diff options
50 files changed, 5943 insertions, 6951 deletions
diff --git a/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi b/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi index 83f0bbe86410..21063a13556d 100644 --- a/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -1158,6 +1158,10 @@ <&pm8994_gpios 7 0>; /* INT3 */ }; + qcom,tv-tuner { + compatible = "qcom,tv-tuner"; + }; + qcom,msm-ba { compatible = "qcom,msm-ba"; qcom,ba-input-profile-0 { @@ -1179,6 +1183,16 @@ qcom,ba-node = <1>; /* ba node */ qcom,user-type = <1>; /* user type */ }; + + qcom,ba-input-profile-2 { + qcom,type = <8>; /* input type */ + qcom,name = "TUNER-2"; /* input name */ + qcom,ba-input = <16>; /* ba input id */ + qcom,ba-output = <0>; /* ba output id */ + qcom,sd-name = "tv-tuner"; /* sd name */ + qcom,ba-node = <2>; /* ba node */ + qcom,user-type = <1>; /* user type */ + }; }; }; diff --git a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-telematics.dts b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-telematics.dts index 37528ab0625e..187648f50f59 100644 --- a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-telematics.dts +++ b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-telematics.dts @@ -1,4 +1,4 @@ -/* Copyright (c) 2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -113,6 +113,24 @@ /* Up to 800 Mbps */ <45 512 207108 14432000>; }; + + dsrc_vreg: dsrc_vreg { + compatible = "qcom,stub-regulator"; + regulator-name = "dsrc_vreg"; + startup-delay-us = <2410>; + enable-active-high; + gpio = <&tlmm 125 0>; + }; + + qcom,cnss_sdio { + compatible = "qcom,cnss_sdio"; + subsys-name = "AR6320_SDIO"; + vdd-wlan-supply = <&rome_vreg>; + vdd-wlan-xtal-supply = <&pm8994_l30>; + vdd-wlan-io-supply = <&pm8994_s4>; + vdd-wlan-dsrc-supply = <&dsrc_vreg>; + qcom,skip-wlan-en-toggle; + }; }; &spi_9 { diff --git a/arch/arm64/configs/msm-auto-perf_defconfig b/arch/arm64/configs/msm-auto-perf_defconfig index bb0b8f71963c..1f9e8ac9a446 100644 --- a/arch/arm64/configs/msm-auto-perf_defconfig +++ b/arch/arm64/configs/msm-auto-perf_defconfig @@ -386,6 +386,7 @@ CONFIG_MSM_AIS_DEBUG=y CONFIG_MSM_AIS_CAMERA_SENSOR=y # CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set CONFIG_VIDEO_ADV7481=m +CONFIG_VIDEO_TVTUNER=m CONFIG_QCOM_KGSL=y CONFIG_DRM=y CONFIG_MSM_BA_V4L2=y diff --git a/arch/arm64/configs/msm-auto_defconfig b/arch/arm64/configs/msm-auto_defconfig index b72807cc8644..36833b167c30 100644 --- a/arch/arm64/configs/msm-auto_defconfig +++ b/arch/arm64/configs/msm-auto_defconfig @@ -390,6 +390,7 @@ CONFIG_MSM_AIS_DEBUG=y CONFIG_MSM_AIS_CAMERA_SENSOR=y # CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set CONFIG_VIDEO_ADV7481=m +CONFIG_VIDEO_TVTUNER=m CONFIG_QCOM_KGSL=y CONFIG_DRM=y CONFIG_MSM_BA_V4L2=y diff --git a/drivers/gpu/drm/msm/sde/sde_hw_ctl.c b/drivers/gpu/drm/msm/sde/sde_hw_ctl.c index 270e79a774b2..46e2a13cecc4 100644 --- a/drivers/gpu/drm/msm/sde/sde_hw_ctl.c +++ b/drivers/gpu/drm/msm/sde/sde_hw_ctl.c @@ -21,6 +21,9 @@ (0x40 + (((lm) - LM_0) * 0x004)) #define CTL_LAYER_EXT2(lm) \ (0x70 + (((lm) - LM_0) * 0x004)) +#define CTL_LAYER_EXT3(lm) \ + (0xA0 + (((lm) - LM_0) * 0x004)) + #define CTL_TOP 0x014 #define CTL_FLUSH 0x018 #define CTL_START 0x01C @@ -315,8 +318,12 @@ static void sde_hw_ctl_clear_all_blendstages(struct sde_hw_ctl *ctx) int i; for (i = 0; i < ctx->mixer_count; i++) { - SDE_REG_WRITE(c, CTL_LAYER(LM_0 + i), 0); - SDE_REG_WRITE(c, CTL_LAYER_EXT(LM_0 + i), 0); + int mixer_id = ctx->mixer_hw_caps[i].id; + + SDE_REG_WRITE(c, CTL_LAYER(mixer_id), 0); + SDE_REG_WRITE(c, CTL_LAYER_EXT(mixer_id), 0); + SDE_REG_WRITE(c, CTL_LAYER_EXT2(mixer_id), 0); + SDE_REG_WRITE(c, CTL_LAYER_EXT3(mixer_id), 0); } } diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 55033aed6d6b..4ed144d48e2b 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c @@ -2088,7 +2088,7 @@ void ath10k_core_stop(struct ath10k *ar) /* try to suspend target */ if (ar->state != ATH10K_STATE_RESTARTING && ar->state != ATH10K_STATE_UTF) - ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR); + ath10k_wait_for_suspend(ar, ar->hw_values->pdev_suspend_option); ath10k_hif_stop(ar); ath10k_htt_tx_free(&ar->htt); diff --git a/drivers/net/wireless/ath/ath10k/hw.c b/drivers/net/wireless/ath/ath10k/hw.c index caf63b8bbba4..1437b5d29a17 100644 --- a/drivers/net/wireless/ath/ath10k/hw.c +++ b/drivers/net/wireless/ath/ath10k/hw.c @@ -460,6 +460,7 @@ struct ath10k_hw_ce_regs qcax_ce_regs = { }; const struct ath10k_hw_values qca988x_values = { + .pdev_suspend_option = WMI_PDEV_SUSPEND_AND_DISABLE_INTR, .rtc_state_val_on = 3, .ce_count = 8, .msi_assign_ce_max = 7, @@ -469,6 +470,7 @@ const struct ath10k_hw_values qca988x_values = { }; const struct ath10k_hw_values qca6174_values = { + .pdev_suspend_option = WMI_PDEV_SUSPEND_AND_DISABLE_INTR, .rtc_state_val_on = 3, .ce_count = 8, .msi_assign_ce_max = 7, @@ -478,6 +480,7 @@ const struct ath10k_hw_values qca6174_values = { }; const struct ath10k_hw_values qca99x0_values = { + .pdev_suspend_option = WMI_PDEV_SUSPEND_AND_DISABLE_INTR, .rtc_state_val_on = 5, .ce_count = 12, .msi_assign_ce_max = 12, @@ -487,6 +490,7 @@ const struct ath10k_hw_values qca99x0_values = { }; const struct ath10k_hw_values qca9888_values = { + .pdev_suspend_option = WMI_PDEV_SUSPEND_AND_DISABLE_INTR, .rtc_state_val_on = 3, .ce_count = 12, .msi_assign_ce_max = 12, @@ -496,13 +500,15 @@ const struct ath10k_hw_values qca9888_values = { }; const struct ath10k_hw_values qca4019_values = { - .ce_count = 12, - .num_target_ce_config_wlan = 10, - .ce_desc_meta_data_mask = 0xFFF0, - .ce_desc_meta_data_lsb = 4, + .pdev_suspend_option = WMI_PDEV_SUSPEND_AND_DISABLE_INTR, + .ce_count = 12, + .num_target_ce_config_wlan = 10, + .ce_desc_meta_data_mask = 0xFFF0, + .ce_desc_meta_data_lsb = 4, }; const struct ath10k_hw_values wcn3990_values = { + .pdev_suspend_option = WMI_PDEV_SUSPEND, .rtc_state_val_on = 5, .ce_count = 12, .msi_assign_ce_max = 12, diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h index 8aa696ed2e72..a37b956c558f 100644 --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h @@ -363,6 +363,7 @@ extern struct ath10k_hw_ce_regs qcax_ce_regs; extern struct fw_flag wcn3990_fw_flags; struct ath10k_hw_values { + u32 pdev_suspend_option; u32 rtc_state_val_on; u8 ce_count; u8 msi_assign_ce_max; diff --git a/drivers/net/wireless/cnss2/main.c b/drivers/net/wireless/cnss2/main.c index 4d8ad7c8975f..bcea74ad6685 100644 --- a/drivers/net/wireless/cnss2/main.c +++ b/drivers/net/wireless/cnss2/main.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -862,7 +862,7 @@ void cnss_wlan_unregister_driver(struct cnss_wlan_driver *driver_ops) cnss_driver_event_post(plat_priv, CNSS_DRIVER_EVENT_UNREGISTER_DRIVER, - CNSS_EVENT_SYNC, NULL); + CNSS_EVENT_SYNC_UNINTERRUPTIBLE, NULL); } EXPORT_SYMBOL(cnss_wlan_unregister_driver); @@ -1508,8 +1508,14 @@ static int cnss_driver_recovery_hdlr(struct cnss_plat_data *plat_priv, cnss_recovery_reason_to_str(recovery_data->reason), recovery_data->reason); + if (!plat_priv->driver_state) { + cnss_pr_err("Improper driver state, ignore recovery\n"); + ret = -EINVAL; + goto out; + } + if (test_bit(CNSS_DRIVER_RECOVERY, &plat_priv->driver_state)) { - cnss_pr_err("Recovery is already in progress!\n"); + cnss_pr_err("Recovery is already in progress\n"); ret = -EINVAL; goto out; } diff --git a/drivers/soc/qcom/glink.c b/drivers/soc/qcom/glink.c index b8464fdfd310..f21e9c4c4f4e 100644 --- a/drivers/soc/qcom/glink.c +++ b/drivers/soc/qcom/glink.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -2991,7 +2991,7 @@ static int glink_tx_common(void *handle, void *pkt_priv, if (!wait_for_completion_timeout( &ctx->int_req_ack_complete, ctx->rx_intent_req_timeout_jiffies)) { - GLINK_ERR_CH(ctx, + GLINK_ERR( "%s: Intent request ack with size: %zu not granted for lcid\n", __func__, size); ret = -ETIMEDOUT; @@ -3011,7 +3011,7 @@ static int glink_tx_common(void *handle, void *pkt_priv, if (!wait_for_completion_timeout( &ctx->int_req_complete, ctx->rx_intent_req_timeout_jiffies)) { - GLINK_ERR_CH(ctx, + GLINK_ERR( "%s: Intent request with size: %zu not granted for lcid\n", __func__, size); ret = -ETIMEDOUT; diff --git a/drivers/soc/qcom/hab/Makefile b/drivers/soc/qcom/hab/Makefile index 83fc54d42202..77825be16fc4 100644 --- a/drivers/soc/qcom/hab/Makefile +++ b/drivers/soc/qcom/hab/Makefile @@ -9,6 +9,7 @@ msm_hab-objs = \ hab_mem_linux.o \ hab_pipe.o \ qvm_comm.o \ - hab_qvm.o + hab_qvm.o \ + hab_parser.o obj-$(CONFIG_MSM_HAB) += msm_hab.o diff --git a/drivers/soc/qcom/hab/hab.c b/drivers/soc/qcom/hab/hab.c index c6df36f5c0a2..040730d63a83 100644 --- a/drivers/soc/qcom/hab/hab.c +++ b/drivers/soc/qcom/hab/hab.c @@ -21,25 +21,32 @@ .openlock = __SPIN_LOCK_UNLOCKED(&hab_devices[__num__].openlock)\ } -/* the following has to match habmm definitions, order does not matter */ +/* + * The following has to match habmm definitions, order does not matter if + * hab config does not care either. When hab config is not present, the default + * is as guest VM all pchans are pchan opener (FE) + */ static struct hab_device hab_devices[] = { HAB_DEVICE_CNSTR(DEVICE_AUD1_NAME, MM_AUD_1, 0), HAB_DEVICE_CNSTR(DEVICE_AUD2_NAME, MM_AUD_2, 1), HAB_DEVICE_CNSTR(DEVICE_AUD3_NAME, MM_AUD_3, 2), HAB_DEVICE_CNSTR(DEVICE_AUD4_NAME, MM_AUD_4, 3), - HAB_DEVICE_CNSTR(DEVICE_CAM_NAME, MM_CAM, 4), - HAB_DEVICE_CNSTR(DEVICE_DISP1_NAME, MM_DISP_1, 5), - HAB_DEVICE_CNSTR(DEVICE_DISP2_NAME, MM_DISP_2, 6), - HAB_DEVICE_CNSTR(DEVICE_DISP3_NAME, MM_DISP_3, 7), - HAB_DEVICE_CNSTR(DEVICE_DISP4_NAME, MM_DISP_4, 8), - HAB_DEVICE_CNSTR(DEVICE_DISP5_NAME, MM_DISP_5, 9), - HAB_DEVICE_CNSTR(DEVICE_GFX_NAME, MM_GFX, 10), - HAB_DEVICE_CNSTR(DEVICE_VID_NAME, MM_VID, 11), - HAB_DEVICE_CNSTR(DEVICE_MISC_NAME, MM_MISC, 12), - HAB_DEVICE_CNSTR(DEVICE_QCPE1_NAME, MM_QCPE_VM1, 13), - HAB_DEVICE_CNSTR(DEVICE_QCPE2_NAME, MM_QCPE_VM2, 14), - HAB_DEVICE_CNSTR(DEVICE_QCPE3_NAME, MM_QCPE_VM3, 15), - HAB_DEVICE_CNSTR(DEVICE_QCPE4_NAME, MM_QCPE_VM4, 16) + HAB_DEVICE_CNSTR(DEVICE_CAM1_NAME, MM_CAM_1, 4), + HAB_DEVICE_CNSTR(DEVICE_CAM2_NAME, MM_CAM_2, 5), + HAB_DEVICE_CNSTR(DEVICE_DISP1_NAME, MM_DISP_1, 6), + HAB_DEVICE_CNSTR(DEVICE_DISP2_NAME, MM_DISP_2, 7), + HAB_DEVICE_CNSTR(DEVICE_DISP3_NAME, MM_DISP_3, 8), + HAB_DEVICE_CNSTR(DEVICE_DISP4_NAME, MM_DISP_4, 9), + HAB_DEVICE_CNSTR(DEVICE_DISP5_NAME, MM_DISP_5, 10), + HAB_DEVICE_CNSTR(DEVICE_GFX_NAME, MM_GFX, 11), + HAB_DEVICE_CNSTR(DEVICE_VID_NAME, MM_VID, 12), + HAB_DEVICE_CNSTR(DEVICE_MISC_NAME, MM_MISC, 13), + HAB_DEVICE_CNSTR(DEVICE_QCPE1_NAME, MM_QCPE_VM1, 14), + HAB_DEVICE_CNSTR(DEVICE_QCPE2_NAME, MM_QCPE_VM2, 15), + HAB_DEVICE_CNSTR(DEVICE_QCPE3_NAME, MM_QCPE_VM3, 16), + HAB_DEVICE_CNSTR(DEVICE_QCPE4_NAME, MM_QCPE_VM4, 17), + HAB_DEVICE_CNSTR(DEVICE_CLK1_NAME, MM_CLK_VM1, 18), + HAB_DEVICE_CNSTR(DEVICE_CLK2_NAME, MM_CLK_VM2, 19), }; struct hab_driver hab_driver = { @@ -71,6 +78,7 @@ struct uhab_context *hab_ctx_alloc(int kernel) kref_init(&ctx->refcount); ctx->import_ctx = habmem_imp_hyp_open(); if (!ctx->import_ctx) { + pr_err("habmem_imp_hyp_open failed\n"); kfree(ctx); return NULL; } @@ -148,6 +156,7 @@ struct virtual_channel *frontend_open(struct uhab_context *ctx, dev = find_hab_device(mm_id); if (dev == NULL) { + pr_err("HAB device %d is not initialized\n", mm_id); ret = -EINVAL; goto err; } @@ -161,6 +170,7 @@ struct virtual_channel *frontend_open(struct uhab_context *ctx, vchan = hab_vchan_alloc(ctx, pchan); if (!vchan) { + pr_err("vchan alloc failed\n"); ret = -ENOMEM; goto err; } @@ -187,6 +197,9 @@ struct virtual_channel *frontend_open(struct uhab_context *ctx, vchan->otherend_id = recv_request->vchan_id; hab_open_request_free(recv_request); + vchan->session_id = open_id; + pr_debug("vchan->session_id:%d\n", vchan->session_id); + /* Send Ack sequence */ hab_open_request_init(&request, HAB_PAYLOAD_TYPE_ACK, pchan, 0, sub_id, open_id); @@ -221,6 +234,7 @@ struct virtual_channel *backend_listen(struct uhab_context *ctx, dev = find_hab_device(mm_id); if (dev == NULL) { + pr_err("failed to find dev based on id %d\n", mm_id); ret = -EINVAL; goto err; } @@ -249,6 +263,9 @@ struct virtual_channel *backend_listen(struct uhab_context *ctx, vchan->otherend_id = otherend_vchan_id; + vchan->session_id = open_id; + pr_debug("vchan->session_id:%d\n", vchan->session_id); + /* Send Init-Ack sequence */ hab_open_request_init(&request, HAB_PAYLOAD_TYPE_INIT_ACK, pchan, vchan->id, sub_id, open_id); @@ -259,7 +276,7 @@ struct virtual_channel *backend_listen(struct uhab_context *ctx, /* Wait for Ack sequence */ hab_open_request_init(&request, HAB_PAYLOAD_TYPE_ACK, pchan, 0, sub_id, open_id); - ret = hab_open_listen(ctx, dev, &request, &recv_request, HZ); + ret = hab_open_listen(ctx, dev, &request, &recv_request, 0); if (ret != -EAGAIN) break; @@ -280,6 +297,7 @@ struct virtual_channel *backend_listen(struct uhab_context *ctx, hab_pchan_put(pchan); return vchan; err: + pr_err("listen on mmid %d failed\n", mm_id); if (vchan) hab_vchan_put(vchan); if (pchan) @@ -304,12 +322,19 @@ long hab_vchan_send(struct uhab_context *ctx, } vchan = hab_get_vchan_fromvcid(vcid, ctx); - if (!vchan || vchan->otherend_closed) - return -ENODEV; + if (!vchan || vchan->otherend_closed) { + ret = -ENODEV; + goto err; + } HAB_HEADER_SET_SIZE(header, sizebytes); - HAB_HEADER_SET_TYPE(header, HAB_PAYLOAD_TYPE_MSG); + if (flags & HABMM_SOCKET_SEND_FLAGS_XING_VM_STAT) + HAB_HEADER_SET_TYPE(header, HAB_PAYLOAD_TYPE_PROFILE); + else + HAB_HEADER_SET_TYPE(header, HAB_PAYLOAD_TYPE_MSG); + HAB_HEADER_SET_ID(header, vchan->otherend_id); + HAB_HEADER_SET_SESSION_ID(header, vchan->session_id); while (1) { ret = physical_channel_send(vchan->pchan, &header, data); @@ -321,7 +346,11 @@ long hab_vchan_send(struct uhab_context *ctx, schedule(); } - hab_vchan_put(vchan); + +err: + if (vchan) + hab_vchan_put(vchan); + return ret; } @@ -335,7 +364,7 @@ struct hab_message *hab_vchan_recv(struct uhab_context *ctx, int nonblocking_flag = flags & HABMM_SOCKET_RECV_FLAGS_NON_BLOCKING; vchan = hab_get_vchan_fromvcid(vcid, ctx); - if (!vchan || vchan->otherend_closed) + if (!vchan) return ERR_PTR(-ENODEV); if (nonblocking_flag) { @@ -351,6 +380,8 @@ struct hab_message *hab_vchan_recv(struct uhab_context *ctx, if (!message) { if (nonblocking_flag) ret = -EAGAIN; + else if (vchan->otherend_closed) + ret = -ENODEV; else ret = -EPIPE; } @@ -369,7 +400,11 @@ int hab_vchan_open(struct uhab_context *ctx, int32_t *vcid, uint32_t flags) { - struct virtual_channel *vchan; + struct virtual_channel *vchan = NULL; + struct hab_device *dev; + + pr_debug("Open mmid=%d, loopback mode=%d, loopback num=%d\n", + mmid, hab_driver.b_loopback, hab_driver.loopback_num); if (!vcid) return -EINVAL; @@ -383,14 +418,29 @@ int hab_vchan_open(struct uhab_context *ctx, vchan = frontend_open(ctx, mmid, LOOPBACK_DOM); } } else { - if (hab_driver.b_server_dom) - vchan = backend_listen(ctx, mmid); - else - vchan = frontend_open(ctx, mmid, 0); + dev = find_hab_device(mmid); + + if (dev) { + struct physical_channel *pchan = + hab_pchan_find_domid(dev, HABCFG_VMID_DONT_CARE); + + if (pchan->is_be) + vchan = backend_listen(ctx, mmid); + else + vchan = frontend_open(ctx, mmid, + HABCFG_VMID_DONT_CARE); + } else { + pr_err("failed to find device, mmid %d\n", mmid); + } } - if (IS_ERR(vchan)) + if (IS_ERR(vchan)) { + pr_err("vchan open failed over mmid=%d\n", mmid); return PTR_ERR(vchan); + } + + pr_debug("vchan id %x, remote id %x\n", + vchan->id, vchan->otherend_id); write_lock(&ctx->ctx_lock); list_add_tail(&vchan->node, &ctx->vchannels); @@ -403,12 +453,13 @@ int hab_vchan_open(struct uhab_context *ctx, void hab_send_close_msg(struct virtual_channel *vchan) { - struct hab_header header; + struct hab_header header = {0}; if (vchan && !vchan->otherend_closed) { HAB_HEADER_SET_SIZE(header, 0); HAB_HEADER_SET_TYPE(header, HAB_PAYLOAD_TYPE_CLOSE); HAB_HEADER_SET_ID(header, vchan->otherend_id); + HAB_HEADER_SET_SESSION_ID(header, vchan->session_id); physical_channel_send(vchan->pchan, &header, NULL); } } @@ -442,6 +493,220 @@ void hab_vchan_close(struct uhab_context *ctx, int32_t vcid) write_unlock(&ctx->ctx_lock); } +/* + * To name the pchan - the pchan has two ends, either FE or BE locally. + * if is_be is true, then this is listener for BE. pchane name use remote + * FF's vmid from the table. + * if is_be is false, then local is FE as opener. pchan name use local FE's + * vmid (self) + */ +static int hab_initialize_pchan_entry(struct hab_device *mmid_device, + int vmid_local, int vmid_remote, int is_be) +{ + char pchan_name[MAX_VMID_NAME_SIZE]; + struct physical_channel *pchan = NULL; + int ret; + int vmid = is_be ? vmid_remote : vmid_local; + + if (!mmid_device) { + pr_err("habdev %pK, vmid local %d, remote %d, is be %d\n", + mmid_device, vmid_local, vmid_remote, is_be); + return -EINVAL; + } + + snprintf(pchan_name, MAX_VMID_NAME_SIZE, "vm%d-", vmid); + strlcat(pchan_name, mmid_device->name, MAX_VMID_NAME_SIZE); + + ret = habhyp_commdev_alloc((void **)&pchan, is_be, pchan_name, + vmid_remote, mmid_device); + if (ret == 0) { + pr_debug("pchan %s added, vmid local %d, remote %d, is_be %d, total %d\n", + pchan_name, vmid_local, vmid_remote, is_be, + mmid_device->pchan_cnt); + } else { + pr_err("failed %d to allocate pchan %s, vmid local %d, remote %d, is_be %d, total %d\n", + ret, pchan_name, vmid_local, vmid_remote, + is_be, mmid_device->pchan_cnt); + } + + return ret; +} + +static void hab_generate_pchan(struct local_vmid *settings, int i, int j) +{ + int k, ret = 0; + + pr_debug("%d as mmid %d in vmid %d\n", + HABCFG_GET_MMID(settings, i, j), j, i); + + switch (HABCFG_GET_MMID(settings, i, j)) { + case MM_AUD_START/100: + for (k = MM_AUD_START + 1; k < MM_AUD_END; k++) { + /* + * if this local pchan end is BE, then use + * remote FE's vmid. If local end is FE, then + * use self vmid + */ + ret += hab_initialize_pchan_entry( + find_hab_device(k), + settings->self, + HABCFG_GET_VMID(settings, i), + HABCFG_GET_BE(settings, i, j)); + } + break; + + case MM_CAM_START/100: + for (k = MM_CAM_START + 1; k < MM_CAM_END; k++) { + ret += hab_initialize_pchan_entry( + find_hab_device(k), + settings->self, + HABCFG_GET_VMID(settings, i), + HABCFG_GET_BE(settings, i, j)); + } + break; + + case MM_DISP_START/100: + for (k = MM_DISP_START + 1; k < MM_DISP_END; k++) { + ret += hab_initialize_pchan_entry( + find_hab_device(k), + settings->self, + HABCFG_GET_VMID(settings, i), + HABCFG_GET_BE(settings, i, j)); + } + break; + + case MM_GFX_START/100: + for (k = MM_GFX_START + 1; k < MM_GFX_END; k++) { + ret += hab_initialize_pchan_entry( + find_hab_device(k), + settings->self, + HABCFG_GET_VMID(settings, i), + HABCFG_GET_BE(settings, i, j)); + } + break; + + case MM_VID_START/100: + for (k = MM_VID_START + 1; k < MM_VID_END; k++) { + ret += hab_initialize_pchan_entry( + find_hab_device(k), + settings->self, + HABCFG_GET_VMID(settings, i), + HABCFG_GET_BE(settings, i, j)); + } + break; + + case MM_MISC_START/100: + for (k = MM_MISC_START + 1; k < MM_MISC_END; k++) { + ret += hab_initialize_pchan_entry( + find_hab_device(k), + settings->self, + HABCFG_GET_VMID(settings, i), + HABCFG_GET_BE(settings, i, j)); + } + break; + + case MM_QCPE_START/100: + for (k = MM_QCPE_START + 1; k < MM_QCPE_END; k++) { + ret += hab_initialize_pchan_entry( + find_hab_device(k), + settings->self, + HABCFG_GET_VMID(settings, i), + HABCFG_GET_BE(settings, i, j)); + } + break; + + case MM_CLK_START/100: + for (k = MM_CLK_START + 1; k < MM_CLK_END; k++) { + ret += hab_initialize_pchan_entry( + find_hab_device(k), + settings->self, + HABCFG_GET_VMID(settings, i), + HABCFG_GET_BE(settings, i, j)); + } + break; + + default: + pr_err("failed to find mmid %d, i %d, j %d\n", + HABCFG_GET_MMID(settings, i, j), i, j); + + break; + } +} + +/* + * generate pchan list based on hab settings table. + * return status 0: success, otherwise failure + */ +static int hab_generate_pchan_list(struct local_vmid *settings) +{ + int i, j; + + /* scan by valid VMs, then mmid */ + pr_debug("self vmid is %d\n", settings->self); + for (i = 0; i < HABCFG_VMID_MAX; i++) { + if (HABCFG_GET_VMID(settings, i) != HABCFG_VMID_INVALID && + HABCFG_GET_VMID(settings, i) != settings->self) { + pr_debug("create pchans for vm %d\n", i); + + for (j = 1; j <= HABCFG_MMID_AREA_MAX; j++) { + if (HABCFG_GET_MMID(settings, i, j) + != HABCFG_VMID_INVALID) + hab_generate_pchan(settings, i, j); + } + } + } + + return 0; +} + +/* + * This function checks hypervisor plug-in readiness, read in hab configs, + * and configure pchans + */ +int do_hab_parse(void) +{ + int result; + int i; + struct hab_device *device; + int pchan_total = 0; + + /* first check if hypervisor plug-in is ready */ + result = hab_hypervisor_register(); + if (result) { + pr_err("register HYP plug-in failed, ret %d\n", result); + return result; + } + + /* Initialize open Q before first pchan starts */ + for (i = 0; i < hab_driver.ndevices; i++) { + device = &hab_driver.devp[i]; + init_waitqueue_head(&device->openq); + } + + /* read in hab config and create pchans*/ + memset(&hab_driver.settings, HABCFG_VMID_INVALID, + sizeof(hab_driver.settings)); + + pr_debug("prepare default gvm 2 settings...\n"); + fill_default_gvm_settings(&hab_driver.settings, 2, + MM_AUD_START, MM_ID_MAX); + + /* now generate hab pchan list */ + result = hab_generate_pchan_list(&hab_driver.settings); + if (result) { + pr_err("generate pchan list failed, ret %d\n", result); + } else { + for (i = 0; i < hab_driver.ndevices; i++) { + device = &hab_driver.devp[i]; + pchan_total += device->pchan_cnt; + } + pr_debug("ret %d, total %d pchans added, ndevices %d\n", + result, pchan_total, hab_driver.ndevices); + } + + return result; +} + static int hab_open(struct inode *inodep, struct file *filep) { int result = 0; @@ -468,6 +733,8 @@ static int hab_release(struct inode *inodep, struct file *filep) if (!ctx) return 0; + pr_debug("inode %pK, filep %pK\n", inodep, filep); + write_lock(&ctx->ctx_lock); list_for_each_entry_safe(vchan, tmp, &ctx->vchannels, node) { @@ -635,9 +902,7 @@ static const struct dma_map_ops hab_dma_ops = { static int __init hab_init(void) { int result; - int i; dev_t dev; - struct hab_device *device; result = alloc_chrdev_region(&hab_driver.major, 0, 1, "hab"); @@ -676,24 +941,22 @@ static int __init hab_init(void) goto err; } - for (i = 0; i < hab_driver.ndevices; i++) { - device = &hab_driver.devp[i]; - init_waitqueue_head(&device->openq); - } - - hab_hypervisor_register(); + /* read in hab config, then configure pchans */ + result = do_hab_parse(); - hab_driver.kctx = hab_ctx_alloc(1); - if (!hab_driver.kctx) { - pr_err("hab_ctx_alloc failed"); - result = -ENOMEM; - hab_hypervisor_unregister(); - goto err; - } + if (!result) { + hab_driver.kctx = hab_ctx_alloc(1); + if (!hab_driver.kctx) { + pr_err("hab_ctx_alloc failed"); + result = -ENOMEM; + hab_hypervisor_unregister(); + goto err; + } - set_dma_ops(hab_driver.dev, &hab_dma_ops); + set_dma_ops(hab_driver.dev, &hab_dma_ops); - return result; + return result; + } err: if (!IS_ERR_OR_NULL(hab_driver.dev)) @@ -703,6 +966,7 @@ err: cdev_del(&hab_driver.cdev); unregister_chrdev_region(dev, 1); + pr_err("Error in hab init, result %d\n", result); return result; } diff --git a/drivers/soc/qcom/hab/hab.h b/drivers/soc/qcom/hab/hab.h index 805e5b4a7008..19a8584edd35 100644 --- a/drivers/soc/qcom/hab/hab.h +++ b/drivers/soc/qcom/hab/hab.h @@ -13,7 +13,7 @@ #ifndef __HAB_H #define __HAB_H -#define pr_fmt(fmt) "hab: " fmt +#define pr_fmt(fmt) "|hab:%s:%d|" fmt, __func__, __LINE__ #include <linux/types.h> @@ -47,6 +47,7 @@ enum hab_payload_type { HAB_PAYLOAD_TYPE_EXPORT_ACK, HAB_PAYLOAD_TYPE_PROFILE, HAB_PAYLOAD_TYPE_CLOSE, + HAB_PAYLOAD_TYPE_MAX, }; #define LOOPBACK_DOM 0xFF @@ -61,7 +62,8 @@ enum hab_payload_type { #define DEVICE_AUD2_NAME "hab_aud2" #define DEVICE_AUD3_NAME "hab_aud3" #define DEVICE_AUD4_NAME "hab_aud4" -#define DEVICE_CAM_NAME "hab_cam" +#define DEVICE_CAM1_NAME "hab_cam1" +#define DEVICE_CAM2_NAME "hab_cam2" #define DEVICE_DISP1_NAME "hab_disp1" #define DEVICE_DISP2_NAME "hab_disp2" #define DEVICE_DISP3_NAME "hab_disp3" @@ -74,6 +76,48 @@ enum hab_payload_type { #define DEVICE_QCPE2_NAME "hab_qcpe_vm2" #define DEVICE_QCPE3_NAME "hab_qcpe_vm3" #define DEVICE_QCPE4_NAME "hab_qcpe_vm4" +#define DEVICE_CLK1_NAME "hab_clock_vm1" +#define DEVICE_CLK2_NAME "hab_clock_vm2" + +/* make sure concascaded name is less than this value */ +#define MAX_VMID_NAME_SIZE 30 + +#define HABCFG_FILE_SIZE_MAX 256 +#define HABCFG_MMID_AREA_MAX (MM_ID_MAX/100) + +#define HABCFG_VMID_MAX 16 +#define HABCFG_VMID_INVALID (-1) +#define HABCFG_VMID_DONT_CARE (-2) + +#define HABCFG_ID_LINE_LIMIT "," +#define HABCFG_ID_VMID "VMID=" +#define HABCFG_ID_BE "BE=" +#define HABCFG_ID_FE "FE=" +#define HABCFG_ID_MMID "MMID=" +#define HABCFG_ID_RANGE "-" +#define HABCFG_ID_DONTCARE "X" + +#define HABCFG_FOUND_VMID 1 +#define HABCFG_FOUND_FE_MMIDS 2 +#define HABCFG_FOUND_BE_MMIDS 3 +#define HABCFG_FOUND_NOTHING (-1) + +#define HABCFG_BE_FALSE 0 +#define HABCFG_BE_TRUE 1 + +#define HABCFG_GET_VMID(_local_cfg_, _vmid_) \ + ((settings)->vmid_mmid_list[_vmid_].vmid) +#define HABCFG_GET_MMID(_local_cfg_, _vmid_, _mmid_) \ + ((settings)->vmid_mmid_list[_vmid_].mmid[_mmid_]) +#define HABCFG_GET_BE(_local_cfg_, _vmid_, _mmid_) \ + ((settings)->vmid_mmid_list[_vmid_].is_listener[_mmid_]) + +struct hab_header { + uint32_t id_type_size; + uint32_t session_id; + uint32_t signature; + uint32_t sequence; +} __packed; /* "Size" of the HAB_HEADER_ID and HAB_VCID_ID must match */ #define HAB_HEADER_SIZE_SHIFT 0 @@ -96,34 +140,44 @@ enum hab_payload_type { #define HAB_VCID_GET_ID(vcid) \ (((vcid) & HAB_VCID_ID_MASK) >> HAB_VCID_ID_SHIFT) + +#define HAB_HEADER_SET_SESSION_ID(header, sid) ((header).session_id = (sid)) + #define HAB_HEADER_SET_SIZE(header, size) \ - ((header).info = (((header).info) & (~HAB_HEADER_SIZE_MASK)) | \ - (((size) << HAB_HEADER_SIZE_SHIFT) & HAB_HEADER_SIZE_MASK)) + ((header).id_type_size = ((header).id_type_size & \ + (~HAB_HEADER_SIZE_MASK)) | \ + (((size) << HAB_HEADER_SIZE_SHIFT) & \ + HAB_HEADER_SIZE_MASK)) #define HAB_HEADER_SET_TYPE(header, type) \ - ((header).info = (((header).info) & (~HAB_HEADER_TYPE_MASK)) | \ - (((type) << HAB_HEADER_TYPE_SHIFT) & HAB_HEADER_TYPE_MASK)) + ((header).id_type_size = ((header).id_type_size & \ + (~HAB_HEADER_TYPE_MASK)) | \ + (((type) << HAB_HEADER_TYPE_SHIFT) & \ + HAB_HEADER_TYPE_MASK)) #define HAB_HEADER_SET_ID(header, id) \ - ((header).info = (((header).info) & (~HAB_HEADER_ID_MASK)) | \ - ((HAB_VCID_GET_ID(id) << HAB_HEADER_ID_SHIFT) \ - & HAB_HEADER_ID_MASK)) + ((header).id_type_size = ((header).id_type_size & \ + (~HAB_HEADER_ID_MASK)) | \ + ((HAB_VCID_GET_ID(id) << HAB_HEADER_ID_SHIFT) & \ + HAB_HEADER_ID_MASK)) #define HAB_HEADER_GET_SIZE(header) \ - ((((header).info) & HAB_HEADER_SIZE_MASK) >> HAB_HEADER_SIZE_SHIFT) + (((header).id_type_size & \ + HAB_HEADER_SIZE_MASK) >> HAB_HEADER_SIZE_SHIFT) #define HAB_HEADER_GET_TYPE(header) \ - ((((header).info) & HAB_HEADER_TYPE_MASK) >> HAB_HEADER_TYPE_SHIFT) + (((header).id_type_size & \ + HAB_HEADER_TYPE_MASK) >> HAB_HEADER_TYPE_SHIFT) #define HAB_HEADER_GET_ID(header) \ - (((((header).info) & HAB_HEADER_ID_MASK) >> \ + ((((header).id_type_size & HAB_HEADER_ID_MASK) >> \ (HAB_HEADER_ID_SHIFT - HAB_VCID_ID_SHIFT)) & HAB_VCID_ID_MASK) -struct hab_header { - uint32_t info; -}; +#define HAB_HEADER_GET_SESSION_ID(header) ((header).session_id) struct physical_channel { + char name[MAX_VMID_NAME_SIZE]; + int is_be; struct kref refcount; struct hab_device *habdev; struct list_head node; @@ -138,6 +192,10 @@ struct physical_channel { int closed; spinlock_t rxbuf_lock; + + /* vchans over this pchan */ + struct list_head vchannels; + rwlock_t vchans_lock; }; struct hab_open_send_data { @@ -179,9 +237,10 @@ struct hab_message { }; struct hab_device { - const char *name; + char name[MAX_VMID_NAME_SIZE]; unsigned int id; struct list_head pchannels; + int pchan_cnt; struct mutex pchan_lock; struct list_head openq_list; spinlock_t openlock; @@ -211,19 +270,37 @@ struct uhab_context { int kernel; }; +/* + * array to describe the VM and its MMID configuration as what is connected to + * so this is describing a pchan's remote side + */ +struct vmid_mmid_desc { + int vmid; /* remote vmid */ + int mmid[HABCFG_MMID_AREA_MAX+1]; /* selected or not */ + int is_listener[HABCFG_MMID_AREA_MAX+1]; /* yes or no */ +}; + +struct local_vmid { + int32_t self; /* only this field is for local */ + struct vmid_mmid_desc vmid_mmid_list[HABCFG_VMID_MAX]; +}; + struct hab_driver { struct device *dev; struct cdev cdev; dev_t major; struct class *class; - int irq; - int ndevices; struct hab_device *devp; struct uhab_context *kctx; + + struct local_vmid settings; /* parser results */ + int b_server_dom; int loopback_num; int b_loopback; + + void *hyp_priv; /* hypervisor plug-in storage */ }; struct virtual_channel { @@ -243,12 +320,14 @@ struct virtual_channel { struct physical_channel *pchan; struct uhab_context *ctx; struct list_head node; + struct list_head pnode; struct list_head rx_list; wait_queue_head_t rx_queue; spinlock_t rx_lock; int id; int otherend_id; int otherend_closed; + uint32_t session_id; }; /* @@ -271,7 +350,7 @@ struct export_desc { void *kva; int payload_count; unsigned char payload[1]; -}; +} __packed; int hab_vchan_open(struct uhab_context *ctx, unsigned int mmid, int32_t *vcid, uint32_t flags); @@ -286,6 +365,7 @@ struct hab_message *hab_vchan_recv(struct uhab_context *ctx, int vcid, unsigned int flags); void hab_vchan_stop(struct virtual_channel *vchan); +void hab_vchans_stop(struct physical_channel *pchan); void hab_vchan_stop_notify(struct virtual_channel *vchan); int hab_mem_export(struct uhab_context *ctx, @@ -350,7 +430,7 @@ void hab_open_request_init(struct hab_open_request *request, int open_id); int hab_open_request_send(struct hab_open_request *request); int hab_open_request_add(struct physical_channel *pchan, - struct hab_header *header); + size_t sizebytes, int request_type); void hab_open_request_free(struct hab_open_request *request); int hab_open_listen(struct uhab_context *ctx, struct hab_device *dev, @@ -361,7 +441,7 @@ int hab_open_listen(struct uhab_context *ctx, struct virtual_channel *hab_vchan_alloc(struct uhab_context *ctx, struct physical_channel *pchan); struct virtual_channel *hab_vchan_get(struct physical_channel *pchan, - uint32_t vchan_id); + struct hab_header *header); void hab_vchan_put(struct virtual_channel *vchan); struct virtual_channel *hab_get_vchan_fromvcid(int32_t vcid, @@ -394,6 +474,9 @@ static inline void hab_ctx_put(struct uhab_context *ctx) void hab_send_close_msg(struct virtual_channel *vchan); int hab_hypervisor_register(void); void hab_hypervisor_unregister(void); +int habhyp_commdev_alloc(void **commdev, int is_be, char *name, + int vmid_remote, struct hab_device *mmid_device); +int habhyp_commdev_dealloc(void *commdev); int physical_channel_read(struct physical_channel *pchan, void *payload, @@ -407,6 +490,13 @@ void physical_channel_rx_dispatch(unsigned long physical_channel); int loopback_pchan_create(char *dev_name); +int hab_parse(struct local_vmid *settings); + +int do_hab_parse(void); + +int fill_default_gvm_settings(struct local_vmid *settings, + int vmid_local, int mmid_start, int mmid_end); + bool hab_is_loopback(void); /* Global singleton HAB instance */ diff --git a/drivers/soc/qcom/hab/hab_mem_linux.c b/drivers/soc/qcom/hab/hab_mem_linux.c index ab4b9d0885cb..ecc3f52a6662 100644 --- a/drivers/soc/qcom/hab/hab_mem_linux.c +++ b/drivers/soc/qcom/hab/hab_mem_linux.c @@ -35,6 +35,7 @@ struct importer_context { int cnt; /* pages allocated for local file */ struct list_head imp_list; struct file *filp; + rwlock_t implist_lock; }; void *habmm_hyp_allocate_grantable(int page_count, @@ -73,8 +74,12 @@ static int habmem_get_dma_pages(unsigned long address, int fd; vma = find_vma(current->mm, address); - if (!vma || !vma->vm_file) + if (!vma || !vma->vm_file) { + pr_err("cannot find vma\n"); goto err; + } + + pr_debug("vma flags %lx\n", vma->vm_flags); /* Look for the fd that matches this the vma file */ fd = iterate_fd(current->files, 0, match_file, vma->vm_file); @@ -103,6 +108,7 @@ static int habmem_get_dma_pages(unsigned long address, for_each_sg(sg_table->sgl, s, sg_table->nents, i) { page = sg_page(s); + pr_debug("sgl length %d\n", s->length); for (j = page_offset; j < (s->length >> PAGE_SHIFT); j++) { pages[rc] = nth_page(page, j); @@ -136,6 +142,12 @@ err: return rc; } +/* + * exporter - grant & revoke + * degenerate sharabled page list based on CPU friendly virtual "address". + * The result as an array is stored in ppdata to return to caller + * page size 4KB is assumed + */ int habmem_hyp_grant_user(unsigned long address, int page_count, int flags, @@ -220,6 +232,7 @@ void *habmem_imp_hyp_open(void) if (!priv) return NULL; + rwlock_init(&priv->implist_lock); INIT_LIST_HEAD(&priv->imp_list); return priv; @@ -261,7 +274,7 @@ long habmem_imp_hyp_map(void *imp_ctx, uint32_t userflags) { struct page **pages; - struct compressed_pfns *pfn_table = impdata; + struct compressed_pfns *pfn_table = (struct compressed_pfns *)impdata; struct pages_list *pglist; struct importer_context *priv = imp_ctx; unsigned long pfn; @@ -310,6 +323,9 @@ long habmem_imp_hyp_map(void *imp_ctx, kfree(pglist); pr_err("%ld pages vmap failed\n", pglist->npages); return -ENOMEM; + } else { + pr_debug("%ld pages vmap pass, return %pK\n", + pglist->npages, pglist->kva); } pglist->uva = NULL; @@ -320,8 +336,11 @@ long habmem_imp_hyp_map(void *imp_ctx, pglist->kva = NULL; } + write_lock(&priv->implist_lock); list_add_tail(&pglist->list, &priv->imp_list); priv->cnt++; + write_unlock(&priv->implist_lock); + pr_debug("index returned %llx\n", *index); return 0; } @@ -333,11 +352,15 @@ long habmm_imp_hyp_unmap(void *imp_ctx, int kernel) { struct importer_context *priv = imp_ctx; - struct pages_list *pglist; + struct pages_list *pglist, *tmp; int found = 0; uint64_t pg_index = index >> PAGE_SHIFT; - list_for_each_entry(pglist, &priv->imp_list, list) { + write_lock(&priv->implist_lock); + list_for_each_entry_safe(pglist, tmp, &priv->imp_list, list) { + pr_debug("node pglist %pK, kernel %d, pg_index %llx\n", + pglist, pglist->kernel, pg_index); + if (kernel) { if (pglist->kva == (void *)((uintptr_t)index)) found = 1; @@ -353,11 +376,15 @@ long habmm_imp_hyp_unmap(void *imp_ctx, } } + write_unlock(&priv->implist_lock); if (!found) { pr_err("failed to find export id on index %llx\n", index); return -EINVAL; } + pr_debug("detach pglist %pK, index %llx, kernel %d, list cnt %d\n", + pglist, pglist->index, pglist->kernel, priv->cnt); + if (kernel) if (pglist->kva) vunmap(pglist->kva); @@ -393,6 +420,8 @@ static int hab_map_fault(struct vm_area_struct *vma, struct vm_fault *vmf) return VM_FAULT_SIGBUS; } + pr_debug("Fault page index %d\n", page_idx); + page = pglist->pages[page_idx]; get_page(page); vmf->page = page; @@ -422,15 +451,20 @@ int habmem_imp_hyp_mmap(struct file *filp, struct vm_area_struct *vma) struct pages_list *pglist; int bfound = 0; + pr_debug("mmap request start %lX, len %ld, index %lX\n", + vma->vm_start, length, vma->vm_pgoff); + + read_lock(&imp_ctx->implist_lock); list_for_each_entry(pglist, &imp_ctx->imp_list, list) { if (pglist->index == vma->vm_pgoff) { bfound = 1; break; } } + read_unlock(&imp_ctx->implist_lock); if (!bfound) { - pr_err("Failed to find pglist vm_pgoff: %d\n", vma->vm_pgoff); + pr_err("Failed to find pglist vm_pgoff: %ld\n", vma->vm_pgoff); return -EINVAL; } diff --git a/drivers/soc/qcom/hab/hab_mimex.c b/drivers/soc/qcom/hab/hab_mimex.c index aaef9aa9f414..67601590908e 100644 --- a/drivers/soc/qcom/hab/hab_mimex.c +++ b/drivers/soc/qcom/hab/hab_mimex.c @@ -31,11 +31,11 @@ static int hab_export_ack_find(struct uhab_context *ctx, struct hab_export_ack *expect_ack) { int ret = 0; - struct hab_export_ack_recvd *ack_recvd; + struct hab_export_ack_recvd *ack_recvd, *tmp; spin_lock_bh(&ctx->expq_lock); - list_for_each_entry(ack_recvd, &ctx->exp_rxq, node) { + list_for_each_entry_safe(ack_recvd, tmp, &ctx->exp_rxq, node) { if (ack_recvd->ack.export_id == expect_ack->export_id && ack_recvd->ack.vcid_local == expect_ack->vcid_local && ack_recvd->ack.vcid_remote == expect_ack->vcid_remote) { @@ -197,6 +197,7 @@ static int habmem_export_vchan(struct uhab_context *ctx, HAB_HEADER_SET_SIZE(header, sizebytes); HAB_HEADER_SET_TYPE(header, HAB_PAYLOAD_TYPE_EXPORT); HAB_HEADER_SET_ID(header, vchan->otherend_id); + HAB_HEADER_SET_SESSION_ID(header, vchan->session_id); ret = physical_channel_send(vchan->pchan, &header, exp); if (ret != 0) { @@ -228,6 +229,8 @@ int hab_mem_export(struct uhab_context *ctx, if (!ctx || !param || param->sizebytes > HAB_MAX_EXPORT_SIZE) return -EINVAL; + pr_debug("vc %X, mem size %d\n", param->vcid, param->sizebytes); + vchan = hab_get_vchan_fromvcid(param->vcid, ctx); if (!vchan || !vchan->pchan) { ret = -ENODEV; @@ -303,7 +306,10 @@ int hab_mem_unexport(struct uhab_context *ctx, return -EINVAL; ret = habmem_hyp_revoke(exp->payload, exp->payload_count); - + if (ret) { + pr_err("Error found in revoke grant with ret %d", ret); + return ret; + } habmem_remove_export(exp); return ret; } @@ -335,6 +341,10 @@ int hab_mem_import(struct uhab_context *ctx, return ret; } + pr_debug("call map id: %d pcnt %d remote_dom %d 1st_ref:0x%X\n", + exp->export_id, exp->payload_count, exp->domid_local, + *((uint32_t *)exp->payload)); + ret = habmem_imp_hyp_map(ctx->import_ctx, exp->payload, exp->payload_count, @@ -349,6 +359,8 @@ int hab_mem_import(struct uhab_context *ctx, exp->domid_local, *((uint32_t *)exp->payload)); return ret; } + pr_debug("import index %llx, kva %llx, kernel %d\n", + exp->import_index, param->kva, kernel); param->index = exp->import_index; param->kva = (uint64_t)exp->kva; @@ -373,6 +385,9 @@ int hab_mem_unimport(struct uhab_context *ctx, list_del(&exp->node); ctx->import_total--; found = 1; + + pr_debug("found id:%d payload cnt:%d kernel:%d\n", + exp->export_id, exp->payload_count, kernel); break; } } @@ -385,7 +400,10 @@ int hab_mem_unimport(struct uhab_context *ctx, exp->import_index, exp->payload_count, kernel); - + if (ret) { + pr_err("unmap fail id:%d pcnt:%d kernel:%d\n", + exp->export_id, exp->payload_count, kernel); + } param->kva = (uint64_t)exp->kva; kfree(exp); } diff --git a/drivers/soc/qcom/hab/hab_msg.c b/drivers/soc/qcom/hab/hab_msg.c index f08cc83fe9fc..700239a25652 100644 --- a/drivers/soc/qcom/hab/hab_msg.c +++ b/drivers/soc/qcom/hab/hab_msg.c @@ -55,13 +55,12 @@ hab_msg_dequeue(struct virtual_channel *vchan, int wait_flag) vchan->otherend_closed); } - if (!ret && !vchan->otherend_closed) { + /* return all the received messages before the remote close */ + if (!ret && !hab_rx_queue_empty(vchan)) { spin_lock_bh(&vchan->rx_lock); - if (!list_empty(&vchan->rx_list)) { - message = list_first_entry(&vchan->rx_list, + message = list_first_entry(&vchan->rx_list, struct hab_message, node); - list_del(&message->node); - } + list_del(&message->node); spin_unlock_bh(&vchan->rx_lock); } @@ -91,8 +90,9 @@ static int hab_export_enqueue(struct virtual_channel *vchan, return 0; } -static int hab_send_export_ack(struct physical_channel *pchan, - struct export_desc *exp) +static int hab_send_export_ack(struct virtual_channel *vchan, + struct physical_channel *pchan, + struct export_desc *exp) { struct hab_export_ack exp_ack = { .export_id = exp->export_id, @@ -104,11 +104,12 @@ static int hab_send_export_ack(struct physical_channel *pchan, HAB_HEADER_SET_SIZE(header, sizeof(exp_ack)); HAB_HEADER_SET_TYPE(header, HAB_PAYLOAD_TYPE_EXPORT_ACK); HAB_HEADER_SET_ID(header, exp->vcid_local); + HAB_HEADER_SET_SESSION_ID(header, vchan->session_id); return physical_channel_send(pchan, &header, &exp_ack); } static int hab_receive_create_export_ack(struct physical_channel *pchan, - struct uhab_context *ctx) + struct uhab_context *ctx, size_t sizebytes) { struct hab_export_ack_recvd *ack_recvd = kzalloc(sizeof(*ack_recvd), GFP_ATOMIC); @@ -116,11 +117,20 @@ static int hab_receive_create_export_ack(struct physical_channel *pchan, if (!ack_recvd) return -ENOMEM; + if (sizeof(ack_recvd->ack) != sizebytes) + pr_err("exp ack size %lu is not as arrived %zu\n", + sizeof(ack_recvd->ack), sizebytes); + if (physical_channel_read(pchan, &ack_recvd->ack, - sizeof(ack_recvd->ack)) != sizeof(ack_recvd->ack)) + sizebytes) != sizebytes) return -EIO; + pr_debug("receive export id %d, local vc %X, vd remote %X\n", + ack_recvd->ack.export_id, + ack_recvd->ack.vcid_local, + ack_recvd->ack.vcid_remote); + spin_lock_bh(&ctx->expq_lock); list_add_tail(&ack_recvd->node, &ctx->exp_rxq); spin_unlock_bh(&ctx->expq_lock); @@ -137,20 +147,48 @@ void hab_msg_recv(struct physical_channel *pchan, size_t sizebytes = HAB_HEADER_GET_SIZE(*header); uint32_t payload_type = HAB_HEADER_GET_TYPE(*header); uint32_t vchan_id = HAB_HEADER_GET_ID(*header); + uint32_t session_id = HAB_HEADER_GET_SESSION_ID(*header); struct virtual_channel *vchan = NULL; struct export_desc *exp_desc; + struct timeval tv; /* get the local virtual channel if it isn't an open message */ if (payload_type != HAB_PAYLOAD_TYPE_INIT && payload_type != HAB_PAYLOAD_TYPE_INIT_ACK && payload_type != HAB_PAYLOAD_TYPE_ACK) { - vchan = hab_vchan_get(pchan, vchan_id); + + /* sanity check the received message */ + if (payload_type >= HAB_PAYLOAD_TYPE_MAX || + vchan_id > (HAB_HEADER_ID_MASK >> HAB_HEADER_ID_SHIFT) + || !vchan_id || !session_id) { + pr_err("Invalid message received, payload type %d, vchan id %x, sizebytes %zx, session %d\n", + payload_type, vchan_id, sizebytes, session_id); + } + + vchan = hab_vchan_get(pchan, header); if (!vchan) { + pr_debug("vchan is not found, payload type %d, vchan id %x, sizebytes %zx, session %d\n", + payload_type, vchan_id, sizebytes, session_id); + + if (sizebytes) + pr_err("message is dropped\n"); + return; } else if (vchan->otherend_closed) { hab_vchan_put(vchan); + pr_debug("vchan remote is closed, payload type %d, vchan id %x, sizebytes %zx, session %d\n", + payload_type, vchan_id, sizebytes, session_id); + + if (sizebytes) + pr_err("message is dropped\n"); + return; } + } else { + if (sizebytes != sizeof(struct hab_open_send_data)) { + pr_err("Invalid open request received, payload type %d, vchan id %x, sizebytes %zx, session %d\n", + payload_type, vchan_id, sizebytes, session_id); + } } switch (payload_type) { @@ -165,9 +203,12 @@ void hab_msg_recv(struct physical_channel *pchan, case HAB_PAYLOAD_TYPE_INIT: case HAB_PAYLOAD_TYPE_INIT_ACK: case HAB_PAYLOAD_TYPE_ACK: - ret = hab_open_request_add(pchan, header); - if (ret) + ret = hab_open_request_add(pchan, sizebytes, payload_type); + if (ret) { + pr_err("open request add failed, ret %d, payload type %d, sizebytes %zx\n", + ret, payload_type, sizebytes); break; + } wake_up_interruptible(&dev->openq); break; @@ -185,22 +226,49 @@ void hab_msg_recv(struct physical_channel *pchan, exp_desc->domid_local = pchan->dom_id; hab_export_enqueue(vchan, exp_desc); - hab_send_export_ack(pchan, exp_desc); + hab_send_export_ack(vchan, pchan, exp_desc); break; case HAB_PAYLOAD_TYPE_EXPORT_ACK: - ret = hab_receive_create_export_ack(pchan, vchan->ctx); - if (ret) + ret = hab_receive_create_export_ack(pchan, vchan->ctx, + sizebytes); + if (ret) { + pr_err("failed to handled export ack %d\n", ret); break; - + } wake_up_interruptible(&vchan->ctx->exp_wq); break; case HAB_PAYLOAD_TYPE_CLOSE: + /* remote request close */ + pr_debug("remote side request close\n"); + pr_debug(" vchan id %X, other end %X, session %d\n", + vchan->id, vchan->otherend_id, session_id); hab_vchan_stop(vchan); break; + case HAB_PAYLOAD_TYPE_PROFILE: + do_gettimeofday(&tv); + + /* pull down the incoming data */ + message = hab_msg_alloc(pchan, sizebytes); + if (!message) { + pr_err("msg alloc failed\n"); + break; + } + + ((uint64_t *)message->data)[2] = tv.tv_sec; + ((uint64_t *)message->data)[3] = tv.tv_usec; + hab_msg_queue(vchan, message); + break; + default: + pr_err("unknown msg is received\n"); + pr_err("payload type %d, vchan id %x\n", + payload_type, vchan_id); + pr_err("sizebytes %zx, session %d\n", + sizebytes, session_id); + break; } if (vchan) diff --git a/drivers/soc/qcom/hab/hab_open.c b/drivers/soc/qcom/hab/hab_open.c index 66468aa43afd..35f3281604e2 100644 --- a/drivers/soc/qcom/hab/hab_open.c +++ b/drivers/soc/qcom/hab/hab_open.c @@ -42,7 +42,7 @@ int hab_open_request_send(struct hab_open_request *request) } int hab_open_request_add(struct physical_channel *pchan, - struct hab_header *header) + size_t sizebytes, int request_type) { struct hab_open_node *node; struct hab_device *dev = pchan->habdev; @@ -53,12 +53,11 @@ int hab_open_request_add(struct physical_channel *pchan, if (!node) return -ENOMEM; - if (physical_channel_read(pchan, &data, HAB_HEADER_GET_SIZE(*header)) != - HAB_HEADER_GET_SIZE(*header)) + if (physical_channel_read(pchan, &data, sizebytes) != sizebytes) return -EIO; request = &node->request; - request->type = HAB_HEADER_GET_TYPE(*header); + request->type = request_type; request->pchan = pchan; request->vchan_id = data.vchan_id; request->sub_id = data.sub_id; diff --git a/drivers/soc/qcom/hab/hab_parser.c b/drivers/soc/qcom/hab/hab_parser.c new file mode 100644 index 000000000000..a38d9bcf26b9 --- /dev/null +++ b/drivers/soc/qcom/hab/hab_parser.c @@ -0,0 +1,65 @@ +/* Copyright (c) 2017, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "hab.h" + +/* + * set valid mmid value in tbl to show this is valid entry. All inputs here are + * normalized to 1 based integer + */ +static int fill_vmid_mmid_tbl(struct vmid_mmid_desc *tbl, int32_t vm_start, + int32_t vm_range, int32_t mmid_start, + int32_t mmid_range, int32_t be) +{ + int ret = 0; + int i, j; + + for (i = vm_start; i < vm_start+vm_range; i++) { + tbl[i].vmid = i; /* set valid vmid value to make it usable */ + for (j = mmid_start; j < mmid_start + mmid_range; j++) { + /* sanity check */ + if (tbl[i].mmid[j] != HABCFG_VMID_INVALID) { + pr_err("overwrite previous setting, i %d, j %d, be %d\n", + i, j, tbl[i].is_listener[j]); + } + tbl[i].mmid[j] = j; + tbl[i].is_listener[j] = be; /* BE IS listen */ + } + } + + return ret; +} + +void dump_settings(struct local_vmid *settings) +{ + int i, j; + + pr_debug("self vmid is %d\n", settings->self); + for (i = 0; i < HABCFG_VMID_MAX; i++) { + pr_debug("remote vmid %d\n", + settings->vmid_mmid_list[i].vmid); + for (j = 0; j <= HABCFG_MMID_AREA_MAX; j++) { + pr_debug("mmid %d, is_be %d\n", + settings->vmid_mmid_list[i].mmid[j], + settings->vmid_mmid_list[i].is_listener[j]); + } + } +} + +int fill_default_gvm_settings(struct local_vmid *settings, int vmid_local, + int mmid_start, int mmid_end) { + settings->self = vmid_local; + /* default gvm always talks to host as vm0 */ + return fill_vmid_mmid_tbl(settings->vmid_mmid_list, 0, 1, + mmid_start/100, (mmid_end-mmid_start)/100+1, HABCFG_BE_FALSE); +} diff --git a/drivers/soc/qcom/hab/hab_pchan.c b/drivers/soc/qcom/hab/hab_pchan.c index 1ad727f7d90f..36bc29b7bd0c 100644 --- a/drivers/soc/qcom/hab/hab_pchan.c +++ b/drivers/soc/qcom/hab/hab_pchan.c @@ -31,10 +31,13 @@ hab_pchan_alloc(struct hab_device *habdev, int otherend_id) pchan->closed = 1; pchan->hyp_data = NULL; + INIT_LIST_HEAD(&pchan->vchannels); + rwlock_init(&pchan->vchans_lock); spin_lock_init(&pchan->rxbuf_lock); mutex_lock(&habdev->pchan_lock); list_add_tail(&pchan->node, &habdev->pchannels); + habdev->pchan_cnt++; mutex_unlock(&habdev->pchan_lock); return pchan; @@ -47,6 +50,7 @@ static void hab_pchan_free(struct kref *ref) mutex_lock(&pchan->habdev->pchan_lock); list_del(&pchan->node); + pchan->habdev->pchan_cnt--; mutex_unlock(&pchan->habdev->pchan_lock); kfree(pchan->hyp_data); kfree(pchan); @@ -59,11 +63,14 @@ hab_pchan_find_domid(struct hab_device *dev, int dom_id) mutex_lock(&dev->pchan_lock); list_for_each_entry(pchan, &dev->pchannels, node) - if (pchan->dom_id == dom_id) + if (pchan->dom_id == dom_id || dom_id == HABCFG_VMID_DONT_CARE) break; - if (pchan->dom_id != dom_id) + if (pchan->dom_id != dom_id && dom_id != HABCFG_VMID_DONT_CARE) { + pr_err("dom_id mismatch requested %d, existing %d\n", + dom_id, pchan->dom_id); pchan = NULL; + } if (pchan && !kref_get_unless_zero(&pchan->refcount)) pchan = NULL; diff --git a/drivers/soc/qcom/hab/hab_qvm.c b/drivers/soc/qcom/hab/hab_qvm.c index a37590f23c61..fec06cbbd0c7 100644 --- a/drivers/soc/qcom/hab/hab_qvm.c +++ b/drivers/soc/qcom/hab/hab_qvm.c @@ -21,9 +21,51 @@ #include <linux/of.h> #include <linux/of_platform.h> -#define DEFAULT_HAB_SHMEM_IRQ 7 -#define SHMEM_PHYSICAL_ADDR 0x1c050000 +struct shmem_irq_config { + unsigned long factory_addr; /* from gvm settings when provided */ + int irq; /* from gvm settings when provided */ +}; + +/* + * this is for platform does not provide probe features. the size should match + * hab device side (all mmids) + */ +static struct shmem_irq_config pchan_factory_settings[] = { + {0x1b000000, 7}, + {0x1b001000, 8}, + {0x1b002000, 9}, + {0x1b003000, 10}, + {0x1b004000, 11}, + {0x1b005000, 12}, + {0x1b006000, 13}, + {0x1b007000, 14}, + {0x1b008000, 15}, + {0x1b009000, 16}, + {0x1b00a000, 17}, + {0x1b00b000, 18}, + {0x1b00c000, 19}, + {0x1b00d000, 20}, + {0x1b00e000, 21}, + {0x1b00f000, 22}, + {0x1b010000, 23}, + {0x1b011000, 24}, + {0x1b012000, 25}, + {0x1b013000, 26}, + +}; + +static struct qvm_plugin_info { + struct shmem_irq_config *pchan_settings; + int setting_size; + int curr; + int probe_cnt; +} qvm_priv_info = { + pchan_factory_settings, + ARRAY_SIZE(pchan_factory_settings), + 0, + ARRAY_SIZE(pchan_factory_settings) +}; static irqreturn_t shm_irq_handler(int irq, void *_pchan) { @@ -43,22 +85,22 @@ static irqreturn_t shm_irq_handler(int irq, void *_pchan) return rc; } +/* + * this is only for guest + */ static uint64_t get_guest_factory_paddr(struct qvm_channel *dev, - const char *name, uint32_t pages) + unsigned long factory_addr, int irq, const char *name, uint32_t pages) { int i; - dev->guest_factory = ioremap(SHMEM_PHYSICAL_ADDR, PAGE_SIZE); - - if (!dev->guest_factory) { - pr_err("Couldn't map guest_factory\n"); - return 0; - } + pr_debug("name = %s, factory paddr = 0x%lx, irq %d, pages %d\n", + name, factory_addr, irq, pages); + dev->guest_factory = (struct guest_shm_factory *)factory_addr; if (dev->guest_factory->signature != GUEST_SHM_SIGNATURE) { - pr_err("shmem factory signature incorrect: %ld != %lu\n", - GUEST_SHM_SIGNATURE, dev->guest_factory->signature); - iounmap(dev->guest_factory); + pr_err("signature error: %ld != %llu, factory addr %lx\n", + GUEST_SHM_SIGNATURE, dev->guest_factory->signature, + factory_addr); return 0; } @@ -77,16 +119,22 @@ static uint64_t get_guest_factory_paddr(struct qvm_channel *dev, /* See if we successfully created/attached to the region. */ if (dev->guest_factory->status != GSS_OK) { pr_err("create failed: %d\n", dev->guest_factory->status); - iounmap(dev->guest_factory); return 0; } - pr_debug("shm creation size %x\n", dev->guest_factory->size); + pr_debug("shm creation size %x, paddr=%llx, vector %d, dev %pK\n", + dev->guest_factory->size, + dev->guest_factory->shmem, + dev->guest_intr, + dev); + + dev->factory_addr = factory_addr; + dev->irq = irq; return dev->guest_factory->shmem; } -static int create_dispatcher(struct physical_channel *pchan, int id) +static int create_dispatcher(struct physical_channel *pchan) { struct qvm_channel *dev = (struct qvm_channel *)pchan->hyp_data; int ret; @@ -94,21 +142,45 @@ static int create_dispatcher(struct physical_channel *pchan, int id) tasklet_init(&dev->task, physical_channel_rx_dispatch, (unsigned long) pchan); - ret = request_irq(hab_driver.irq, shm_irq_handler, IRQF_SHARED, - hab_driver.devp[id].name, pchan); + pr_debug("request_irq: irq = %d, pchan name = %s", + dev->irq, pchan->name); + ret = request_irq(dev->irq, shm_irq_handler, IRQF_SHARED, + pchan->name, pchan); if (ret) pr_err("request_irq for %s failed: %d\n", - hab_driver.devp[id].name, ret); + pchan->name, ret); return ret; } -static struct physical_channel *habhyp_commdev_alloc(int id) +void hab_pipe_reset(struct physical_channel *pchan) { - struct qvm_channel *dev; - struct physical_channel *pchan = NULL; - int ret = 0, channel = 0; + struct hab_pipe_endpoint *pipe_ep; + struct qvm_channel *dev = (struct qvm_channel *)pchan->hyp_data; + + pipe_ep = hab_pipe_init(dev->pipe, PIPE_SHMEM_SIZE, + pchan->is_be ? 0 : 1); + if (dev->pipe_ep != pipe_ep) + pr_warn("The pipe endpoint must not change\n"); +} + +/* + * allocate hypervisor plug-in specific resource for pchan, and call hab pchan + * alloc common function. hab driver struct is directly accessed. + * commdev: pointer to store the pchan address + * id: index to hab_device (mmids) + * is_be: pchan local endpoint role + * name: pchan name + * return: status 0: success, otherwise: failures + */ +int habhyp_commdev_alloc(void **commdev, int is_be, char *name, + int vmid_remote, struct hab_device *mmid_device) +{ + struct qvm_channel *dev = NULL; + struct qvm_plugin_info *qvm_priv = hab_driver.hyp_priv; + struct physical_channel **pchan = (struct physical_channel **)commdev; + int ret = 0, coid = 0, channel = 0; char *shmdata; uint32_t pipe_alloc_size = hab_pipe_calc_required_bytes(PIPE_SHMEM_SIZE); @@ -119,15 +191,27 @@ static struct physical_channel *habhyp_commdev_alloc(int id) int total_pages; struct page **pages; + pr_debug("habhyp_commdev_alloc: pipe_alloc_size is %d\n", + pipe_alloc_size); + dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) - return ERR_PTR(-ENOMEM); + return -ENOMEM; spin_lock_init(&dev->io_lock); paddr = get_guest_factory_paddr(dev, - hab_driver.devp[id].name, + qvm_priv->pchan_settings[qvm_priv->curr].factory_addr, + qvm_priv->pchan_settings[qvm_priv->curr].irq, + name, pipe_alloc_pages); + qvm_priv->curr++; + if (qvm_priv->curr > qvm_priv->probe_cnt) { + pr_err("factory setting %d overflow probed cnt %d\n", + qvm_priv->curr, qvm_priv->probe_cnt); + ret = -1; + goto err; + } total_pages = dev->guest_factory->size + 1; pages = kmalloc_array(total_pages, sizeof(struct page *), GFP_KERNEL); @@ -147,72 +231,138 @@ static struct physical_channel *habhyp_commdev_alloc(int id) } shmdata = (char *)dev->guest_ctrl + PAGE_SIZE; + + pr_debug("ctrl page 0x%llx mapped at 0x%pK, idx %d\n", + paddr, dev->guest_ctrl, dev->guest_ctrl->idx); + pr_debug("data buffer mapped at 0x%pK\n", shmdata); dev->idx = dev->guest_ctrl->idx; kfree(pages); dev->pipe = (struct hab_pipe *) shmdata; + pr_debug("\"%s\": pipesize %d, addr 0x%pK, be %d\n", name, + pipe_alloc_size, dev->pipe, is_be); dev->pipe_ep = hab_pipe_init(dev->pipe, PIPE_SHMEM_SIZE, - dev->be ? 0 : 1); - - pchan = hab_pchan_alloc(&hab_driver.devp[id], dev->be); - if (!pchan) { + is_be ? 0 : 1); + /* newly created pchan is added to mmid device list */ + *pchan = hab_pchan_alloc(mmid_device, vmid_remote); + if (!(*pchan)) { ret = -ENOMEM; goto err; } - pchan->closed = 0; - pchan->hyp_data = (void *)dev; + (*pchan)->closed = 0; + (*pchan)->hyp_data = (void *)dev; + strlcpy((*pchan)->name, name, MAX_VMID_NAME_SIZE); + (*pchan)->is_be = is_be; dev->channel = channel; + dev->coid = coid; - ret = create_dispatcher(pchan, id); - if (ret < 0) + ret = create_dispatcher(*pchan); + if (ret) goto err; - return pchan; + return ret; err: kfree(dev); - if (pchan) - hab_pchan_put(pchan); + if (*pchan) + hab_pchan_put(*pchan); pr_err("habhyp_commdev_alloc failed: %d\n", ret); - return ERR_PTR(ret); + return ret; +} + +int habhyp_commdev_dealloc(void *commdev) +{ + struct physical_channel *pchan = (struct physical_channel *)commdev; + struct qvm_channel *dev = pchan->hyp_data; + + + kfree(dev); + hab_pchan_put(pchan); + return 0; } int hab_hypervisor_register(void) { - int ret = 0, i; + int ret = 0; hab_driver.b_server_dom = 0; - /* - * Can still attempt to instantiate more channels if one fails. - * Others can be retried later. - */ - for (i = 0; i < hab_driver.ndevices; i++) { - if (IS_ERR(habhyp_commdev_alloc(i))) - ret = -EAGAIN; - } + pr_info("initializing for %s VM\n", hab_driver.b_server_dom ? + "host" : "guest"); + + hab_driver.hyp_priv = &qvm_priv_info; return ret; } void hab_hypervisor_unregister(void) { + int status, i; + + for (i = 0; i < hab_driver.ndevices; i++) { + struct hab_device *dev = &hab_driver.devp[i]; + struct physical_channel *pchan; + + list_for_each_entry(pchan, &dev->pchannels, node) { + status = habhyp_commdev_dealloc(pchan); + if (status) { + pr_err("failed to free pchan %pK, i %d, ret %d\n", + pchan, i, status); + } + } + } + + qvm_priv_info.probe_cnt = 0; + qvm_priv_info.curr = 0; } static int hab_shmem_probe(struct platform_device *pdev) { - int irq = platform_get_irq(pdev, 0); + int irq = 0; + struct resource *mem; + void *shmem_base = NULL; + int ret = 0; + + /* hab in one GVM will not have pchans more than one VM could allowed */ + if (qvm_priv_info.probe_cnt >= hab_driver.ndevices) { + pr_err("no more channel, current %d, maximum %d\n", + qvm_priv_info.probe_cnt, hab_driver.ndevices); + return -ENODEV; + } - if (irq > 0) - hab_driver.irq = irq; - else - hab_driver.irq = DEFAULT_HAB_SHMEM_IRQ; + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + pr_err("no interrupt for the channel %d, error %d\n", + qvm_priv_info.probe_cnt, irq); + return irq; + } + qvm_priv_info.pchan_settings[qvm_priv_info.probe_cnt].irq = irq; - return 0; + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) { + pr_err("can not get io mem resource for channel %d\n", + qvm_priv_info.probe_cnt); + return -EINVAL; + } + shmem_base = devm_ioremap_resource(&pdev->dev, mem); + if (IS_ERR(shmem_base)) { + pr_err("ioremap failed for channel %d, mem %pK\n", + qvm_priv_info.probe_cnt, mem); + return -EINVAL; + } + qvm_priv_info.pchan_settings[qvm_priv_info.probe_cnt].factory_addr + = (unsigned long)((uintptr_t)shmem_base); + + pr_debug("pchan idx %d, hab irq=%d shmem_base=%pK, mem %pK\n", + qvm_priv_info.probe_cnt, irq, shmem_base, mem); + + qvm_priv_info.probe_cnt++; + + return ret; } static int hab_shmem_remove(struct platform_device *pdev) @@ -220,6 +370,23 @@ static int hab_shmem_remove(struct platform_device *pdev) return 0; } +static void hab_shmem_shutdown(struct platform_device *pdev) +{ + int i; + struct qvm_channel *dev; + struct physical_channel *pchan; + struct hab_device hab_dev; + + for (i = 0; i < hab_driver.ndevices; i++) { + hab_dev = hab_driver.devp[i]; + pr_debug("detaching %s\n", hab_dev.name); + list_for_each_entry(pchan, &hab_dev.pchannels, node) { + dev = (struct qvm_channel *)pchan->hyp_data; + dev->guest_ctrl->detach = 0; + } + } +} + static const struct of_device_id hab_shmem_match_table[] = { {.compatible = "qvm,guest_shm"}, {}, @@ -228,6 +395,7 @@ static const struct of_device_id hab_shmem_match_table[] = { static struct platform_driver hab_shmem_driver = { .probe = hab_shmem_probe, .remove = hab_shmem_remove, + .shutdown = hab_shmem_shutdown, .driver = { .name = "hab_shmem", .of_match_table = of_match_ptr(hab_shmem_match_table), @@ -236,12 +404,14 @@ static struct platform_driver hab_shmem_driver = { static int __init hab_shmem_init(void) { + qvm_priv_info.probe_cnt = 0; return platform_driver_register(&hab_shmem_driver); } static void __exit hab_shmem_exit(void) { platform_driver_unregister(&hab_shmem_driver); + qvm_priv_info.probe_cnt = 0; } core_initcall(hab_shmem_init); diff --git a/drivers/soc/qcom/hab/hab_qvm.h b/drivers/soc/qcom/hab/hab_qvm.h index e94b82f87942..b483f4c21331 100644 --- a/drivers/soc/qcom/hab/hab_qvm.h +++ b/drivers/soc/qcom/hab/hab_qvm.h @@ -30,6 +30,7 @@ struct qvm_channel { struct tasklet_struct task; struct guest_shm_factory *guest_factory; struct guest_shm_control *guest_ctrl; + /* cached guest ctrl idx value to prevent trap when accessed */ uint32_t idx; int channel; @@ -37,11 +38,15 @@ struct qvm_channel { unsigned int guest_intr; unsigned int guest_iid; + unsigned int factory_addr; + unsigned int irq; + }; /* Shared mem size in each direction for communication pipe */ #define PIPE_SHMEM_SIZE (128 * 1024) void *qnx_hyp_rx_dispatch(void *data); +void hab_pipe_reset(struct physical_channel *pchan); #endif /* __HAB_QNX_H */ diff --git a/drivers/soc/qcom/hab/hab_vchan.c b/drivers/soc/qcom/hab/hab_vchan.c index 75a3fad68ab5..91ae173f7e83 100644 --- a/drivers/soc/qcom/hab/hab_vchan.c +++ b/drivers/soc/qcom/hab/hab_vchan.c @@ -40,6 +40,9 @@ hab_vchan_alloc(struct uhab_context *ctx, struct physical_channel *pchan) hab_pchan_get(pchan); vchan->pchan = pchan; + write_lock(&pchan->vchans_lock); + list_add_tail(&vchan->pnode, &pchan->vchannels); + write_unlock(&pchan->vchans_lock); vchan->id = ((id << HAB_VCID_ID_SHIFT) & HAB_VCID_ID_MASK) | ((pchan->habdev->id << HAB_VCID_MMID_SHIFT) & HAB_VCID_MMID_MASK) | @@ -66,19 +69,22 @@ hab_vchan_free(struct kref *ref) struct virtual_channel *vchan = container_of(ref, struct virtual_channel, refcount); struct hab_message *message, *msg_tmp; - struct export_desc *exp; + struct export_desc *exp, *exp_tmp; struct physical_channel *pchan = vchan->pchan; struct uhab_context *ctx = vchan->ctx; + struct virtual_channel *vc, *vc_tmp; + spin_lock_bh(&vchan->rx_lock); list_for_each_entry_safe(message, msg_tmp, &vchan->rx_list, node) { list_del(&message->node); hab_msg_free(message); } + spin_unlock_bh(&vchan->rx_lock); do { found = 0; write_lock(&ctx->exp_lock); - list_for_each_entry(exp, &ctx->exp_whse, node) { + list_for_each_entry_safe(exp, exp_tmp, &ctx->exp_whse, node) { if (exp->vcid_local == vchan->id) { list_del(&exp->node); found = 1; @@ -95,7 +101,7 @@ hab_vchan_free(struct kref *ref) do { found = 0; spin_lock_bh(&ctx->imp_lock); - list_for_each_entry(exp, &ctx->imp_whse, node) { + list_for_each_entry_safe(exp, exp_tmp, &ctx->imp_whse, node) { if (exp->vcid_remote == vchan->id) { list_del(&exp->node); found = 1; @@ -117,6 +123,15 @@ hab_vchan_free(struct kref *ref) idr_remove(&pchan->vchan_idr, HAB_VCID_GET_ID(vchan->id)); spin_unlock_bh(&pchan->vid_lock); + write_lock(&pchan->vchans_lock); + list_for_each_entry_safe(vc, vc_tmp, &pchan->vchannels, pnode) { + if (vchan == vc) { + list_del(&vc->pnode); + break; + } + } + write_unlock(&pchan->vchans_lock); + hab_pchan_put(pchan); hab_ctx_put(ctx); @@ -124,14 +139,17 @@ hab_vchan_free(struct kref *ref) } struct virtual_channel* -hab_vchan_get(struct physical_channel *pchan, uint32_t vchan_id) +hab_vchan_get(struct physical_channel *pchan, struct hab_header *header) { struct virtual_channel *vchan; + uint32_t vchan_id = HAB_HEADER_GET_ID(*header); + uint32_t session_id = HAB_HEADER_GET_SESSION_ID(*header); spin_lock_bh(&pchan->vid_lock); vchan = idr_find(&pchan->vchan_idr, HAB_VCID_GET_ID(vchan_id)); if (vchan) - if (!kref_get_unless_zero(&vchan->refcount)) + if ((vchan->session_id != session_id) || + (!kref_get_unless_zero(&vchan->refcount))) vchan = NULL; spin_unlock_bh(&pchan->vid_lock); @@ -146,6 +164,17 @@ void hab_vchan_stop(struct virtual_channel *vchan) } } +void hab_vchans_stop(struct physical_channel *pchan) +{ + struct virtual_channel *vchan, *tmp; + + read_lock(&pchan->vchans_lock); + list_for_each_entry_safe(vchan, tmp, &pchan->vchannels, pnode) { + hab_vchan_stop(vchan); + } + read_unlock(&pchan->vchans_lock); +} + void hab_vchan_stop_notify(struct virtual_channel *vchan) { hab_send_close_msg(vchan); diff --git a/drivers/soc/qcom/hab/khab.c b/drivers/soc/qcom/hab/khab.c index f7499773ae42..05e6aa2fa7ca 100644 --- a/drivers/soc/qcom/hab/khab.c +++ b/drivers/soc/qcom/hab/khab.c @@ -117,7 +117,7 @@ int32_t habmm_import(int32_t handle, void **buff_shared, uint32_t size_bytes, param.flags = flags; ret = hab_mem_import(hab_driver.kctx, ¶m, 1); - if (!IS_ERR(ret)) + if (!ret) *buff_shared = (void *)(uintptr_t)param.kva; return ret; diff --git a/drivers/soc/qcom/hab/qvm_comm.c b/drivers/soc/qcom/hab/qvm_comm.c index 20a631e13794..41e34be9ac21 100644 --- a/drivers/soc/qcom/hab/qvm_comm.c +++ b/drivers/soc/qcom/hab/qvm_comm.c @@ -21,6 +21,7 @@ static inline void habhyp_notify(void *commdev) dev->guest_ctrl->notify = ~0; } +/* this is only used to read payload, never the head! */ int physical_channel_read(struct physical_channel *pchan, void *payload, size_t read_size) @@ -33,6 +34,8 @@ int physical_channel_read(struct physical_channel *pchan, return 0; } +#define HAB_HEAD_SIGNATURE 0xBEE1BEE1 + int physical_channel_send(struct physical_channel *pchan, struct hab_header *header, void *payload) @@ -40,6 +43,7 @@ int physical_channel_send(struct physical_channel *pchan, int sizebytes = HAB_HEADER_GET_SIZE(*header); struct qvm_channel *dev = (struct qvm_channel *)pchan->hyp_data; int total_size = sizeof(*header) + sizebytes; + struct timeval tv; if (total_size > dev->pipe_ep->tx_info.sh_buf->size) return -EINVAL; /* too much data for ring */ @@ -53,6 +57,8 @@ int physical_channel_send(struct physical_channel *pchan, return -EAGAIN; /* not enough free space */ } + header->signature = HAB_HEAD_SIGNATURE; + if (hab_pipe_write(dev->pipe_ep, (unsigned char *)header, sizeof(*header)) != sizeof(*header)) { @@ -60,6 +66,12 @@ int physical_channel_send(struct physical_channel *pchan, return -EIO; } + if (HAB_HEADER_GET_TYPE(*header) == HAB_PAYLOAD_TYPE_PROFILE) { + do_gettimeofday(&tv); + ((uint64_t *)payload)[0] = tv.tv_sec; + ((uint64_t *)payload)[1] = tv.tv_usec; + } + if (sizebytes) { if (hab_pipe_write(dev->pipe_ep, (unsigned char *)payload, @@ -89,6 +101,14 @@ void physical_channel_rx_dispatch(unsigned long data) sizeof(header)) != sizeof(header)) break; /* no data available */ + if (header.signature != HAB_HEAD_SIGNATURE) { + pr_err("HAB signature mismatch, expect %X, received %X, id_type_size %X, session %X, sequence %X\n", + HAB_HEAD_SIGNATURE, header.signature, + header.id_type_size, + header.session_id, + header.sequence); + } + hab_msg_recv(pchan, &header); } spin_unlock_bh(&pchan->rxbuf_lock); diff --git a/drivers/soc/qcom/msm_glink_pkt.c b/drivers/soc/qcom/msm_glink_pkt.c index 2a2d213f8ca0..ecc633749204 100644 --- a/drivers/soc/qcom/msm_glink_pkt.c +++ b/drivers/soc/qcom/msm_glink_pkt.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -572,8 +572,10 @@ static void glink_pkt_notify_state_worker(struct work_struct *work) mutex_lock(&devp->ch_lock); devp->ch_state = event; if (event == GLINK_CONNECTED) { - if (!devp->handle) - devp->handle = handle; + if (!devp->handle) { + GLINK_PKT_ERR("%s: Invalid device handle\n", __func__); + goto exit; + } devp->in_reset = 0; wake_up_interruptible(&devp->ch_opened_wait_queue); } else if (event == GLINK_REMOTE_DISCONNECTED) { @@ -585,6 +587,7 @@ static void glink_pkt_notify_state_worker(struct work_struct *work) devp->handle = NULL; wake_up_interruptible(&devp->ch_closed_wait_queue); } +exit: mutex_unlock(&devp->ch_lock); kfree(work_item); } diff --git a/drivers/usb/gadget/function/f_qc_rndis.c b/drivers/usb/gadget/function/f_qc_rndis.c index a28bcd084dc3..8a2346ce6b42 100644 --- a/drivers/usb/gadget/function/f_qc_rndis.c +++ b/drivers/usb/gadget/function/f_qc_rndis.c @@ -106,6 +106,7 @@ struct f_rndis_qc { u8 port_num; u16 cdc_filter; bool net_ready_trigger; + bool use_wceis; }; static struct ipa_usb_init_params rndis_ipa_params; @@ -161,9 +162,9 @@ static struct usb_interface_descriptor rndis_qc_control_intf = { /* .bInterfaceNumber = DYNAMIC */ /* status endpoint is optional; this could be patched later */ .bNumEndpoints = 1, - .bInterfaceClass = USB_CLASS_WIRELESS_CONTROLLER, - .bInterfaceSubClass = 0x01, - .bInterfaceProtocol = 0x03, + .bInterfaceClass = USB_CLASS_MISC, + .bInterfaceSubClass = 0x04, + .bInterfaceProtocol = 0x01, /* RNDIS over ethernet */ /* .iInterface = DYNAMIC */ }; @@ -222,9 +223,9 @@ rndis_qc_iad_descriptor = { .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, .bFirstInterface = 0, /* XXX, hardcoded */ .bInterfaceCount = 2, /* control + data */ - .bFunctionClass = USB_CLASS_WIRELESS_CONTROLLER, - .bFunctionSubClass = 0x01, - .bFunctionProtocol = 0x03, + .bFunctionClass = USB_CLASS_MISC, + .bFunctionSubClass = 0x04, + .bFunctionProtocol = 0x01, /* RNDIS over ethernet */ /* .iFunction = DYNAMIC */ }; @@ -935,6 +936,17 @@ rndis_qc_bind(struct usb_configuration *c, struct usb_function *f) rndis_qc_iad_descriptor.iFunction = status; } + if (rndis->use_wceis) { + rndis_qc_iad_descriptor.bFunctionClass = + USB_CLASS_WIRELESS_CONTROLLER; + rndis_qc_iad_descriptor.bFunctionSubClass = 0x01; + rndis_qc_iad_descriptor.bFunctionProtocol = 0x03; + rndis_qc_control_intf.bInterfaceClass = + USB_CLASS_WIRELESS_CONTROLLER; + rndis_qc_control_intf.bInterfaceSubClass = 0x1; + rndis_qc_control_intf.bInterfaceProtocol = 0x03; + } + /* allocate instance-specific interface IDs */ status = usb_interface_id(c, f); if (status < 0) @@ -1470,8 +1482,38 @@ static struct configfs_item_operations qcrndis_item_ops = { .release = qcrndis_attr_release, }; + +static ssize_t qcrndis_wceis_show(struct config_item *item, char *page) +{ + struct f_rndis_qc *rndis = to_f_qc_rndis_opts(item)->rndis; + + return snprintf(page, PAGE_SIZE, "%d\n", rndis->use_wceis); +} + +static ssize_t qcrndis_wceis_store(struct config_item *item, + const char *page, size_t len) +{ + struct f_rndis_qc *rndis = to_f_qc_rndis_opts(item)->rndis; + bool val; + + if (kstrtobool(page, &val)) + return -EINVAL; + + rndis->use_wceis = val; + + return len; +} + +CONFIGFS_ATTR(qcrndis_, wceis); + +static struct configfs_attribute *qcrndis_attrs[] = { + &qcrndis_attr_wceis, + NULL, +}; + static struct config_item_type qcrndis_func_type = { .ct_item_ops = &qcrndis_item_ops, + .ct_attrs = qcrndis_attrs, .ct_owner = THIS_MODULE, }; diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h index 6819af659768..ca2ceff39f2f 100644 --- a/include/sound/apr_audio-v2.h +++ b/include/sound/apr_audio-v2.h @@ -501,70 +501,36 @@ struct adm_cmd_device_open_v6 { /* Sets one or more parameters to a COPP. */ #define ADM_CMD_SET_PP_PARAMS_V5 0x00010328 +#define ADM_CMD_SET_PP_PARAMS_V6 0x0001035D -/* Payload of the #ADM_CMD_SET_PP_PARAMS_V5 command. - * If the data_payload_addr_lsw and data_payload_addr_msw element - * are NULL, a series of adm_param_datastructures immediately - * follows, whose total size is data_payload_size bytes. +/* + * Structure of the ADM Set PP Params command. Parameter data must be + * pre-packed with correct header for either V2 or V3 when sent in-band. + * Use q6core_pack_pp_params to pack the header and data correctly depending on + * Instance ID support. */ -struct adm_cmd_set_pp_params_v5 { - struct apr_hdr hdr; - u32 payload_addr_lsw; - /* LSW of parameter data payload address.*/ - u32 payload_addr_msw; - /* MSW of parameter data payload address.*/ +struct adm_cmd_set_pp_params { + /* APR Header */ + struct apr_hdr apr_hdr; - u32 mem_map_handle; -/* Memory map handle returned by ADM_CMD_SHARED_MEM_MAP_REGIONS - * command */ -/* If mem_map_handle is zero implies the message is in - * the payload */ + /* The memory mapping header to be used when sending out of band */ + struct mem_mapping_hdr mem_hdr; - u32 payload_size; -/* Size in bytes of the variable payload accompanying this - * message or - * in shared memory. This is used for parsing the parameter - * payload. - */ -} __packed; - -/* Payload format for COPP parameter data. - * Immediately following this structure are param_size bytes - * of parameter - * data. - */ -struct adm_param_data_v5 { - u32 module_id; - /* Unique ID of the module. */ - u32 param_id; - /* Unique ID of the parameter. */ - u16 param_size; - /* Data size of the param_id/module_id combination. - This value is a - multiple of 4 bytes. */ - u16 reserved; - /* Reserved for future enhancements. - * This field must be set to zero. + /* Size in bytes of the variable payload accompanying this + * message or + * in shared memory. This is used for parsing the parameter + * payload. */ -} __packed; - - -struct param_data_v6 { - /* Unique ID of the module. */ - u32 module_id; - /* Unique ID of the instance. */ - u16 instance_id; - /* Reserved for future enhancements. - * This field must be set to zero. + u32 payload_size; + + /* Parameter data for in band payload. This should be structured as the + * parameter header immediately followed by the parameter data. Multiple + * parameters can be set in one command by repeating the header followed + * by the data for as many parameters as need to be set. + * Use q6core_pack_pp_params to pack the header and data correctly + * depending on Instance ID support. */ - u16 reserved; - /* Unique ID of the parameter. */ - u32 param_id; - /* Data size of the param_id/module_id combination. - * This value is a - * multiple of 4 bytes. - */ - u32 param_size; + u8 param_data[0]; } __packed; /* ADM_CMD_SET_MTMX_STRTR_DEV_PARAMS_V1 command is used to set @@ -582,7 +548,7 @@ struct param_data_v6 { /* Payload of the #define ADM_CMD_SET_MTMX_STRTR_DEV_PARAMS_V1 command. * If the data_payload_addr_lsw and data_payload_addr_msw element - * are NULL, a series of struct param_data_v6 structures immediately + * are NULL, a series of struct param_hdr_v3 structures immediately * follows, whose total size is payload_size bytes. */ struct adm_cmd_set_mtmx_params_v1 { @@ -619,7 +585,7 @@ struct enable_param_v6 { * This parameter is generic/common parameter to configure or * determine the state of any audio processing module. */ - struct param_data_v6 param; + struct param_hdr_v3 param; /* @values 0 : Disable 1: Enable */ uint32_t enable; @@ -672,25 +638,6 @@ struct adm_cmd_set_pspd_mtmx_strtr_params_v5 { u16 reserved; } __packed; -/* Defined specifically for in-band use, includes params */ -struct adm_cmd_set_pp_params_inband_v5 { - struct apr_hdr hdr; - /* LSW of parameter data payload address.*/ - u32 payload_addr_lsw; - /* MSW of parameter data payload address.*/ - u32 payload_addr_msw; - /* Memory map handle returned by ADM_CMD_SHARED_MEM_MAP_REGIONS */ - /* command. If mem_map_handle is zero implies the message is in */ - /* the payload */ - u32 mem_map_handle; - /* Size in bytes of the variable payload accompanying this */ - /* message or in shared memory. This is used for parsing the */ - /* parameter payload. */ - u32 payload_size; - /* Parameters passed for in band payload */ - struct adm_param_data_v5 params; -} __packed; - /* Returns the status and COPP ID to an #ADM_CMD_DEVICE_OPEN_V5 command. */ #define ADM_CMDRSP_DEVICE_OPEN_V5 0x00010329 @@ -723,44 +670,21 @@ struct adm_cmd_rsp_device_open_v5 { /* This command allows a query of one COPP parameter. */ #define ADM_CMD_GET_PP_PARAMS_V5 0x0001032A +#define ADM_CMD_GET_PP_PARAMS_V6 0x0001035E -/* Payload an #ADM_CMD_GET_PP_PARAMS_V5 command. -*/ -struct adm_cmd_get_pp_params_v5 { - struct apr_hdr hdr; - u32 data_payload_addr_lsw; - /* LSW of parameter data payload address.*/ - - u32 data_payload_addr_msw; - /* MSW of parameter data payload address.*/ - - /* If the mem_map_handle is non zero, - * on ACK, the ParamData payloads begin at - * the address specified (out-of-band). - */ - - u32 mem_map_handle; - /* Memory map handle returned - * by ADM_CMD_SHARED_MEM_MAP_REGIONS command. - * If the mem_map_handle is 0, it implies that - * the ACK's payload will contain the ParamData (in-band). - */ - - u32 module_id; - /* Unique ID of the module. */ +/* + * Structure of the ADM Get PP Params command. Parameter header must be + * packed correctly for either V2 or V3. Use q6core_pack_pp_params to pack the + * header correctly depending on Instance ID support. + */ +struct adm_cmd_get_pp_params { + struct apr_hdr apr_hdr; - u32 param_id; - /* Unique ID of the parameter. */ + /* The memory mapping header to be used when requesting outband */ + struct mem_mapping_hdr mem_hdr; - u16 param_max_size; - /* Maximum data size of the parameter - *ID/module ID combination. This - * field is a multiple of 4 bytes. - */ - u16 reserved; - /* Reserved for future enhancements. - * This field must be set to zero. - */ + /* Parameter header for in band payload. */ + union param_hdrs param_hdr; } __packed; /* Returns parameter values @@ -772,15 +696,48 @@ struct adm_cmd_get_pp_params_v5 { * which returns parameter values in response * to an #ADM_CMD_GET_PP_PARAMS_V5 command. * Immediately following this - * structure is the adm_param_data_v5 + * structure is the param_hdr_v1 * structure containing the pre/postprocessing * parameter data. For an in-band * scenario, the variable payload depends * on the size of the parameter. */ struct adm_cmd_rsp_get_pp_params_v5 { - u32 status; /* Status message (error code).*/ + u32 status; + + /* The header that identifies the subsequent parameter data */ + struct param_hdr_v1 param_hdr; + + /* The parameter data returned */ + u32 param_data[0]; +} __packed; + +/* + * Returns parameter values in response to an #ADM_CMD_GET_PP_PARAMS_V5/6 + * command. + */ +#define ADM_CMDRSP_GET_PP_PARAMS_V6 0x0001035F + +/* Payload of the #ADM_CMDRSP_GET_PP_PARAMS_V6 message, + * which returns parameter values in response + * to an #ADM_CMD_GET_PP_PARAMS_V6 command. + * Immediately following this + * structure is the param_hdr_v3 + * structure containing the pre/postprocessing + * parameter data. For an in-band + * scenario, the variable payload depends + * on the size of the parameter. +*/ +struct adm_cmd_rsp_get_pp_params_v6 { + /* Status message (error code).*/ + u32 status; + + /* The header that identifies the subsequent parameter data */ + struct param_hdr_v3 param_hdr; + + /* The parameter data returned */ + u32 param_data[0]; } __packed; /* Structure for holding soft stepping volume parameters. */ @@ -833,9 +790,29 @@ struct adm_pspd_param_data_t { uint16_t reserved; } __packed; -struct audproc_mfc_output_media_fmt { - struct adm_cmd_set_pp_params_v5 params; - struct adm_param_data_v5 data; +struct adm_cmd_set_pp_params_v5 { + struct apr_hdr hdr; + u32 payload_addr_lsw; + /* LSW of parameter data payload address.*/ + u32 payload_addr_msw; + /* MSW of parameter data payload address.*/ + + u32 mem_map_handle; + /* Memory map handle returned by ADM_CMD_SHARED_MEM_MAP_REGIONS + * command. + * If mem_map_handle is zero implies the message is in + * the payload + */ + + u32 payload_size; + /* Size in bytes of the variable payload accompanying this + * message or + * in shared memory. This is used for parsing the parameter + * payload. + */ +} __packed; + +struct audproc_mfc_param_media_fmt { uint32_t sampling_rate; uint16_t bits_per_sample; uint16_t num_channels; @@ -843,8 +820,6 @@ struct audproc_mfc_output_media_fmt { } __packed; struct audproc_volume_ctrl_master_gain { - struct adm_cmd_set_pp_params_v5 params; - struct adm_param_data_v5 data; /* Linear gain in Q13 format. */ uint16_t master_gain; /* Clients must set this field to zero. */ @@ -852,8 +827,6 @@ struct audproc_volume_ctrl_master_gain { } __packed; struct audproc_soft_step_volume_params { - struct adm_cmd_set_pp_params_v5 params; - struct adm_param_data_v5 data; /* * Period in milliseconds. * Supported values: 0 to 15000 @@ -875,7 +848,6 @@ struct audproc_soft_step_volume_params { } __packed; struct audproc_enable_param_t { - struct adm_cmd_set_pp_params_inband_v5 pp_params; /* * Specifies whether the Audio processing module is enabled. * This parameter is generic/common parameter to configure or @@ -1599,87 +1571,136 @@ struct afe_sidetone_iir_filter_config_params { #define AFE_MODULE_LOOPBACK 0x00010205 #define AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH 0x00010206 -/* Payload of the #AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH parameter, - * which gets/sets loopback gain of a port to an Rx port. - * The Tx port ID of the loopback is part of the set_param command. - */ +/* Used by RTAC */ +struct afe_rtac_user_data_set_v2 { + /* Port interface and direction (Rx or Tx) to start. */ + u16 port_id; -/* Payload of the #AFE_PORT_CMD_SET_PARAM_V2 command's - * configuration/calibration settings for the AFE port. - */ -struct afe_port_cmd_set_param_v2 { + /* Actual size of the payload in bytes. + * This is used for parsing the parameter payload. + * Supported values: > 0 + */ + u16 payload_size; + + /* The header detailing the memory mapping for out of band. */ + struct mem_mapping_hdr mem_hdr; + + /* The parameter header for the parameter data to set */ + struct param_hdr_v1 param_hdr; + + /* The parameter data to be filled when sent inband */ + u32 *param_data; +} __packed; + +struct afe_rtac_user_data_set_v3 { + /* Port interface and direction (Rx or Tx) to start. */ + u16 port_id; + /* Reserved for future enhancements. Must be 0. */ + u16 reserved; + + /* The header detailing the memory mapping for out of band. */ + struct mem_mapping_hdr mem_hdr; + + /* The size of the parameter header and parameter data */ + u32 payload_size; + + /* The parameter header for the parameter data to set */ + struct param_hdr_v3 param_hdr; + + /* The parameter data to be filled when sent inband */ + u32 *param_data; +} __packed; + +struct afe_rtac_user_data_get_v2 { + /* Port interface and direction (Rx or Tx) to start. */ u16 port_id; -/* Port interface and direction (Rx or Tx) to start. - */ + /* Actual size of the payload in bytes. + * This is used for parsing the parameter payload. + * Supported values: > 0 + */ u16 payload_size; -/* Actual size of the payload in bytes. - * This is used for parsing the parameter payload. - * Supported values: > 0 - */ -u32 payload_address_lsw; -/* LSW of 64 bit Payload address. - * Address should be 32-byte, - * 4kbyte aligned and must be contiguous memory. - */ + /* The header detailing the memory mapping for out of band. */ + struct mem_mapping_hdr mem_hdr; -u32 payload_address_msw; -/* MSW of 64 bit Payload address. - * In case of 32-bit shared memory address, - * this field must be set to zero. - * In case of 36-bit shared memory address, - * bit-4 to bit-31 must be set to zero. - * Address should be 32-byte, 4kbyte aligned - * and must be contiguous memory. - */ + /* The module ID of the parameter to get */ + u32 module_id; -u32 mem_map_handle; -/* Memory map handle returned by - * AFE_SERVICE_CMD_SHARED_MEM_MAP_REGIONS commands. - * Supported Values: - * - NULL -- Message. The parameter data is in-band. - * - Non-NULL -- The parameter data is Out-band.Pointer to - * the physical address - * in shared memory of the payload data. - * An optional field is available if parameter - * data is in-band: - * afe_param_data_v2 param_data[...]. - * For detailed payload content, see the - * afe_port_param_data_v2 structure. - */ + /* The parameter ID of the parameter to get */ + u32 param_id; + + /* The parameter data to be filled when sent inband */ + struct param_hdr_v1 param_hdr; } __packed; +struct afe_rtac_user_data_get_v3 { + /* Port interface and direction (Rx or Tx) to start. */ + u16 port_id; + /* Reserved for future enhancements. Must be 0. */ + u16 reserved; + + /* The header detailing the memory mapping for out of band. */ + struct mem_mapping_hdr mem_hdr; + + /* The parameter data to be filled when sent inband */ + struct param_hdr_v3 param_hdr; +} __packed; #define AFE_PORT_CMD_SET_PARAM_V2 0x000100EF +struct afe_port_cmd_set_param_v2 { + /* APR Header */ + struct apr_hdr apr_hdr; -struct afe_port_param_data_v2 { - u32 module_id; -/* ID of the module to be configured. - * Supported values: Valid module ID - */ + /* Port interface and direction (Rx or Tx) to start. */ + u16 port_id; -u32 param_id; -/* ID of the parameter corresponding to the supported parameters - * for the module ID. - * Supported values: Valid parameter ID - */ + /* + * Actual size of the payload in bytes. + * This is used for parsing the parameter payload. + * Supported values: > 0 + */ + u16 payload_size; -u16 param_size; -/* Actual size of the data for the - * module_id/param_id pair. The size is a - * multiple of four bytes. - * Supported values: > 0 - */ + /* The header detailing the memory mapping for out of band. */ + struct mem_mapping_hdr mem_hdr; -u16 reserved; -/* This field must be set to zero. - */ + /* The parameter data to be filled when sent inband */ + u8 param_data[0]; } __packed; +#define AFE_PORT_CMD_SET_PARAM_V3 0x000100FA +struct afe_port_cmd_set_param_v3 { + /* APR Header */ + struct apr_hdr apr_hdr; + + /* Port ID of the AFE port to configure. Port interface and direction + * (Rx or Tx) to configure. An even number represents the Rx direction, + * and an odd number represents the Tx direction. + */ + u16 port_id; + + /* Reserved. This field must be set to zero. */ + u16 reserved; + + /* The memory mapping header to be used when sending outband */ + struct mem_mapping_hdr mem_hdr; + + /* The total size of the payload, including param_hdr_v3 */ + u32 payload_size; + + /* + * The parameter data to be filled when sent inband. + * Must include param_hdr packed correctly. + */ + u8 param_data[0]; +} __packed; + +/* Payload of the #AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH parameter, + * which gets/sets loopback gain of a port to an Rx port. + * The Tx port ID of the loopback is part of the set_param command. + */ + struct afe_loopback_gain_per_path_param { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; u16 rx_port_id; /* Rx port of the loopback. */ @@ -1715,9 +1736,6 @@ enum afe_loopback_routing_mode { * which enables/disables one AFE loopback. */ struct afe_loopback_cfg_v1 { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; u32 loopback_cfg_minor_version; /* Minor version used for tracking the version of the RMC module * configuration interface. @@ -1779,19 +1797,19 @@ struct loopback_cfg_data { struct afe_st_loopback_cfg_v1 { struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 gain_pdata; + struct mem_mapping_hdr mem_hdr; + struct param_hdr_v1 gain_pdata; struct afe_loopback_sidetone_gain gain_data; - struct afe_port_param_data_v2 cfg_pdata; + struct param_hdr_v1 cfg_pdata; struct loopback_cfg_data cfg_data; } __packed; struct afe_loopback_iir_cfg_v2 { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 st_iir_enable_pdata; - struct afe_mod_enable_param st_iir_mode_enable_data; - struct afe_port_param_data_v2 st_iir_filter_config_pdata; + struct apr_hdr hdr; + struct mem_mapping_hdr param; + struct param_hdr_v1 st_iir_enable_pdata; + struct afe_mod_enable_param st_iir_mode_enable_data; + struct param_hdr_v1 st_iir_filter_config_pdata; struct afe_sidetone_iir_filter_config_params st_iir_filter_config_data; } __packed; #define AFE_MODULE_SPEAKER_PROTECTION 0x00010209 @@ -2243,20 +2261,6 @@ struct afe_param_id_spdif_clk_cfg { */ } __packed; -struct afe_spdif_clk_config_command { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; - struct afe_param_id_spdif_clk_cfg clk_cfg; -} __packed; - -struct afe_spdif_chstatus_config_command { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; - struct afe_param_id_spdif_ch_status_cfg ch_status; -} __packed; - struct afe_spdif_port_config { struct afe_param_id_spdif_cfg cfg; struct afe_param_id_spdif_ch_status_cfg ch_status; @@ -2782,16 +2786,6 @@ struct afe_param_id_usb_audio_cfg { u32 endian; } __packed; -struct afe_usb_audio_dev_param_command { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; - union { - struct afe_param_id_usb_audio_dev_params usb_dev; - struct afe_param_id_usb_audio_dev_lpcm_fmt lpcm_fmt; - }; -} __packed; - /* * This param id is used to configure Real Time Proxy interface. */ @@ -3186,20 +3180,6 @@ struct afe_param_id_custom_tdm_header_cfg { uint16_t header7; Reserved Info[3] - Bitrate[kbps] - Low Byte -> 0x0 */ } __packed; -struct afe_slot_mapping_config_command { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; - struct afe_param_id_slot_mapping_cfg slot_mapping; -} __packed; - -struct afe_custom_tdm_header_config_command { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; - struct afe_param_id_custom_tdm_header_cfg custom_tdm_header; -} __packed; - struct afe_tdm_port_config { struct afe_param_id_tdm_cfg tdm; struct afe_param_id_slot_mapping_cfg slot_mapping; @@ -3576,18 +3556,6 @@ union afe_port_config { struct avs_enc_packetizer_id_param_t enc_pkt_id_param; } __packed; -struct afe_audioif_config_command_no_payload { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; -} __packed; - -struct afe_audioif_config_command { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; - union afe_port_config port; -} __packed; - #define AFE_PORT_CMD_DEVICE_START 0x000100E5 /* Payload of the #AFE_PORT_CMD_DEVICE_START.*/ @@ -3750,13 +3718,8 @@ u32 mem_map_handle; */ } __packed; -#define AFE_PORT_CMD_GET_PARAM_V2 0x000100F0 - -/* Payload of the #AFE_PORT_CMD_GET_PARAM_V2 command, - * which queries for one post/preprocessing parameter of a - * stream. - */ -struct afe_port_cmd_get_param_v2 { +/* Used by RTAC */ +struct afe_rtac_get_param_v2 { u16 port_id; /* Port interface and direction (Rx or Tx) to start. */ @@ -3802,6 +3765,37 @@ struct afe_port_cmd_get_param_v2 { */ } __packed; +#define AFE_PORT_CMD_GET_PARAM_V2 0x000100F0 + +/* Payload of the #AFE_PORT_CMD_GET_PARAM_V2 command, + * which queries for one post/preprocessing parameter of a + * stream. + */ +struct afe_port_cmd_get_param_v2 { + struct apr_hdr apr_hdr; + + /* Port interface and direction (Rx or Tx) to start. */ + u16 port_id; + + /* Maximum data size of the parameter ID/module ID combination. + * This is a multiple of four bytes + * Supported values: > 0 + */ + u16 payload_size; + + /* The memory mapping header to be used when requesting outband */ + struct mem_mapping_hdr mem_hdr; + + /* The module ID of the parameter data requested */ + u32 module_id; + + /* The parameter ID of the parameter data requested */ + u32 param_id; + + /* The header information for the parameter data */ + struct param_hdr_v1 param_hdr; +} __packed; + #define AFE_PORT_CMDRSP_GET_PARAM_V2 0x00010106 /* Payload of the #AFE_PORT_CMDRSP_GET_PARAM_V2 message, which @@ -3817,6 +3811,41 @@ struct afe_port_cmd_get_param_v2 { struct afe_port_cmdrsp_get_param_v2 { u32 status; + struct param_hdr_v1 param_hdr; + u8 param_data[0]; +} __packed; + +#define AFE_PORT_CMD_GET_PARAM_V3 0x000100FB +struct afe_port_cmd_get_param_v3 { + /* APR Header */ + struct apr_hdr apr_hdr; + + /* Port ID of the AFE port to configure. Port interface and direction + * (Rx or Tx) to configure. An even number represents the Rx direction, + * and an odd number represents the Tx direction. + */ + u16 port_id; + + /* Reserved. This field must be set to zero. */ + u16 reserved; + + /* The memory mapping header to be used when requesting outband */ + struct mem_mapping_hdr mem_hdr; + + /* The header information for the parameter data */ + struct param_hdr_v3 param_hdr; +} __packed; + +#define AFE_PORT_CMDRSP_GET_PARAM_V3 0x00010108 +struct afe_port_cmdrsp_get_param_v3 { + /* The status of the command */ + uint32_t status; + + /* The header information for the parameter data */ + struct param_hdr_v3 param_hdr; + + /* The parameter data to be filled when sent inband */ + u8 param_data[0]; } __packed; #define AFE_PARAM_ID_LPASS_CORE_SHARED_CLOCK_CONFIG 0x0001028C @@ -3838,13 +3867,6 @@ struct afe_param_id_lpass_core_shared_clk_cfg { */ } __packed; -struct afe_lpass_core_shared_clk_config_command { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; - struct afe_param_id_lpass_core_shared_clk_cfg clk_cfg; -} __packed; - /* adsp_afe_service_commands.h */ #define ADSP_MEMORY_MAP_EBI_POOL 0 @@ -6484,59 +6506,33 @@ struct asm_stream_cmd_open_transcode_loopback_t { #define ASM_STREAM_CMD_FLUSH_READBUFS 0x00010C09 #define ASM_STREAM_CMD_SET_PP_PARAMS_V2 0x00010DA1 +#define ASM_STREAM_CMD_SET_PP_PARAMS_V3 0x0001320D -struct asm_stream_cmd_set_pp_params_v2 { - u32 data_payload_addr_lsw; -/* LSW of parameter data payload address. Supported values: any. */ - u32 data_payload_addr_msw; -/* MSW of Parameter data payload address. Supported values: any. - * - Must be set to zero for in-band data. - * - In the case of 32 bit Shared memory address, msw field must be - * - set to zero. - * - In the case of 36 bit shared memory address, bit 31 to bit 4 of - * msw - * - * - must be set to zero. +/* + * Structure for the ASM Stream Set PP Params command. Parameter data must be + * pre-packed with the correct header for either V2 or V3 when sent in-band. + * Use q6core_pack_pp_params to pack the header and data correctly depending on + * Instance ID support. */ - u32 mem_map_handle; -/* Supported Values: Any. -* memory map handle returned by DSP through -* ASM_CMD_SHARED_MEM_MAP_REGIONS -* command. -* if mmhandle is NULL, the ParamData payloads are within the -* message payload (in-band). -* If mmhandle is non-NULL, the ParamData payloads begin at the -* address specified in the address msw and lsw (out-of-band). -*/ +struct asm_stream_cmd_set_pp_params { + /* APR Header */ + struct apr_hdr apr_hdr; - u32 data_payload_size; -/* Size in bytes of the variable payload accompanying the -message, or in shared memory. This field is used for parsing the -parameter payload. */ + /* The memory mapping header to be used when sending out of band */ + struct mem_mapping_hdr mem_hdr; -} __packed; - - -struct asm_stream_param_data_v2 { - u32 module_id; - /* Unique module ID. */ - - u32 param_id; - /* Unique parameter ID. */ - - u16 param_size; -/* Data size of the param_id/module_id combination. This is - * a multiple of 4 bytes. - */ - - u16 reserved; -/* Reserved for future enhancements. This field must be set to - * zero. - */ + /* The total size of the payload, including the parameter header */ + u32 payload_size; + /* The parameter data to be filled when sent inband. Parameter data + * must be pre-packed with parameter header and then copied here. Use + * q6core_pack_pp_params to pack the header and param data correctly. + */ + u32 param_data[0]; } __packed; #define ASM_STREAM_CMD_GET_PP_PARAMS_V2 0x00010DA2 +#define ASM_STREAM_CMD_GET_PP_PARAMS_V3 0x0001320E struct asm_stream_cmd_get_pp_params_v2 { u32 data_payload_addr_lsw; @@ -6715,6 +6711,7 @@ struct asm_aac_dual_mono_mapping_param { } __packed; #define ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2 0x00010DA4 +#define ASM_STREAM_CMDRSP_GET_PP_PARAMS_V3 0x0001320F struct asm_stream_cmdrsp_get_pp_params_v2 { u32 status; @@ -7490,12 +7487,6 @@ struct admx_mic_gain { /*< Clients must set this field to zero. */ } __packed; -struct adm_set_mic_gain_params { - struct adm_cmd_set_pp_params_v5 params; - struct adm_param_data_v5 data; - struct admx_mic_gain mic_gain_data; -} __packed; - /* end_addtogroup audio_pp_param_ids */ /* @ingroup audio_pp_module_ids @@ -7851,56 +7842,23 @@ struct adm_qensemble_param_set_new_angle { #define ADM_CMD_GET_PP_TOPO_MODULE_LIST 0x00010349 #define ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST 0x00010350 +#define ADM_CMD_GET_PP_TOPO_MODULE_LIST_V2 0x00010360 +#define ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST_V2 0x00010361 #define AUDPROC_PARAM_ID_ENABLE 0x00010904 - /* - * Payload of the ADM_CMD_GET_PP_TOPO_MODULE_LIST command. - */ -struct adm_cmd_get_pp_topo_module_list_t { - struct apr_hdr hdr; - /* Lower 32 bits of the 64-bit parameter data payload address. */ - uint32_t data_payload_addr_lsw; - /* - * Upper 32 bits of the 64-bit parameter data payload address. - * - * - * The size of the shared memory, if specified, must be large enough to - * contain the entire parameter data payload, including the module ID, - * parameter ID, parameter size, and parameter values. - */ - uint32_t data_payload_addr_msw; - /* - * Unique identifier for an address. - * - * This memory map handle is returned by the aDSP through the - * #ADM_CMD_SHARED_MEM_MAP_REGIONS command. - * - * @values - * - Non-NULL -- On acknowledgment, the parameter data payloads begin at - * the address specified (out-of-band) - * - NULL -- The acknowledgment's payload contains the parameter data - * (in-band) @tablebulletend - */ - uint32_t mem_map_handle; +/* + * Payload of the ADM_CMD_GET_PP_TOPO_MODULE_LIST command. + */ +struct adm_cmd_get_pp_topo_module_list { + struct apr_hdr apr_hdr; + + /* The memory mapping header to be used when requesting out of band */ + struct mem_mapping_hdr mem_hdr; + /* * Maximum data size of the list of modules. This * field is a multiple of 4 bytes. */ - uint16_t param_max_size; - /* This field must be set to zero. */ - uint16_t reserved; -} __packed; - -/* - * Payload of the ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST message, which returns - * module ids in response to an ADM_CMD_GET_PP_TOPO_MODULE_LIST command. - * Immediately following this structure is the acknowledgement <b>module id - * data variable payload</b> containing the pre/postprocessing module id - * values. For an in-band scenario, the variable payload depends on the size - * of the parameter. - */ -struct adm_cmd_rsp_get_pp_topo_module_list_t { - /* Status message (error code). */ - uint32_t status; + uint32_t param_max_size; } __packed; struct audproc_topology_module_id_info_t { @@ -7993,9 +7951,6 @@ struct audproc_topology_module_id_info_t { struct asm_volume_ctrl_master_gain { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; uint16_t master_gain; /*< Linear gain in Q13 format. */ @@ -8006,10 +7961,6 @@ struct asm_volume_ctrl_master_gain { struct asm_volume_ctrl_lr_chan_gain { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; - uint16_t l_chan_gain; /*< Linear gain in Q13 format for the left channel. */ @@ -8021,6 +7972,7 @@ struct audproc_chmixer_param_coeff { uint32_t index; uint16_t num_output_channels; uint16_t num_input_channels; + uint32_t payload[0]; } __packed; @@ -8049,6 +8001,7 @@ struct audproc_volume_ctrl_channel_type_gain_pair { /* Payload of the AUDPROC_PARAM_ID_MULTICHANNEL_MUTE parameters used by * the Volume Control module. */ +#define ASM_MAX_CHANNELS 8 struct audproc_volume_ctrl_multichannel_gain { uint32_t num_channels; /* Number of channels for which mute configuration is provided. Any @@ -8056,7 +8009,8 @@ struct audproc_volume_ctrl_multichannel_gain { * provided are set to unmute. */ - struct audproc_volume_ctrl_channel_type_gain_pair *gain_data; + struct audproc_volume_ctrl_channel_type_gain_pair + gain_data[ASM_MAX_CHANNELS]; /* Array of channel type/mute setting pairs. */ } __packed; @@ -8070,9 +8024,6 @@ struct audproc_volume_ctrl_multichannel_gain { struct asm_volume_ctrl_mute_config { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; uint32_t mute_flag; /*< Specifies whether mute is disabled (0) or enabled (nonzero).*/ @@ -8100,9 +8051,6 @@ struct asm_volume_ctrl_mute_config { * parameters used by the Volume Control module. */ struct asm_soft_step_volume_params { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; uint32_t period; /*< Period in milliseconds. * Supported values: 0 to 15000 @@ -8132,9 +8080,6 @@ struct asm_soft_step_volume_params { struct asm_soft_pause_params { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; uint32_t enable_flag; /*< Specifies whether soft pause is disabled (0) or enabled * (nonzero). @@ -8224,10 +8169,7 @@ struct asm_volume_ctrl_channeltype_gain_pair { struct asm_volume_ctrl_multichannel_gain { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; - uint32_t num_channels; + uint32_t num_channels; /* * Number of channels for which gain values are provided. Any * channels present in the data for which gain is not provided are @@ -8252,9 +8194,6 @@ struct asm_volume_ctrl_multichannel_gain { struct asm_volume_ctrl_channelype_mute_pair { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; uint8_t channelype; /*< Channel type for which the mute setting is to be applied. * Supported values: @@ -8303,9 +8242,6 @@ struct asm_volume_ctrl_channelype_mute_pair { struct asm_volume_ctrl_multichannel_mute { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; uint32_t num_channels; /*< Number of channels for which mute configuration is * provided. Any channels present in the data for which mute @@ -8750,9 +8686,6 @@ struct asm_eq_per_band_params { } __packed; struct asm_eq_params { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; uint32_t enable_flag; /*< Specifies whether the equalizer module is disabled (0) or enabled * (nonzero). @@ -8791,6 +8724,9 @@ struct asm_eq_params { #define VSS_ICOMMON_CMD_SET_PARAM_V2 0x0001133D #define VSS_ICOMMON_CMD_GET_PARAM_V2 0x0001133E #define VSS_ICOMMON_RSP_GET_PARAM 0x00011008 +#define VSS_ICOMMON_CMD_SET_PARAM_V3 0x00013245 +#define VSS_ICOMMON_CMD_GET_PARAM_V3 0x00013246 +#define VSS_ICOMMON_RSP_GET_PARAM_V3 0x00013247 /** ID of the Bass Boost module. This module supports the following parameter IDs: @@ -9174,15 +9110,13 @@ struct afe_sp_th_vi_ftm_params { } __packed; struct afe_sp_th_vi_get_param { - struct apr_hdr hdr; - struct afe_port_cmd_get_param_v2 get_param; - struct afe_port_param_data_v2 pdata; + struct param_hdr_v3 pdata; struct afe_sp_th_vi_ftm_params param; } __packed; struct afe_sp_th_vi_get_param_resp { uint32_t status; - struct afe_port_param_data_v2 pdata; + struct param_hdr_v3 pdata; struct afe_sp_th_vi_ftm_params param; } __packed; @@ -9248,15 +9182,13 @@ struct afe_sp_ex_vi_ftm_params { } __packed; struct afe_sp_ex_vi_get_param { - struct apr_hdr hdr; - struct afe_port_cmd_get_param_v2 get_param; - struct afe_port_param_data_v2 pdata; + struct param_hdr_v3 pdata; struct afe_sp_ex_vi_ftm_params param; } __packed; struct afe_sp_ex_vi_get_param_resp { uint32_t status; - struct afe_port_param_data_v2 pdata; + struct param_hdr_v3 pdata; struct afe_sp_ex_vi_ftm_params param; } __packed; @@ -9271,23 +9203,16 @@ union afe_spkr_prot_config { struct afe_sp_ex_vi_ftm_cfg ex_vi_ftm_cfg; } __packed; -struct afe_spkr_prot_config_command { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; - union afe_spkr_prot_config prot_config; -} __packed; - struct afe_spkr_prot_get_vi_calib { struct apr_hdr hdr; - struct afe_port_cmd_get_param_v2 get_param; - struct afe_port_param_data_v2 pdata; + struct mem_mapping_hdr mem_hdr; + struct param_hdr_v3 pdata; struct asm_calib_res_cfg res_cfg; } __packed; struct afe_spkr_prot_calib_get_resp { uint32_t status; - struct afe_port_param_data_v2 pdata; + struct param_hdr_v3 pdata; struct asm_calib_res_cfg res_cfg; } __packed; @@ -9415,16 +9340,6 @@ struct srs_trumedia_params { #define ASM_STREAM_POSTPROC_TOPO_ID_DTS_HPX 0x00010DED #define ASM_STREAM_POSTPROC_TOPO_ID_HPX_PLUS 0x10015000 #define ASM_STREAM_POSTPROC_TOPO_ID_HPX_MASTER 0x10015001 -struct asm_dts_eagle_param { - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 param; - struct asm_stream_param_data_v2 data; -} __packed; - -struct asm_dts_eagle_param_get { - struct apr_hdr hdr; - struct asm_stream_cmd_get_pp_params_v2 param; -} __packed; /* Opcode to set BT address and license for aptx decoder */ #define APTX_DECODER_BT_ADDRESS 0x00013201 @@ -9532,6 +9447,7 @@ struct avcs_fwk_ver_info { #define LSM_SESSION_CMD_CLOSE_TX (0x00012A88) #define LSM_SESSION_CMD_SET_PARAMS (0x00012A83) #define LSM_SESSION_CMD_SET_PARAMS_V2 (0x00012A8F) +#define LSM_SESSION_CMD_SET_PARAMS_V3 (0x00012A92) #define LSM_SESSION_CMD_REGISTER_SOUND_MODEL (0x00012A84) #define LSM_SESSION_CMD_DEREGISTER_SOUND_MODEL (0x00012A85) #define LSM_SESSION_CMD_START (0x00012A86) @@ -9578,6 +9494,7 @@ struct avcs_fwk_ver_info { /* Commands/Params to pass the codec/slimbus data to DSP */ #define AFE_SVC_CMD_SET_PARAM (0x000100f3) +#define AFE_SVC_CMD_SET_PARAM_V2 (0x000100fc) #define AFE_MODULE_CDC_DEV_CFG (0x00010234) #define AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG (0x00010235) #define AFE_PARAM_ID_CDC_REG_CFG (0x00010236) @@ -9962,13 +9879,6 @@ struct afe_clk_cfg { #define AFE_MODULE_CLOCK_SET 0x0001028F #define AFE_PARAM_ID_CLOCK_SET 0x00010290 -struct afe_lpass_clk_config_command { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; - struct afe_clk_cfg clk_cfg; -} __packed; - enum afe_lpass_digital_clk_src { Q6AFE_LPASS_DIGITAL_ROOT_INVALID, Q6AFE_LPASS_DIGITAL_ROOT_PRI_MI2S_OSR, @@ -10004,14 +9914,6 @@ struct afe_digital_clk_cfg { u16 reserved; } __packed; - -struct afe_lpass_digital_clk_config_command { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; - struct afe_digital_clk_cfg clk_cfg; -} __packed; - /* * Opcode for AFE to start DTMF. */ @@ -10120,107 +10022,43 @@ struct afe_param_cdc_reg_cfg_data { struct afe_param_cdc_reg_cfg *reg_data; } __packed; -struct afe_svc_cmd_set_param { - uint32_t payload_size; - uint32_t payload_address_lsw; - uint32_t payload_address_msw; - uint32_t mem_map_handle; -} __packed; - -struct afe_svc_param_data { - uint32_t module_id; - uint32_t param_id; - uint16_t param_size; - uint16_t reserved; -} __packed; +struct afe_svc_cmd_set_param_v1 { + /* APR Header */ + struct apr_hdr apr_hdr; -struct afe_param_hw_mad_ctrl { - uint32_t minor_version; - uint16_t mad_type; - uint16_t mad_enable; -} __packed; - -struct afe_cmd_hw_mad_ctrl { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; - struct afe_param_hw_mad_ctrl payload; -} __packed; - -struct afe_cmd_hw_mad_slimbus_slave_port_cfg { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; - struct afe_param_slimbus_slave_port_cfg sb_port_cfg; -} __packed; - -struct afe_cmd_sw_mad_enable { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; -} __packed; - -struct afe_param_cdc_reg_cfg_payload { - struct afe_svc_param_data common; - struct afe_param_cdc_reg_cfg reg_cfg; -} __packed; + /* The total size of the payload, including param_hdr_v3 */ + uint32_t payload_size; -struct afe_lpass_clk_config_command_v2 { - struct apr_hdr hdr; - struct afe_svc_cmd_set_param param; - struct afe_svc_param_data pdata; - struct afe_clk_set clk_cfg; -} __packed; + /* The memory mapping header to be used when sending outband */ + struct mem_mapping_hdr mem_hdr; -/* - * reg_data's size can be up to AFE_MAX_CDC_REGISTERS_TO_CONFIG - */ -struct afe_svc_cmd_cdc_reg_cfg { - struct apr_hdr hdr; - struct afe_svc_cmd_set_param param; - struct afe_param_cdc_reg_cfg_payload reg_data[0]; + /* The parameter data to be filled when sent inband */ + u32 param_data[0]; } __packed; -struct afe_svc_cmd_init_cdc_reg_cfg { - struct apr_hdr hdr; - struct afe_svc_cmd_set_param param; - struct afe_port_param_data_v2 init; -} __packed; +struct afe_svc_cmd_set_param_v2 { + /* APR Header */ + struct apr_hdr apr_hdr; -struct afe_svc_cmd_sb_slave_cfg { - struct apr_hdr hdr; - struct afe_svc_cmd_set_param param; - struct afe_port_param_data_v2 pdata; - struct afe_param_cdc_slimbus_slave_cfg sb_slave_cfg; -} __packed; + /* The memory mapping header to be used when sending outband */ + struct mem_mapping_hdr mem_hdr; -struct afe_svc_cmd_cdc_reg_page_cfg { - struct apr_hdr hdr; - struct afe_svc_cmd_set_param param; - struct afe_port_param_data_v2 pdata; - struct afe_param_cdc_reg_page_cfg cdc_reg_page_cfg; -} __packed; + /* The total size of the payload, including param_hdr_v3 */ + u32 payload_size; -struct afe_svc_cmd_cdc_aanc_version { - struct apr_hdr hdr; - struct afe_svc_cmd_set_param param; - struct afe_port_param_data_v2 pdata; - struct afe_param_id_cdc_aanc_version version; + /* The parameter data to be filled when sent inband */ + u32 param_data[0]; } __packed; -struct afe_port_cmd_set_aanc_param { - struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; - struct afe_port_param_data_v2 pdata; - union { - struct afe_param_aanc_port_cfg aanc_port_cfg; - struct afe_mod_enable_param mod_enable; - } __packed data; +struct afe_param_hw_mad_ctrl { + uint32_t minor_version; + uint16_t mad_type; + uint16_t mad_enable; } __packed; struct afe_port_cmd_set_aanc_acdb_table { struct apr_hdr hdr; - struct afe_port_cmd_set_param_v2 param; + struct mem_mapping_hdr mem_hdr; } __packed; /* Dolby DAP topology */ @@ -10243,13 +10081,6 @@ struct afe_port_cmd_set_aanc_acdb_table { #define Q14_GAIN_ZERO_POINT_FIVE 0x2000 #define Q14_GAIN_UNITY 0x4000 -struct afe_svc_cmd_set_clip_bank_selection { - struct apr_hdr hdr; - struct afe_svc_cmd_set_param param; - struct afe_port_param_data_v2 pdata; - struct afe_param_id_clip_bank_sel bank_sel; -} __packed; - /* Ultrasound supported formats */ #define US_POINT_EPOS_FORMAT_V2 0x0001272D #define US_RAW_FORMAT_V2 0x0001272C @@ -10463,13 +10294,6 @@ union afe_port_group_config { struct afe_param_id_group_device_tdm_cfg tdm_cfg; } __packed; -struct afe_port_group_create { - struct apr_hdr hdr; - struct afe_svc_cmd_set_param param; - struct afe_port_param_data_v2 pdata; - union afe_port_group_config data; -} __packed; - /* ID of the parameter used by #AFE_MODULE_AUDIO_DEV_INTERFACE to specify * the timing statistics of the corresponding device interface. * Client can periodically query for the device time statistics to help adjust @@ -10559,16 +10383,9 @@ struct afe_param_id_dev_timing_stats { u32 ref_timer_abs_ts_msw; } __packed; -struct afe_av_dev_drift_get_param { - struct apr_hdr hdr; - struct afe_port_cmd_get_param_v2 get_param; - struct afe_port_param_data_v2 pdata; - struct afe_param_id_dev_timing_stats timing_stats; -} __packed; - struct afe_av_dev_drift_get_param_resp { uint32_t status; - struct afe_port_param_data_v2 pdata; + struct param_hdr_v3 pdata; struct afe_param_id_dev_timing_stats timing_stats; } __packed; @@ -10780,7 +10597,7 @@ union asm_session_mtmx_strtr_param_config { struct asm_mtmx_strtr_params { struct apr_hdr hdr; struct asm_session_cmd_set_mtmx_strstr_params_v2 param; - struct asm_stream_param_data_v2 data; + struct param_hdr_v1 data; union asm_session_mtmx_strtr_param_config config; } __packed; @@ -10890,7 +10707,7 @@ struct asm_mtmx_strtr_get_params { struct asm_mtmx_strtr_get_params_cmdrsp { uint32_t err_code; - struct asm_stream_param_data_v2 param_info; + struct param_hdr_v1 param_info; union asm_session_mtmx_strtr_data_type param_data; } __packed; @@ -10910,18 +10727,14 @@ enum { #define AUDPROC_PARAM_ID_COMPRESSED_MUTE 0x00010771 struct adm_set_compressed_device_mute { - struct adm_cmd_set_pp_params_v5 command; - struct adm_param_data_v5 params; - u32 mute_on; + u32 mute_on; } __packed; #define AUDPROC_MODULE_ID_COMPRESSED_LATENCY 0x0001076E #define AUDPROC_PARAM_ID_COMPRESSED_LATENCY 0x0001076F struct adm_set_compressed_device_latency { - struct adm_cmd_set_pp_params_v5 command; - struct adm_param_data_v5 params; - u32 latency; + u32 latency; } __packed; #define VOICEPROC_MODULE_ID_GENERIC_TX 0x00010EF6 @@ -10951,12 +10764,6 @@ struct adm_param_fluence_soundfocus_t { uint16_t reserved; } __packed; -struct adm_set_fluence_soundfocus_param { - struct adm_cmd_set_pp_params_v5 params; - struct adm_param_data_v5 data; - struct adm_param_fluence_soundfocus_t soundfocus_data; -} __packed; - struct adm_param_fluence_sourcetracking_t { uint8_t vad[MAX_SECTORS]; uint16_t doa_speech; @@ -10986,10 +10793,4 @@ struct admx_sec_primary_mic_ch { uint16_t reserved1; } __packed; - -struct adm_set_sec_primary_ch_params { - struct adm_cmd_set_pp_params_v5 params; - struct adm_param_data_v5 data; - struct admx_sec_primary_mic_ch sec_primary_mic_ch_data; -} __packed; #endif /*_APR_AUDIO_V2_H_ */ diff --git a/include/sound/q6adm-v2.h b/include/sound/q6adm-v2.h index 65c42ee18914..84087de3d4d8 100644 --- a/include/sound/q6adm-v2.h +++ b/include/sound/q6adm-v2.h @@ -25,6 +25,8 @@ #define MAX_MODULES_IN_TOPO 16 #define ADM_GET_TOPO_MODULE_LIST_LENGTH\ ((MAX_MODULES_IN_TOPO + 1) * sizeof(uint32_t)) +#define ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH \ + ((MAX_MODULES_IN_TOPO + 1) * 2 * sizeof(uint32_t)) #define AUD_PROC_BLOCK_SIZE 4096 #define AUD_VOL_BLOCK_SIZE 4096 #define AUDIO_RX_CALIBRATION_SIZE (AUD_PROC_BLOCK_SIZE + \ @@ -101,12 +103,24 @@ void adm_copp_mfc_cfg(int port_id, int copp_idx, int dst_sample_rate); int adm_get_params(int port_id, int copp_idx, uint32_t module_id, uint32_t param_id, uint32_t params_length, char *params); +int adm_get_pp_params(int port_id, int copp_idx, uint32_t client_id, + struct mem_mapping_hdr *mem_hdr, + struct param_hdr_v3 *param_hdr, u8 *returned_param_data); + int adm_send_params_v5(int port_id, int copp_idx, char *params, uint32_t params_length); int adm_dolby_dap_send_params(int port_id, int copp_idx, char *params, uint32_t params_length); +int adm_set_pp_params(int port_id, int copp_idx, + struct mem_mapping_hdr *mem_hdr, u8 *param_data, + u32 params_size); + +int adm_pack_and_set_one_pp_param(int port_id, int copp_idx, + struct param_hdr_v3 param_hdr, + u8 *param_data); + int adm_open(int port, int path, int rate, int mode, int topology, int perf_mode, uint16_t bits_per_sample, int app_type, int acdbdev_id); @@ -157,6 +171,10 @@ int adm_set_downmix_params(int port_id, int copp_idx, int adm_get_pp_topo_module_list(int port_id, int copp_idx, int32_t param_length, char *params); +int adm_get_pp_topo_module_list_v2(int port_id, int copp_idx, + int32_t param_length, + int32_t *returned_params); + int adm_set_volume(int port_id, int copp_idx, int volume); int adm_set_softvolume(int port_id, int copp_idx, @@ -169,6 +187,9 @@ int adm_send_set_multichannel_ec_primary_mic_ch(int port_id, int copp_idx, int adm_param_enable(int port_id, int copp_idx, int module_id, int enable); +int adm_param_enable_v2(int port_id, int copp_idx, + struct module_instance_info mod_inst_info, int enable); + int adm_send_calibration(int port_id, int copp_idx, int path, int perf_mode, int cal_type, char *params, int size); diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h index 9ddd02cac9ac..285d32e249b8 100644 --- a/include/sound/q6asm-v2.h +++ b/include/sound/q6asm-v2.h @@ -265,6 +265,17 @@ int q6asm_audio_client_buf_alloc_contiguous(unsigned int dir int q6asm_audio_client_buf_free_contiguous(unsigned int dir, struct audio_client *ac); +int q6asm_set_pp_params(struct audio_client *ac, + struct mem_mapping_hdr *mem_hdr, u8 *param_data, + u32 param_size); + +int q6asm_pack_and_set_pp_param_in_band(struct audio_client *ac, + struct param_hdr_v3 param_hdr, + u8 *param_data); + +int q6asm_set_soft_volume_module_instance_ids(int instance, + struct param_hdr_v3 *param_hdr); + int q6asm_open_read(struct audio_client *ac, uint32_t format /*, uint16_t bits_per_sample*/); diff --git a/include/sound/q6lsm.h b/include/sound/q6lsm.h index 4805246766d6..c046cd468b49 100644 --- a/include/sound/q6lsm.h +++ b/include/sound/q6lsm.h @@ -112,31 +112,27 @@ struct lsm_custom_topologies { uint32_t buffer_size; } __packed; -struct lsm_param_size_reserved { - uint16_t param_size; - uint16_t reserved; -} __packed; - -union lsm_param_size { - uint32_t param_size; - struct lsm_param_size_reserved sr; +struct lsm_session_cmd_set_params_v2 { + struct apr_hdr apr_hdr; + uint32_t payload_size; + struct mem_mapping_hdr mem_hdr; + u32 param_data[0]; } __packed; -struct lsm_param_payload_common { - uint32_t module_id; - uint32_t param_id; - union lsm_param_size p_size; +struct lsm_session_cmd_set_params_v3 { + struct apr_hdr apr_hdr; + struct mem_mapping_hdr mem_hdr; + uint32_t payload_size; + u32 param_data[0]; } __packed; struct lsm_param_op_mode { - struct lsm_param_payload_common common; uint32_t minor_version; uint16_t mode; uint16_t reserved; } __packed; struct lsm_param_connect_to_port { - struct lsm_param_payload_common common; uint32_t minor_version; /* AFE port id that receives voice wake up data */ uint16_t port_id; @@ -144,20 +140,17 @@ struct lsm_param_connect_to_port { } __packed; struct lsm_param_poll_enable { - struct lsm_param_payload_common common; uint32_t minor_version; /* indicates to voice wakeup that HW MAD/SW polling is enabled or not */ uint32_t polling_enable; } __packed; struct lsm_param_fwk_mode_cfg { - struct lsm_param_payload_common common; uint32_t minor_version; uint32_t mode; } __packed; struct lsm_param_media_fmt { - struct lsm_param_payload_common common; uint32_t minor_version; uint32_t sample_rate; uint16_t num_channels; @@ -165,78 +158,23 @@ struct lsm_param_media_fmt { uint8_t channel_mapping[LSM_MAX_NUM_CHANNELS]; } __packed; -/* - * This param cannot be sent in this format. - * The actual number of confidence level values - * need to appended to this param payload. - */ -struct lsm_param_min_confidence_levels { - struct lsm_param_payload_common common; - uint8_t num_confidence_levels; -} __packed; - -struct lsm_set_params_hdr { - uint32_t data_payload_size; - uint32_t data_payload_addr_lsw; - uint32_t data_payload_addr_msw; - uint32_t mem_map_handle; -} __packed; - -struct lsm_cmd_set_params { - struct apr_hdr msg_hdr; - struct lsm_set_params_hdr param_hdr; -} __packed; - -struct lsm_cmd_set_params_conf { - struct apr_hdr msg_hdr; - struct lsm_set_params_hdr params_hdr; - struct lsm_param_min_confidence_levels conf_payload; -} __packed; - -struct lsm_cmd_set_params_opmode { - struct apr_hdr msg_hdr; - struct lsm_set_params_hdr params_hdr; - struct lsm_param_op_mode op_mode; -} __packed; - -struct lsm_cmd_set_connectport { - struct apr_hdr msg_hdr; - struct lsm_set_params_hdr params_hdr; - struct lsm_param_connect_to_port connect_to_port; -} __packed; - -struct lsm_cmd_poll_enable { - struct apr_hdr msg_hdr; - struct lsm_set_params_hdr params_hdr; - struct lsm_param_poll_enable poll_enable; +struct lsm_param_confidence_levels { + uint8_t num_confidence_levels; + uint8_t confidence_levels[0]; } __packed; struct lsm_param_epd_thres { - struct lsm_param_payload_common common; uint32_t minor_version; uint32_t epd_begin; uint32_t epd_end; } __packed; -struct lsm_cmd_set_epd_threshold { - struct apr_hdr msg_hdr; - struct lsm_set_params_hdr param_hdr; - struct lsm_param_epd_thres epd_thres; -} __packed; - struct lsm_param_gain { - struct lsm_param_payload_common common; uint32_t minor_version; uint16_t gain; uint16_t reserved; } __packed; -struct lsm_cmd_set_gain { - struct apr_hdr msg_hdr; - struct lsm_set_params_hdr param_hdr; - struct lsm_param_gain lsm_gain; -} __packed; - struct lsm_cmd_reg_snd_model { struct apr_hdr hdr; uint32_t model_size; @@ -245,31 +183,16 @@ struct lsm_cmd_reg_snd_model { uint32_t mem_map_handle; } __packed; -struct lsm_lab_enable { - struct lsm_param_payload_common common; +struct lsm_param_lab_enable { uint16_t enable; uint16_t reserved; } __packed; -struct lsm_params_lab_enable { - struct apr_hdr msg_hdr; - struct lsm_set_params_hdr params_hdr; - struct lsm_lab_enable lab_enable; -} __packed; - -struct lsm_lab_config { - struct lsm_param_payload_common common; +struct lsm_param_lab_config { uint32_t minor_version; uint32_t wake_up_latency_ms; } __packed; - -struct lsm_params_lab_config { - struct apr_hdr msg_hdr; - struct lsm_set_params_hdr params_hdr; - struct lsm_lab_config lab_config; -} __packed; - struct lsm_cmd_read { struct apr_hdr hdr; uint32_t buf_addr_lsw; @@ -291,19 +214,6 @@ struct lsm_cmd_read_done { uint32_t flags; } __packed; -struct lsm_cmd_set_fwk_mode_cfg { - struct apr_hdr msg_hdr; - struct lsm_set_params_hdr params_hdr; - struct lsm_param_fwk_mode_cfg fwk_mode_cfg; -} __packed; - -struct lsm_cmd_set_media_fmt { - struct apr_hdr msg_hdr; - struct lsm_set_params_hdr params_hdr; - struct lsm_param_media_fmt media_fmt; -} __packed; - - struct lsm_client *q6lsm_client_alloc(lsm_app_cb cb, void *priv); void q6lsm_client_free(struct lsm_client *client); int q6lsm_open(struct lsm_client *client, uint16_t app_id); diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h index 739bcb89f602..cc0ebe6867a5 100644 --- a/include/trace/events/sched.h +++ b/include/trace/events/sched.h @@ -436,9 +436,9 @@ TRACE_EVENT(sched_update_task_ravg, TRACE_EVENT(sched_get_task_cpu_cycles, - TP_PROTO(int cpu, int event, u64 cycles, u64 exec_time), + TP_PROTO(int cpu, int event, u64 cycles, u64 exec_time, struct task_struct *p), - TP_ARGS(cpu, event, cycles, exec_time), + TP_ARGS(cpu, event, cycles, exec_time, p), TP_STRUCT__entry( __field(int, cpu ) @@ -448,6 +448,8 @@ TRACE_EVENT(sched_get_task_cpu_cycles, __field(u32, freq ) __field(u32, legacy_freq ) __field(u32, max_freq) + __field(pid_t, pid ) + __array(char, comm, TASK_COMM_LEN ) ), TP_fast_assign( @@ -458,12 +460,14 @@ TRACE_EVENT(sched_get_task_cpu_cycles, __entry->freq = cpu_cycles_to_freq(cycles, exec_time); __entry->legacy_freq = cpu_cur_freq(cpu); __entry->max_freq = cpu_max_freq(cpu); + __entry->pid = p->pid; + memcpy(__entry->comm, p->comm, TASK_COMM_LEN); ), - TP_printk("cpu=%d event=%d cycles=%llu exec_time=%llu freq=%u legacy_freq=%u max_freq=%u", + TP_printk("cpu=%d event=%d cycles=%llu exec_time=%llu freq=%u legacy_freq=%u max_freq=%u task=%d (%s)", __entry->cpu, __entry->event, __entry->cycles, __entry->exec_time, __entry->freq, __entry->legacy_freq, - __entry->max_freq) + __entry->max_freq, __entry->pid, __entry->comm) ); TRACE_EVENT(sched_update_history, diff --git a/include/uapi/linux/habmm.h b/include/uapi/linux/habmm.h index 902bd35ee474..59b603a0fcf7 100644 --- a/include/uapi/linux/habmm.h +++ b/include/uapi/linux/habmm.h @@ -73,8 +73,9 @@ struct hab_unimport { #define MM_AUD_END 105 #define MM_CAM_START 200 -#define MM_CAM 201 -#define MM_CAM_END 202 +#define MM_CAM_1 201 +#define MM_CAM_2 202 +#define MM_CAM_END 203 #define MM_DISP_START 300 #define MM_DISP_1 301 @@ -102,7 +103,13 @@ struct hab_unimport { #define MM_QCPE_VM3 703 #define MM_QCPE_VM4 704 #define MM_QCPE_END 705 -#define MM_ID_MAX 706 + +#define MM_CLK_START 800 +#define MM_CLK_VM1 801 +#define MM_CLK_VM2 802 +#define MM_CLK_END 803 + +#define MM_ID_MAX 804 #define HABMM_SOCKET_OPEN_FLAGS_SINGLE_BE_SINGLE_FE 0x00000000 #define HABMM_SOCKET_OPEN_FLAGS_SINGLE_BE_SINGLE_DOMU 0x00000001 @@ -110,6 +117,14 @@ struct hab_unimport { #define HABMM_SOCKET_SEND_FLAGS_NON_BLOCKING 0x00000001 +/* + * Collect cross-VM stats: client provides stat-buffer large enough to allow 2 + * ets of a 2-uint64_t pair to collect seconds and nano-seconds at the + * beginning of the stat-buffer. Stats are collected when the stat-buffer leaves + * VM1, then enters VM2 + */ +#define HABMM_SOCKET_SEND_FLAGS_XING_VM_STAT 0x00000002 + #define HABMM_SOCKET_RECV_FLAGS_NON_BLOCKING 0x00000001 #define HABMM_EXP_MEM_TYPE_DMA 0x00000001 diff --git a/include/uapi/sound/audio_effects.h b/include/uapi/sound/audio_effects.h index 6565acff4073..147e877db71e 100644 --- a/include/uapi/sound/audio_effects.h +++ b/include/uapi/sound/audio_effects.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2015, 2017 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -159,8 +159,12 @@ #define PBE_ENABLE_PARAM_LEN 1 #define PBE_CONFIG_PARAM_LEN 28 +/* Command Payload length and size for Non-IID commands */ #define COMMAND_PAYLOAD_LEN 3 #define COMMAND_PAYLOAD_SZ (COMMAND_PAYLOAD_LEN * sizeof(uint32_t)) +/* Command Payload length and size for IID commands */ +#define COMMAND_IID_PAYLOAD_LEN 4 +#define COMMAND_IID_PAYLOAD_SZ (COMMAND_IID_PAYLOAD_LEN * sizeof(uint32_t)) #define MAX_INBAND_PARAM_SZ 4096 #define Q27_UNITY (1 << 27) #define Q8_UNITY (1 << 8) diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 1d91c012b5d8..13a64488c3d2 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -2325,11 +2325,11 @@ void sched_exit(struct task_struct *p) reset_task_stats(p); p->ravg.mark_start = wallclock; p->ravg.sum_history[0] = EXITING_TASK_MARKER; - free_task_load_ptrs(p); enqueue_task(rq, p, 0); clear_ed_task(p, rq); task_rq_unlock(rq, p, &flags); + free_task_load_ptrs(p); } #endif /* CONFIG_SCHED_HMP */ @@ -4914,6 +4914,15 @@ long sched_getaffinity(pid_t pid, struct cpumask *mask) raw_spin_lock_irqsave(&p->pi_lock, flags); cpumask_and(mask, &p->cpus_allowed, cpu_active_mask); + + /* + * The userspace tasks are forbidden to run on + * isolated CPUs. So exclude isolated CPUs from + * the getaffinity. + */ + if (!(p->flags & PF_KTHREAD)) + cpumask_andnot(mask, mask, cpu_isolated_mask); + raw_spin_unlock_irqrestore(&p->pi_lock, flags); out_unlock: diff --git a/kernel/sched/hmp.c b/kernel/sched/hmp.c index ae6876e62c0f..ea066ab8376b 100644 --- a/kernel/sched/hmp.c +++ b/kernel/sched/hmp.c @@ -1526,6 +1526,10 @@ unsigned int cpu_temp(int cpu) return 0; } +/* + * kfree() may wakeup kswapd. So this function should NOT be called + * with any CPU's rq->lock acquired. + */ void free_task_load_ptrs(struct task_struct *p) { kfree(p->ravg.curr_window_cpu); @@ -2608,7 +2612,8 @@ update_task_rq_cpu_cycles(struct task_struct *p, struct rq *rq, int event, p->cpu_cycles = cur_cycles; - trace_sched_get_task_cpu_cycles(cpu, event, rq->cc.cycles, rq->cc.time); + trace_sched_get_task_cpu_cycles(cpu, event, rq->cc.cycles, + rq->cc.time, p); } static int diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 7ff14b7f598e..7b31973c6db3 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h @@ -1247,7 +1247,7 @@ static inline int cpu_min_power_cost(int cpu) return cpu_rq(cpu)->cluster->min_power_cost; } -static inline u32 cpu_cycles_to_freq(u64 cycles, u32 period) +static inline u32 cpu_cycles_to_freq(u64 cycles, u64 period) { return div64_u64(cycles, period); } diff --git a/sound/core/timer.c b/sound/core/timer.c index f0675acecc93..0e51e5cd33fe 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -318,8 +318,6 @@ int snd_timer_open(struct snd_timer_instance **ti, return 0; } -static int _snd_timer_stop(struct snd_timer_instance *timeri, int event); - /* * close a timer instance */ @@ -408,7 +406,6 @@ unsigned long snd_timer_resolution(struct snd_timer_instance *timeri) static void snd_timer_notify1(struct snd_timer_instance *ti, int event) { struct snd_timer *timer; - unsigned long flags; unsigned long resolution = 0; struct snd_timer_instance *ts; struct timespec tstamp; @@ -432,34 +429,66 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event) return; if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE) return; - spin_lock_irqsave(&timer->lock, flags); list_for_each_entry(ts, &ti->slave_active_head, active_list) if (ts->ccallback) ts->ccallback(ts, event + 100, &tstamp, resolution); - spin_unlock_irqrestore(&timer->lock, flags); } -static int snd_timer_start1(struct snd_timer *timer, struct snd_timer_instance *timeri, - unsigned long sticks) +/* start/continue a master timer */ +static int snd_timer_start1(struct snd_timer_instance *timeri, + bool start, unsigned long ticks) { + struct snd_timer *timer; + int result; + unsigned long flags; + + timer = timeri->timer; + if (!timer) + return -EINVAL; + + spin_lock_irqsave(&timer->lock, flags); + if (timer->card && timer->card->shutdown) { + result = -ENODEV; + goto unlock; + } + if (timeri->flags & (SNDRV_TIMER_IFLG_RUNNING | + SNDRV_TIMER_IFLG_START)) { + result = -EBUSY; + goto unlock; + } + + if (start) + timeri->ticks = timeri->cticks = ticks; + else if (!timeri->cticks) + timeri->cticks = 1; + timeri->pticks = 0; + list_move_tail(&timeri->active_list, &timer->active_list_head); if (timer->running) { if (timer->hw.flags & SNDRV_TIMER_HW_SLAVE) goto __start_now; timer->flags |= SNDRV_TIMER_FLG_RESCHED; timeri->flags |= SNDRV_TIMER_IFLG_START; - return 1; /* delayed start */ + result = 1; /* delayed start */ } else { - timer->sticks = sticks; + if (start) + timer->sticks = ticks; timer->hw.start(timer); __start_now: timer->running++; timeri->flags |= SNDRV_TIMER_IFLG_RUNNING; - return 0; + result = 0; } + snd_timer_notify1(timeri, start ? SNDRV_TIMER_EVENT_START : + SNDRV_TIMER_EVENT_CONTINUE); + unlock: + spin_unlock_irqrestore(&timer->lock, flags); + return result; } -static int snd_timer_start_slave(struct snd_timer_instance *timeri) +/* start/continue a slave timer */ +static int snd_timer_start_slave(struct snd_timer_instance *timeri, + bool start) { unsigned long flags; @@ -473,88 +502,37 @@ static int snd_timer_start_slave(struct snd_timer_instance *timeri) spin_lock(&timeri->timer->lock); list_add_tail(&timeri->active_list, &timeri->master->slave_active_head); + snd_timer_notify1(timeri, start ? SNDRV_TIMER_EVENT_START : + SNDRV_TIMER_EVENT_CONTINUE); spin_unlock(&timeri->timer->lock); } spin_unlock_irqrestore(&slave_active_lock, flags); return 1; /* delayed start */ } -/* - * start the timer instance - */ -int snd_timer_start(struct snd_timer_instance *timeri, unsigned int ticks) +/* stop/pause a master timer */ +static int snd_timer_stop1(struct snd_timer_instance *timeri, bool stop) { struct snd_timer *timer; - int result = -EINVAL; + int result = 0; unsigned long flags; - if (timeri == NULL || ticks < 1) - return -EINVAL; - if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) { - result = snd_timer_start_slave(timeri); - if (result >= 0) - snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START); - return result; - } - timer = timeri->timer; - if (timer == NULL) - return -EINVAL; - if (timer->card && timer->card->shutdown) - return -ENODEV; - spin_lock_irqsave(&timer->lock, flags); - if (timeri->flags & (SNDRV_TIMER_IFLG_RUNNING | - SNDRV_TIMER_IFLG_START)) { - result = -EBUSY; - goto unlock; - } - timeri->ticks = timeri->cticks = ticks; - timeri->pticks = 0; - result = snd_timer_start1(timer, timeri, ticks); - unlock: - spin_unlock_irqrestore(&timer->lock, flags); - if (result >= 0) - snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_START); - return result; -} - -static int _snd_timer_stop(struct snd_timer_instance *timeri, int event) -{ - struct snd_timer *timer; - unsigned long flags; - - if (snd_BUG_ON(!timeri)) - return -ENXIO; - - if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) { - spin_lock_irqsave(&slave_active_lock, flags); - if (!(timeri->flags & SNDRV_TIMER_IFLG_RUNNING)) { - spin_unlock_irqrestore(&slave_active_lock, flags); - return -EBUSY; - } - if (timeri->timer) - spin_lock(&timeri->timer->lock); - timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING; - list_del_init(&timeri->ack_list); - list_del_init(&timeri->active_list); - if (timeri->timer) - spin_unlock(&timeri->timer->lock); - spin_unlock_irqrestore(&slave_active_lock, flags); - goto __end; - } timer = timeri->timer; if (!timer) return -EINVAL; spin_lock_irqsave(&timer->lock, flags); if (!(timeri->flags & (SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START))) { - spin_unlock_irqrestore(&timer->lock, flags); - return -EBUSY; + result = -EBUSY; + goto unlock; } list_del_init(&timeri->ack_list); list_del_init(&timeri->active_list); - if (timer->card && timer->card->shutdown) { - spin_unlock_irqrestore(&timer->lock, flags); - return 0; + if (timer->card && timer->card->shutdown) + goto unlock; + if (stop) { + timeri->cticks = timeri->ticks; + timeri->pticks = 0; } if ((timeri->flags & SNDRV_TIMER_IFLG_RUNNING) && !(--timer->running)) { @@ -569,35 +547,60 @@ static int _snd_timer_stop(struct snd_timer_instance *timeri, int event) } } timeri->flags &= ~(SNDRV_TIMER_IFLG_RUNNING | SNDRV_TIMER_IFLG_START); + snd_timer_notify1(timeri, stop ? SNDRV_TIMER_EVENT_STOP : + SNDRV_TIMER_EVENT_CONTINUE); + unlock: spin_unlock_irqrestore(&timer->lock, flags); - __end: - if (event != SNDRV_TIMER_EVENT_RESOLUTION) - snd_timer_notify1(timeri, event); + return result; +} + +/* stop/pause a slave timer */ +static int snd_timer_stop_slave(struct snd_timer_instance *timeri, bool stop) +{ + unsigned long flags; + + spin_lock_irqsave(&slave_active_lock, flags); + if (!(timeri->flags & SNDRV_TIMER_IFLG_RUNNING)) { + spin_unlock_irqrestore(&slave_active_lock, flags); + return -EBUSY; + } + timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING; + if (timeri->timer) { + spin_lock(&timeri->timer->lock); + list_del_init(&timeri->ack_list); + list_del_init(&timeri->active_list); + snd_timer_notify1(timeri, stop ? SNDRV_TIMER_EVENT_STOP : + SNDRV_TIMER_EVENT_CONTINUE); + spin_unlock(&timeri->timer->lock); + } + spin_unlock_irqrestore(&slave_active_lock, flags); return 0; } /* + * start the timer instance + */ +int snd_timer_start(struct snd_timer_instance *timeri, unsigned int ticks) +{ + if (timeri == NULL || ticks < 1) + return -EINVAL; + if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) + return snd_timer_start_slave(timeri, true); + else + return snd_timer_start1(timeri, true, ticks); +} + +/* * stop the timer instance. * * do not call this from the timer callback! */ int snd_timer_stop(struct snd_timer_instance *timeri) { - struct snd_timer *timer; - unsigned long flags; - int err; - - err = _snd_timer_stop(timeri, SNDRV_TIMER_EVENT_STOP); - if (err < 0) - return err; - timer = timeri->timer; - if (!timer) - return -EINVAL; - spin_lock_irqsave(&timer->lock, flags); - timeri->cticks = timeri->ticks; - timeri->pticks = 0; - spin_unlock_irqrestore(&timer->lock, flags); - return 0; + if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) + return snd_timer_stop_slave(timeri, true); + else + return snd_timer_stop1(timeri, true); } /* @@ -605,32 +608,10 @@ int snd_timer_stop(struct snd_timer_instance *timeri) */ int snd_timer_continue(struct snd_timer_instance *timeri) { - struct snd_timer *timer; - int result = -EINVAL; - unsigned long flags; - - if (timeri == NULL) - return result; if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) - return snd_timer_start_slave(timeri); - timer = timeri->timer; - if (! timer) - return -EINVAL; - if (timer->card && timer->card->shutdown) - return -ENODEV; - spin_lock_irqsave(&timer->lock, flags); - if (timeri->flags & SNDRV_TIMER_IFLG_RUNNING) { - result = -EBUSY; - goto unlock; - } - if (!timeri->cticks) - timeri->cticks = 1; - timeri->pticks = 0; - result = snd_timer_start1(timer, timeri, timer->sticks); - unlock: - spin_unlock_irqrestore(&timer->lock, flags); - snd_timer_notify1(timeri, SNDRV_TIMER_EVENT_CONTINUE); - return result; + return snd_timer_start_slave(timeri, false); + else + return snd_timer_start1(timeri, false, 0); } /* @@ -638,7 +619,10 @@ int snd_timer_continue(struct snd_timer_instance *timeri) */ int snd_timer_pause(struct snd_timer_instance * timeri) { - return _snd_timer_stop(timeri, SNDRV_TIMER_EVENT_PAUSE); + if (timeri->flags & SNDRV_TIMER_IFLG_SLAVE) + return snd_timer_stop_slave(timeri, false); + else + return snd_timer_stop1(timeri, false); } /* diff --git a/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c index 1286d3185780..37c43253a5bd 100644 --- a/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-audio-effects-q6-v2.c @@ -16,6 +16,7 @@ #include <sound/compress_params.h> #include <sound/msm-audio-effects-q6-v2.h> #include <sound/devdep_params.h> +#include <sound/q6common.h> #define MAX_ENABLE_CMD_SIZE 32 @@ -61,44 +62,35 @@ int msm_audio_effects_enable_extn(struct audio_client *ac, struct msm_nt_eff_all_config *effects, bool flag) { - uint32_t updt_params[MAX_ENABLE_CMD_SIZE] = {0}; - uint32_t params_length; + u32 flag_param = flag ? 1 : 0; + struct param_hdr_v3 param_hdr = {0}; int rc = 0; pr_debug("%s\n", __func__); - if (!ac) { - pr_err("%s: cannot set audio effects\n", __func__); - return -EINVAL; - } - params_length = 0; - updt_params[0] = AUDPROC_MODULE_ID_VIRTUALIZER; - updt_params[1] = AUDPROC_PARAM_ID_ENABLE; - updt_params[2] = VIRTUALIZER_ENABLE_PARAM_SZ; - updt_params[3] = flag; - params_length += COMMAND_PAYLOAD_SZ + VIRTUALIZER_ENABLE_PARAM_SZ; + param_hdr.module_id = AUDPROC_MODULE_ID_VIRTUALIZER; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_ENABLE; + param_hdr.param_size = VIRTUALIZER_ENABLE_PARAM_SZ; if (effects->virtualizer.enable_flag) - q6asm_send_audio_effects_params(ac, (char *)&updt_params[0], - params_length); - memset(updt_params, 0, MAX_ENABLE_CMD_SIZE); - params_length = 0; - updt_params[0] = AUDPROC_MODULE_ID_BASS_BOOST; - updt_params[1] = AUDPROC_PARAM_ID_ENABLE; - updt_params[2] = BASS_BOOST_ENABLE_PARAM_SZ; - updt_params[3] = flag; - params_length += COMMAND_PAYLOAD_SZ + BASS_BOOST_ENABLE_PARAM_SZ; + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_hdr, + (u8 *) &flag_param); + + param_hdr.module_id = AUDPROC_MODULE_ID_BASS_BOOST; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_ENABLE; + param_hdr.param_size = BASS_BOOST_ENABLE_PARAM_SZ; if (effects->bass_boost.enable_flag) - q6asm_send_audio_effects_params(ac, (char *)&updt_params[0], - params_length); - memset(updt_params, 0, MAX_ENABLE_CMD_SIZE); - params_length = 0; - updt_params[0] = AUDPROC_MODULE_ID_POPLESS_EQUALIZER; - updt_params[1] = AUDPROC_PARAM_ID_ENABLE; - updt_params[2] = EQ_ENABLE_PARAM_SZ; - updt_params[3] = flag; - params_length += COMMAND_PAYLOAD_SZ + EQ_ENABLE_PARAM_SZ; + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_hdr, + (u8 *) &flag_param); + + param_hdr.module_id = AUDPROC_MODULE_ID_POPLESS_EQUALIZER; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_ENABLE; + param_hdr.param_size = EQ_ENABLE_PARAM_SZ; if (effects->equalizer.enable_flag) - q6asm_send_audio_effects_params(ac, (char *)&updt_params[0], - params_length); + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_hdr, + (u8 *) &flag_param); + return rc; } @@ -108,25 +100,32 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, { long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1; char *params = NULL; + u8 *updt_params; int rc = 0; int devices = GET_NEXT(values, param_max_offset, rc); int num_commands = GET_NEXT(values, param_max_offset, rc); - int *updt_params, i, prev_enable_flag; - uint32_t params_length = (MAX_INBAND_PARAM_SZ); + int i, prev_enable_flag; + uint32_t max_params_length = 0; + uint32_t params_length = 0; + struct param_hdr_v3 param_hdr = {0}; + u8 *param_data = NULL; + u32 packed_data_size = 0; pr_debug("%s\n", __func__); if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) { pr_err("%s: cannot set audio effects\n", __func__); return -EINVAL; } - params = kzalloc(params_length, GFP_KERNEL); + params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL); if (!params) { pr_err("%s, params memory alloc failed\n", __func__); return -ENOMEM; } pr_debug("%s: device: %d\n", __func__, devices); - updt_params = (int *)params; - params_length = 0; + updt_params = (u8 *) params; + /* Set MID and IID once at top and only update param specific fields*/ + param_hdr.module_id = AUDPROC_MODULE_ID_VIRTUALIZER; + param_hdr.instance_id = INSTANCE_ID_0; for (i = 0; i < num_commands; i++) { uint32_t command_id = GET_NEXT(values, param_max_offset, rc); @@ -148,23 +147,19 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s:VIRT ENABLE prev:%d, new:%d\n", __func__, prev_enable_flag, virtualizer->enable_flag); - if (prev_enable_flag != virtualizer->enable_flag) { - params_length += COMMAND_PAYLOAD_SZ + - VIRTUALIZER_ENABLE_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "VIRT ENABLE", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_VIRTUALIZER; - *updt_params++ = + if (prev_enable_flag == virtualizer->enable_flag) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + VIRTUALIZER_ENABLE_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "VIRT ENABLE", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_VIRTUALIZER_ENABLE; - *updt_params++ = - VIRTUALIZER_ENABLE_PARAM_SZ; - *updt_params++ = - virtualizer->enable_flag; - } + param_hdr.param_size = VIRTUALIZER_ENABLE_PARAM_SZ; + param_data = (u8 *) &virtualizer->enable_flag; break; case VIRTUALIZER_STRENGTH: if (length != 1 || index_offset != 0) { @@ -176,23 +171,19 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: VIRT STRENGTH val: %d\n", __func__, virtualizer->strength); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - VIRTUALIZER_STRENGTH_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "VIRT STRENGTH", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_VIRTUALIZER; - *updt_params++ = - AUDPROC_PARAM_ID_VIRTUALIZER_STRENGTH; - *updt_params++ = - VIRTUALIZER_STRENGTH_PARAM_SZ; - *updt_params++ = - virtualizer->strength; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + VIRTUALIZER_STRENGTH_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "VIRT STRENGTH", rc); + if (rc != 0) + break; + param_hdr.param_id = + AUDPROC_PARAM_ID_VIRTUALIZER_STRENGTH; + param_hdr.param_size = VIRTUALIZER_STRENGTH_PARAM_SZ; + param_data = (u8 *) &virtualizer->strength; break; case VIRTUALIZER_OUT_TYPE: if (length != 1 || index_offset != 0) { @@ -204,23 +195,19 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: VIRT OUT_TYPE val:%d\n", __func__, virtualizer->out_type); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - VIRTUALIZER_OUT_TYPE_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "VIRT OUT_TYPE", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_VIRTUALIZER; - *updt_params++ = - AUDPROC_PARAM_ID_VIRTUALIZER_OUT_TYPE; - *updt_params++ = - VIRTUALIZER_OUT_TYPE_PARAM_SZ; - *updt_params++ = - virtualizer->out_type; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + VIRTUALIZER_OUT_TYPE_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "VIRT OUT_TYPE", rc); + if (rc != 0) + break; + param_hdr.param_id = + AUDPROC_PARAM_ID_VIRTUALIZER_OUT_TYPE; + param_hdr.param_size = VIRTUALIZER_OUT_TYPE_PARAM_SZ; + param_data = (u8 *) &virtualizer->out_type; break; case VIRTUALIZER_GAIN_ADJUST: if (length != 1 || index_offset != 0) { @@ -232,32 +219,40 @@ int msm_audio_effects_virtualizer_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: VIRT GAIN_ADJUST val:%d\n", __func__, virtualizer->gain_adjust); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - VIRTUALIZER_GAIN_ADJUST_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "VIRT GAIN_ADJUST", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_VIRTUALIZER; - *updt_params++ = + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + VIRTUALIZER_GAIN_ADJUST_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "VIRT GAIN_ADJUST", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_VIRTUALIZER_GAIN_ADJUST; - *updt_params++ = - VIRTUALIZER_GAIN_ADJUST_PARAM_SZ; - *updt_params++ = - virtualizer->gain_adjust; - } + param_hdr.param_size = VIRTUALIZER_GAIN_ADJUST_PARAM_SZ; + param_data = (u8 *) &virtualizer->gain_adjust; break; default: pr_err("%s: Invalid command to set config\n", __func__); - break; + continue; + } + if (rc) + goto invalid_config; + + rc = q6common_pack_pp_params(updt_params, ¶m_hdr, + param_data, &packed_data_size); + if (rc) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, rc); + goto invalid_config; } + + updt_params += packed_data_size; + params_length += packed_data_size; } if (params_length && (rc == 0)) - q6asm_send_audio_effects_params(ac, params, - params_length); + q6asm_set_pp_params(ac, NULL, params, params_length); else pr_debug("%s: did not send pp params\n", __func__); invalid_config: @@ -271,25 +266,32 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, { long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1; char *params = NULL; + u8 *updt_params; int rc = 0; int devices = GET_NEXT(values, param_max_offset, rc); int num_commands = GET_NEXT(values, param_max_offset, rc); - int *updt_params, i, prev_enable_flag; - uint32_t params_length = (MAX_INBAND_PARAM_SZ); + int i, prev_enable_flag; + uint32_t max_params_length = 0; + uint32_t params_length = 0; + struct param_hdr_v3 param_hdr = {0}; + u8 *param_data = NULL; + u32 packed_data_size = 0; pr_debug("%s\n", __func__); if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) { pr_err("%s: cannot set audio effects\n", __func__); return -EINVAL; } - params = kzalloc(params_length, GFP_KERNEL); + params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL); if (!params) { pr_err("%s, params memory alloc failed\n", __func__); return -ENOMEM; } pr_debug("%s: device: %d\n", __func__, devices); - updt_params = (int *)params; - params_length = 0; + updt_params = (u8 *) params; + /* Set MID and IID once at top and only update param specific fields*/ + param_hdr.module_id = AUDPROC_MODULE_ID_REVERB; + param_hdr.instance_id = INSTANCE_ID_0; for (i = 0; i < num_commands; i++) { uint32_t command_id = GET_NEXT(values, param_max_offset, rc); @@ -311,23 +313,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s:REVERB_ENABLE prev:%d,new:%d\n", __func__, prev_enable_flag, reverb->enable_flag); - if (prev_enable_flag != reverb->enable_flag) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_ENABLE_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_ENABLE", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_ENABLE; - *updt_params++ = - REVERB_ENABLE_PARAM_SZ; - *updt_params++ = - reverb->enable_flag; - } + if (prev_enable_flag == reverb->enable_flag) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_ENABLE_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_ENABLE", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_ENABLE; + param_hdr.param_size = REVERB_ENABLE_PARAM_SZ; + param_data = (u8 *) &reverb->enable_flag; break; case REVERB_MODE: if (length != 1 || index_offset != 0) { @@ -339,23 +336,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_MODE val:%d\n", __func__, reverb->mode); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_MODE_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_MODE", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_MODE; - *updt_params++ = - REVERB_MODE_PARAM_SZ; - *updt_params++ = - reverb->mode; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_MODE_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_MODE", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_MODE; + param_hdr.param_size = REVERB_MODE_PARAM_SZ; + param_data = (u8 *) &reverb->mode; break; case REVERB_PRESET: if (length != 1 || index_offset != 0) { @@ -367,23 +359,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_PRESET val:%d\n", __func__, reverb->preset); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_PRESET_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_PRESET", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_PRESET; - *updt_params++ = - REVERB_PRESET_PARAM_SZ; - *updt_params++ = - reverb->preset; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_PRESET_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_PRESET", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_PRESET; + param_hdr.param_size = REVERB_PRESET_PARAM_SZ; + param_data = (u8 *) &reverb->preset; break; case REVERB_WET_MIX: if (length != 1 || index_offset != 0) { @@ -395,23 +382,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_WET_MIX val:%d\n", __func__, reverb->wet_mix); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_WET_MIX_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_WET_MIX", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_WET_MIX; - *updt_params++ = - REVERB_WET_MIX_PARAM_SZ; - *updt_params++ = - reverb->wet_mix; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_WET_MIX_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_WET_MIX", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_WET_MIX; + param_hdr.param_size = REVERB_WET_MIX_PARAM_SZ; + param_data = (u8 *) &reverb->wet_mix; break; case REVERB_GAIN_ADJUST: if (length != 1 || index_offset != 0) { @@ -423,23 +405,19 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_GAIN_ADJUST val:%d\n", __func__, reverb->gain_adjust); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_GAIN_ADJUST_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_GAIN_ADJUST", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_GAIN_ADJUST; - *updt_params++ = - REVERB_GAIN_ADJUST_PARAM_SZ; - *updt_params++ = - reverb->gain_adjust; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_GAIN_ADJUST_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_GAIN_ADJUST", rc); + if (rc != 0) + break; + param_hdr.param_id = + AUDPROC_PARAM_ID_REVERB_GAIN_ADJUST; + param_hdr.param_size = REVERB_GAIN_ADJUST_PARAM_SZ; + param_data = (u8 *) &reverb->gain_adjust; break; case REVERB_ROOM_LEVEL: if (length != 1 || index_offset != 0) { @@ -451,23 +429,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_ROOM_LEVEL val:%d\n", __func__, reverb->room_level); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_ROOM_LEVEL_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_ROOM_LEVEL", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_ROOM_LEVEL; - *updt_params++ = - REVERB_ROOM_LEVEL_PARAM_SZ; - *updt_params++ = - reverb->room_level; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_ROOM_LEVEL_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_ROOM_LEVEL", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_ROOM_LEVEL; + param_hdr.param_size = REVERB_ROOM_LEVEL_PARAM_SZ; + param_data = (u8 *) &reverb->room_level; break; case REVERB_ROOM_HF_LEVEL: if (length != 1 || index_offset != 0) { @@ -479,23 +452,19 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_ROOM_HF_LEVEL val%d\n", __func__, reverb->room_hf_level); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_ROOM_HF_LEVEL_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_ROOM_HF_LEVEL", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_ROOM_HF_LEVEL; - *updt_params++ = - REVERB_ROOM_HF_LEVEL_PARAM_SZ; - *updt_params++ = - reverb->room_hf_level; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_ROOM_HF_LEVEL_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_ROOM_HF_LEVEL", rc); + if (rc != 0) + break; + param_hdr.param_id = + AUDPROC_PARAM_ID_REVERB_ROOM_HF_LEVEL; + param_hdr.param_size = REVERB_ROOM_HF_LEVEL_PARAM_SZ; + param_data = (u8 *) &reverb->room_hf_level; break; case REVERB_DECAY_TIME: if (length != 1 || index_offset != 0) { @@ -507,23 +476,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_DECAY_TIME val:%d\n", __func__, reverb->decay_time); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_DECAY_TIME_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_DECAY_TIME", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_DECAY_TIME; - *updt_params++ = - REVERB_DECAY_TIME_PARAM_SZ; - *updt_params++ = - reverb->decay_time; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_DECAY_TIME_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_DECAY_TIME", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_DECAY_TIME; + param_hdr.param_size = REVERB_DECAY_TIME_PARAM_SZ; + param_data = (u8 *) &reverb->decay_time; break; case REVERB_DECAY_HF_RATIO: if (length != 1 || index_offset != 0) { @@ -535,23 +499,19 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_DECAY_HF_RATIO val%d\n", __func__, reverb->decay_hf_ratio); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_DECAY_HF_RATIO_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_DECAY_HF_RATIO", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_DECAY_HF_RATIO; - *updt_params++ = - REVERB_DECAY_HF_RATIO_PARAM_SZ; - *updt_params++ = - reverb->decay_hf_ratio; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_DECAY_HF_RATIO_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_DECAY_HF_RATIO", rc); + if (rc != 0) + break; + param_hdr.param_id = + AUDPROC_PARAM_ID_REVERB_DECAY_HF_RATIO; + param_hdr.param_size = REVERB_DECAY_HF_RATIO_PARAM_SZ; + param_data = (u8 *) &reverb->decay_hf_ratio; break; case REVERB_REFLECTIONS_LEVEL: if (length != 1 || index_offset != 0) { @@ -563,23 +523,20 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_REFLECTIONS_LEVEL val:%d\n", __func__, reverb->reflections_level); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_REFLECTIONS_LEVEL_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_REFLECTIONS_LEVEL", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_REFLECTIONS_LEVEL_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_REFLECTIONS_LEVEL", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_REFLECTIONS_LEVEL; - *updt_params++ = + param_hdr.param_size = REVERB_REFLECTIONS_LEVEL_PARAM_SZ; - *updt_params++ = - reverb->reflections_level; - } + param_data = (u8 *) &reverb->reflections_level; break; case REVERB_REFLECTIONS_DELAY: if (length != 1 || index_offset != 0) { @@ -591,23 +548,20 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_REFLECTIONS_DELAY val:%d\n", __func__, reverb->reflections_delay); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_REFLECTIONS_DELAY_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_REFLECTIONS_DELAY", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_REFLECTIONS_DELAY_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_REFLECTIONS_DELAY", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_REFLECTIONS_DELAY; - *updt_params++ = + param_hdr.param_size = REVERB_REFLECTIONS_DELAY_PARAM_SZ; - *updt_params++ = - reverb->reflections_delay; - } + param_data = (u8 *) &reverb->reflections_delay; break; case REVERB_LEVEL: if (length != 1 || index_offset != 0) { @@ -619,23 +573,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_LEVEL val:%d\n", __func__, reverb->level); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_LEVEL_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_LEVEL", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_LEVEL; - *updt_params++ = - REVERB_LEVEL_PARAM_SZ; - *updt_params++ = - reverb->level; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_LEVEL_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_LEVEL", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_LEVEL; + param_hdr.param_size = REVERB_LEVEL_PARAM_SZ; + param_data = (u8 *) &reverb->level; break; case REVERB_DELAY: if (length != 1 || index_offset != 0) { @@ -647,23 +596,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s:REVERB_DELAY val:%d\n", __func__, reverb->delay); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_DELAY_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_DELAY", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_DELAY; - *updt_params++ = - REVERB_DELAY_PARAM_SZ; - *updt_params++ = - reverb->delay; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_DELAY_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_DELAY", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_DELAY; + param_hdr.param_size = REVERB_DELAY_PARAM_SZ; + param_data = (u8 *) &reverb->delay; break; case REVERB_DIFFUSION: if (length != 1 || index_offset != 0) { @@ -675,23 +619,18 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_DIFFUSION val:%d\n", __func__, reverb->diffusion); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_DIFFUSION_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_DIFFUSION", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_DIFFUSION; - *updt_params++ = - REVERB_DIFFUSION_PARAM_SZ; - *updt_params++ = - reverb->diffusion; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_DIFFUSION_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_DIFFUSION", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_DIFFUSION; + param_hdr.param_size = REVERB_DIFFUSION_PARAM_SZ; + param_data = (u8 *) &reverb->diffusion; break; case REVERB_DENSITY: if (length != 1 || index_offset != 0) { @@ -703,32 +642,39 @@ int msm_audio_effects_reverb_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: REVERB_DENSITY val:%d\n", __func__, reverb->density); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - REVERB_DENSITY_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "REVERB_DENSITY", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_REVERB; - *updt_params++ = - AUDPROC_PARAM_ID_REVERB_DENSITY; - *updt_params++ = - REVERB_DENSITY_PARAM_SZ; - *updt_params++ = - reverb->density; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + REVERB_DENSITY_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "REVERB_DENSITY", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_DENSITY; + param_hdr.param_size = REVERB_DENSITY_PARAM_SZ; + param_data = (u8 *) &reverb->density; break; default: pr_err("%s: Invalid command to set config\n", __func__); - break; + continue; } + if (rc) + goto invalid_config; + + rc = q6common_pack_pp_params(updt_params, ¶m_hdr, + param_data, &packed_data_size); + if (rc) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, rc); + goto invalid_config; + } + + updt_params += packed_data_size; + params_length += packed_data_size; } if (params_length && (rc == 0)) - q6asm_send_audio_effects_params(ac, params, - params_length); + q6asm_set_pp_params(ac, NULL, params, params_length); else pr_debug("%s: did not send pp params\n", __func__); invalid_config: @@ -742,25 +688,32 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac, { long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1; char *params = NULL; + u8 *updt_params; int rc = 0; int devices = GET_NEXT(values, param_max_offset, rc); int num_commands = GET_NEXT(values, param_max_offset, rc); - int *updt_params, i, prev_enable_flag; - uint32_t params_length = (MAX_INBAND_PARAM_SZ); + int i, prev_enable_flag; + uint32_t max_params_length = 0; + uint32_t params_length = 0; + struct param_hdr_v3 param_hdr = {0}; + u8 *param_data = NULL; + u32 packed_data_size = 0; pr_debug("%s\n", __func__); if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) { pr_err("%s: cannot set audio effects\n", __func__); return -EINVAL; } - params = kzalloc(params_length, GFP_KERNEL); + params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL); if (!params) { pr_err("%s, params memory alloc failed\n", __func__); return -ENOMEM; } pr_debug("%s: device: %d\n", __func__, devices); - updt_params = (int *)params; - params_length = 0; + updt_params = (u8 *) params; + /* Set MID and IID once at top and only update param specific fields*/ + param_hdr.module_id = AUDPROC_MODULE_ID_BASS_BOOST; + param_hdr.instance_id = INSTANCE_ID_0; for (i = 0; i < num_commands; i++) { uint32_t command_id = GET_NEXT(values, param_max_offset, rc); @@ -783,23 +736,18 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac, pr_debug("%s: BASS_BOOST_ENABLE prev:%d new:%d\n", __func__, prev_enable_flag, bass_boost->enable_flag); - if (prev_enable_flag != bass_boost->enable_flag) { - params_length += COMMAND_PAYLOAD_SZ + - BASS_BOOST_ENABLE_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "BASS_BOOST_ENABLE", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_BASS_BOOST; - *updt_params++ = - AUDPROC_PARAM_ID_BASS_BOOST_ENABLE; - *updt_params++ = - BASS_BOOST_ENABLE_PARAM_SZ; - *updt_params++ = - bass_boost->enable_flag; - } + if (prev_enable_flag == bass_boost->enable_flag) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + BASS_BOOST_ENABLE_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "BASS_BOOST_ENABLE", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_BASS_BOOST_ENABLE; + param_hdr.param_size = BASS_BOOST_ENABLE_PARAM_SZ; + param_data = (u8 *) &bass_boost->enable_flag; break; case BASS_BOOST_MODE: if (length != 1 || index_offset != 0) { @@ -811,23 +759,18 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: BASS_BOOST_MODE val:%d\n", __func__, bass_boost->mode); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - BASS_BOOST_MODE_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "BASS_BOOST_MODE", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_BASS_BOOST; - *updt_params++ = - AUDPROC_PARAM_ID_BASS_BOOST_MODE; - *updt_params++ = - BASS_BOOST_MODE_PARAM_SZ; - *updt_params++ = - bass_boost->mode; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + BASS_BOOST_MODE_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "BASS_BOOST_MODE", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_BASS_BOOST_MODE; + param_hdr.param_size = BASS_BOOST_MODE_PARAM_SZ; + param_data = (u8 *) &bass_boost->mode; break; case BASS_BOOST_STRENGTH: if (length != 1 || index_offset != 0) { @@ -839,32 +782,40 @@ int msm_audio_effects_bass_boost_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: BASS_BOOST_STRENGTH val:%d\n", __func__, bass_boost->strength); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - BASS_BOOST_STRENGTH_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "BASS_BOOST_STRENGTH", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_BASS_BOOST; - *updt_params++ = - AUDPROC_PARAM_ID_BASS_BOOST_STRENGTH; - *updt_params++ = - BASS_BOOST_STRENGTH_PARAM_SZ; - *updt_params++ = - bass_boost->strength; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + BASS_BOOST_STRENGTH_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "BASS_BOOST_STRENGTH", rc); + if (rc != 0) + break; + param_hdr.param_id = + AUDPROC_PARAM_ID_BASS_BOOST_STRENGTH; + param_hdr.param_size = BASS_BOOST_STRENGTH_PARAM_SZ; + param_data = (u8 *) &bass_boost->strength; break; default: pr_err("%s: Invalid command to set config\n", __func__); - break; + continue; } + if (rc) + goto invalid_config; + + rc = q6common_pack_pp_params(updt_params, ¶m_hdr, + param_data, &packed_data_size); + if (rc) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, rc); + goto invalid_config; + } + + updt_params += packed_data_size; + params_length += packed_data_size; } if (params_length && (rc == 0)) - q6asm_send_audio_effects_params(ac, params, - params_length); + q6asm_set_pp_params(ac, NULL, params, params_length); else pr_debug("%s: did not send pp params\n", __func__); invalid_config: @@ -878,25 +829,32 @@ int msm_audio_effects_pbe_handler(struct audio_client *ac, { long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1; char *params = NULL; + u8 *updt_params; int rc = 0; int devices = GET_NEXT(values, param_max_offset, rc); int num_commands = GET_NEXT(values, param_max_offset, rc); - int *updt_params, i, j, prev_enable_flag; - uint32_t params_length = (MAX_INBAND_PARAM_SZ); + int i, prev_enable_flag; + uint32_t max_params_length = 0; + uint32_t params_length = 0; + struct param_hdr_v3 param_hdr = {0}; + u8 *param_data = NULL; + u32 packed_data_size = 0; pr_debug("%s\n", __func__); if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) { pr_err("%s: cannot set audio effects\n", __func__); return -EINVAL; } - params = kzalloc(params_length, GFP_KERNEL); + params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL); if (!params) { pr_err("%s, params memory alloc failed\n", __func__); return -ENOMEM; } pr_debug("%s: device: %d\n", __func__, devices); - updt_params = (int *)params; - params_length = 0; + updt_params = (u8 *) params; + /* Set MID and IID once at top and only update param specific fields*/ + param_hdr.module_id = AUDPROC_MODULE_ID_PBE; + param_hdr.instance_id = INSTANCE_ID_0; for (i = 0; i < num_commands; i++) { uint32_t command_id = GET_NEXT(values, param_max_offset, rc); @@ -917,23 +875,18 @@ int msm_audio_effects_pbe_handler(struct audio_client *ac, prev_enable_flag = pbe->enable_flag; pbe->enable_flag = GET_NEXT(values, param_max_offset, rc); - if (prev_enable_flag != pbe->enable_flag) { - params_length += COMMAND_PAYLOAD_SZ + - PBE_ENABLE_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "PBE_ENABLE", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_PBE; - *updt_params++ = - AUDPROC_PARAM_ID_PBE_ENABLE; - *updt_params++ = - PBE_ENABLE_PARAM_SZ; - *updt_params++ = - pbe->enable_flag; - } + if (prev_enable_flag == pbe->enable_flag) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + PBE_ENABLE_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "PBE_ENABLE", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_PBE_ENABLE; + param_hdr.param_size = PBE_ENABLE_PARAM_SZ; + param_data = (u8 *) &pbe->enable_flag; break; case PBE_CONFIG: pr_debug("%s: PBE_PARAM length %u\n", __func__, length); @@ -944,37 +897,38 @@ int msm_audio_effects_pbe_handler(struct audio_client *ac, rc = -EINVAL; goto invalid_config; } - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + length; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "PBE_PARAM", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_PBE; - *updt_params++ = - AUDPROC_PARAM_ID_PBE_PARAM_CONFIG; - *updt_params++ = - length; - for (j = 0; j < length; ) { - j += sizeof(*updt_params); - *updt_params++ = - GET_NEXT( - values, - param_max_offset, - rc); - } - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = + params_length + COMMAND_IID_PAYLOAD_SZ + length; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "PBE_PARAM", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_PBE_PARAM_CONFIG; + param_hdr.param_size = length; + param_data = (u8 *) values; break; default: pr_err("%s: Invalid command to set config\n", __func__); - break; + continue; + } + if (rc) + goto invalid_config; + + rc = q6common_pack_pp_params(updt_params, ¶m_hdr, + param_data, &packed_data_size); + if (rc) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, rc); + goto invalid_config; } + + updt_params += packed_data_size; + params_length += packed_data_size; } if (params_length && (rc == 0)) - q6asm_send_audio_effects_params(ac, params, - params_length); + q6asm_set_pp_params(ac, NULL, params, params_length); invalid_config: kfree(params); return rc; @@ -986,25 +940,35 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, { long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1; char *params = NULL; + u8 *updt_params = NULL; int rc = 0; int devices = GET_NEXT(values, param_max_offset, rc); int num_commands = GET_NEXT(values, param_max_offset, rc); - int *updt_params, i, prev_enable_flag; - uint32_t params_length = (MAX_INBAND_PARAM_SZ); + int i, prev_enable_flag; + uint32_t max_params_length = 0; + uint32_t params_length = 0; + struct param_hdr_v3 param_hdr = {0}; + u8 *param_data = NULL; + u32 packed_data_size = 0; + u8 *eq_config_data = NULL; + u32 *updt_config_data = NULL; + int config_param_length; pr_debug("%s\n", __func__); if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) { pr_err("%s: cannot set audio effects\n", __func__); return -EINVAL; } - params = kzalloc(params_length, GFP_KERNEL); + params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL); if (!params) { pr_err("%s, params memory alloc failed\n", __func__); return -ENOMEM; } pr_debug("%s: device: %d\n", __func__, devices); - updt_params = (int *)params; - params_length = 0; + updt_params = (u8 *) params; + /* Set MID and IID once at top and only update param specific fields*/ + param_hdr.module_id = AUDPROC_MODULE_ID_POPLESS_EQUALIZER; + param_hdr.instance_id = INSTANCE_ID_0; for (i = 0; i < num_commands; i++) { uint32_t command_id = GET_NEXT(values, param_max_offset, rc); @@ -1028,23 +992,18 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: EQ_ENABLE prev:%d new:%d\n", __func__, prev_enable_flag, eq->enable_flag); - if (prev_enable_flag != eq->enable_flag) { - params_length += COMMAND_PAYLOAD_SZ + - EQ_ENABLE_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "EQ_ENABLE", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_POPLESS_EQUALIZER; - *updt_params++ = - AUDPROC_PARAM_ID_EQ_ENABLE; - *updt_params++ = - EQ_ENABLE_PARAM_SZ; - *updt_params++ = - eq->enable_flag; - } + if (prev_enable_flag == eq->enable_flag) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + EQ_ENABLE_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "EQ_ENABLE", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_EQ_ENABLE; + param_hdr.param_size = EQ_ENABLE_PARAM_SZ; + param_data = (u8 *) &eq->enable_flag; break; case EQ_CONFIG: if (length < EQ_CONFIG_PARAM_LEN || index_offset != 0) { @@ -1093,43 +1052,46 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, eq->per_band_cfg[idx].quality_factor = GET_NEXT(values, param_max_offset, rc); } - if (command_config_state == CONFIG_SET) { - int config_param_length = EQ_CONFIG_PARAM_SZ + - (EQ_CONFIG_PER_BAND_PARAM_SZ* - eq->config.num_bands); - params_length += COMMAND_PAYLOAD_SZ + - config_param_length; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "EQ_CONFIG", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_POPLESS_EQUALIZER; - *updt_params++ = - AUDPROC_PARAM_ID_EQ_CONFIG; - *updt_params++ = - config_param_length; - *updt_params++ = - eq->config.eq_pregain; - *updt_params++ = - eq->config.preset_id; - *updt_params++ = - eq->config.num_bands; - for (idx = 0; idx < MAX_EQ_BANDS; idx++) { - if (eq->per_band_cfg[idx].band_idx < 0) - continue; - *updt_params++ = + if (command_config_state != CONFIG_SET) + break; + config_param_length = EQ_CONFIG_PARAM_SZ + + (EQ_CONFIG_PER_BAND_PARAM_SZ * + eq->config.num_bands); + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + config_param_length; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "EQ_CONFIG", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_EQ_CONFIG; + param_hdr.param_size = config_param_length; + + if (!eq_config_data) + eq_config_data = kzalloc(config_param_length, + GFP_KERNEL); + else + memset(eq_config_data, 0, config_param_length); + if (!eq_config_data) + return -ENOMEM; + param_data = eq_config_data; + updt_config_data = (u32 *) eq_config_data; + *updt_config_data++ = eq->config.eq_pregain; + *updt_config_data++ = eq->config.preset_id; + *updt_config_data++ = eq->config.num_bands; + for (idx = 0; idx < MAX_EQ_BANDS; idx++) { + if (eq->per_band_cfg[idx].band_idx < 0) + continue; + *updt_config_data++ = eq->per_band_cfg[idx].filter_type; - *updt_params++ = + *updt_config_data++ = eq->per_band_cfg[idx].freq_millihertz; - *updt_params++ = + *updt_config_data++ = eq->per_band_cfg[idx].gain_millibels; - *updt_params++ = + *updt_config_data++ = eq->per_band_cfg[idx].quality_factor; - *updt_params++ = + *updt_config_data++ = eq->per_band_cfg[idx].band_idx; - } } break; case EQ_BAND_INDEX: @@ -1147,23 +1109,18 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, eq->band_index = idx; pr_debug("%s: EQ_BAND_INDEX val:%d\n", __func__, eq->band_index); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - EQ_BAND_INDEX_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "EQ_BAND_INDEX", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_POPLESS_EQUALIZER; - *updt_params++ = - AUDPROC_PARAM_ID_EQ_BAND_INDEX; - *updt_params++ = - EQ_BAND_INDEX_PARAM_SZ; - *updt_params++ = - eq->band_index; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + EQ_BAND_INDEX_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "EQ_BAND_INDEX", rc); + if (rc != 0) + break; + param_hdr.param_id = AUDPROC_PARAM_ID_EQ_BAND_INDEX; + param_hdr.param_size = EQ_BAND_INDEX_PARAM_SZ; + param_data = (u8 *) &eq->band_index; break; case EQ_SINGLE_BAND_FREQ: if (length != 1 || index_offset != 0) { @@ -1179,36 +1136,45 @@ int msm_audio_effects_popless_eq_handler(struct audio_client *ac, GET_NEXT(values, param_max_offset, rc); pr_debug("%s: EQ_SINGLE_BAND_FREQ idx:%d, val:%d\n", __func__, eq->band_index, eq->freq_millihertz); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - EQ_SINGLE_BAND_FREQ_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "EQ_SINGLE_BAND_FREQ", rc); - if (rc != 0) - goto invalid_config; - *updt_params++ = - AUDPROC_MODULE_ID_POPLESS_EQUALIZER; - *updt_params++ = - AUDPROC_PARAM_ID_EQ_SINGLE_BAND_FREQ; - *updt_params++ = - EQ_SINGLE_BAND_FREQ_PARAM_SZ; - *updt_params++ = - eq->freq_millihertz; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + EQ_SINGLE_BAND_FREQ_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "EQ_SINGLE_BAND_FREQ", rc); + if (rc != 0) + break; + param_hdr.param_id = + AUDPROC_PARAM_ID_EQ_SINGLE_BAND_FREQ; + param_hdr.param_size = EQ_SINGLE_BAND_FREQ_PARAM_SZ; + param_data = (u8 *) &eq->freq_millihertz; break; default: pr_err("%s: Invalid command to set config\n", __func__); - break; + continue; + } + if (rc) + goto invalid_config; + + rc = q6common_pack_pp_params(updt_params, ¶m_hdr, + param_data, &packed_data_size); + if (rc) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, rc); + goto invalid_config; } + + updt_params += packed_data_size; + params_length += packed_data_size; } if (params_length && (rc == 0)) - q6asm_send_audio_effects_params(ac, params, - params_length); + q6asm_set_pp_params(ac, NULL, params, params_length); else pr_debug("%s: did not send pp params\n", __func__); invalid_config: kfree(params); + kfree(eq_config_data); return rc; } @@ -1220,8 +1186,13 @@ static int __msm_audio_effects_volume_handler(struct audio_client *ac, int devices; int num_commands; char *params = NULL; - int *updt_params, i; - uint32_t params_length = (MAX_INBAND_PARAM_SZ); + u8 *updt_params; + int i; + uint32_t vol_gain_2ch = 0; + uint32_t max_params_length = 0; + uint32_t params_length = 0; + struct param_hdr_v3 param_hdr = {0}; + u32 packed_data_size = 0; long *param_max_offset; int rc = 0; @@ -1238,13 +1209,14 @@ static int __msm_audio_effects_volume_handler(struct audio_client *ac, pr_err("%s: cannot set audio effects\n", __func__); return -EINVAL; } - params = kzalloc(params_length, GFP_KERNEL); + params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL); if (!params) { pr_err("%s, params memory alloc failed\n", __func__); return -ENOMEM; } - updt_params = (int *)params; - params_length = 0; + updt_params = (u8 *) params; + /* Set MID and IID once at top and only update param specific fields*/ + q6asm_set_soft_volume_module_instance_ids(instance, ¶m_hdr); for (i = 0; i < num_commands; i++) { uint32_t command_id = GET_NEXT(values, param_max_offset, rc); @@ -1266,43 +1238,15 @@ static int __msm_audio_effects_volume_handler(struct audio_client *ac, vol->right_gain = GET_NEXT(values, param_max_offset, rc); vol->master_gain = 0x2000; - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - SOFT_VOLUME_GAIN_2CH_PARAM_SZ; - params_length += COMMAND_PAYLOAD_SZ + - SOFT_VOLUME_GAIN_MASTER_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "VOLUME/VOLUME2_GAIN_2CH", - rc); - if (rc != 0) - goto invalid_config; - if (instance == SOFT_VOLUME_INSTANCE_2) - *updt_params++ = - ASM_MODULE_ID_VOL_CTRL2; - else - *updt_params++ = - ASM_MODULE_ID_VOL_CTRL; - *updt_params++ = - ASM_PARAM_ID_VOL_CTRL_LR_CHANNEL_GAIN; - *updt_params++ = - SOFT_VOLUME_GAIN_2CH_PARAM_SZ; - *updt_params++ = - (vol->left_gain << 16) | - vol->right_gain; - if (instance == SOFT_VOLUME_INSTANCE_2) - *updt_params++ = - ASM_MODULE_ID_VOL_CTRL2; - else - *updt_params++ = - ASM_MODULE_ID_VOL_CTRL; - *updt_params++ = - ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN; - *updt_params++ = - SOFT_VOLUME_GAIN_MASTER_PARAM_SZ; - *updt_params++ = - vol->master_gain; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + SOFT_VOLUME_GAIN_2CH_PARAM_SZ + + COMMAND_IID_PAYLOAD_SZ + + SOFT_VOLUME_GAIN_MASTER_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "VOLUME/VOLUME2_GAIN_2CH", rc); break; case SOFT_VOLUME_GAIN_MASTER: case SOFT_VOLUME2_GAIN_MASTER: @@ -1315,53 +1259,57 @@ static int __msm_audio_effects_volume_handler(struct audio_client *ac, vol->right_gain = 0x2000; vol->master_gain = GET_NEXT(values, param_max_offset, rc); - if (command_config_state == CONFIG_SET) { - params_length += COMMAND_PAYLOAD_SZ + - SOFT_VOLUME_GAIN_2CH_PARAM_SZ; - params_length += COMMAND_PAYLOAD_SZ + - SOFT_VOLUME_GAIN_MASTER_PARAM_SZ; - CHECK_PARAM_LEN(params_length, - MAX_INBAND_PARAM_SZ, - "VOLUME/VOLUME2_GAIN_MASTER", - rc); - if (rc != 0) - goto invalid_config; - if (instance == SOFT_VOLUME_INSTANCE_2) - *updt_params++ = - ASM_MODULE_ID_VOL_CTRL2; - else - *updt_params++ = - ASM_MODULE_ID_VOL_CTRL; - *updt_params++ = - ASM_PARAM_ID_VOL_CTRL_LR_CHANNEL_GAIN; - *updt_params++ = - SOFT_VOLUME_GAIN_2CH_PARAM_SZ; - *updt_params++ = - (vol->left_gain << 16) | - vol->right_gain; - if (instance == SOFT_VOLUME_INSTANCE_2) - *updt_params++ = - ASM_MODULE_ID_VOL_CTRL2; - else - *updt_params++ = - ASM_MODULE_ID_VOL_CTRL; - *updt_params++ = - ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN; - *updt_params++ = - SOFT_VOLUME_GAIN_MASTER_PARAM_SZ; - *updt_params++ = - vol->master_gain; - } + if (command_config_state != CONFIG_SET) + break; + max_params_length = params_length + + COMMAND_IID_PAYLOAD_SZ + + SOFT_VOLUME_GAIN_2CH_PARAM_SZ + + COMMAND_IID_PAYLOAD_SZ + + SOFT_VOLUME_GAIN_MASTER_PARAM_SZ; + CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ, + "VOLUME/VOLUME2_GAIN_MASTER", rc); break; default: pr_err("%s: Invalid command id: %d to set config\n", __func__, command_id); - break; + continue; + } + if (rc) + continue; + + /* Set Volume Control for Left/Right */ + param_hdr.param_id = ASM_PARAM_ID_VOL_CTRL_LR_CHANNEL_GAIN; + param_hdr.param_size = SOFT_VOLUME_GAIN_2CH_PARAM_SZ; + vol_gain_2ch = (vol->left_gain << 16) | vol->right_gain; + rc = q6common_pack_pp_params(updt_params, ¶m_hdr, + (u8 *) &vol_gain_2ch, + &packed_data_size); + if (rc) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, rc); + goto invalid_config; } + + updt_params += packed_data_size; + params_length += packed_data_size; + + /* Set Master Volume Control */ + param_hdr.param_id = ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN; + param_hdr.param_size = SOFT_VOLUME_GAIN_MASTER_PARAM_SZ; + rc = q6common_pack_pp_params(updt_params, ¶m_hdr, + (u8 *) &vol->master_gain, + &packed_data_size); + if (rc) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, rc); + goto invalid_config; + } + + updt_params += packed_data_size; + params_length += packed_data_size; } if (params_length && (rc == 0)) - q6asm_send_audio_effects_params(ac, params, - params_length); + q6asm_set_pp_params(ac, NULL, params, params_length); invalid_config: kfree(params); return rc; diff --git a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c index 4de712a10f96..6dda41cc85bb 100644 --- a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c +++ b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.c @@ -14,6 +14,7 @@ #include <linux/bitops.h> #include <sound/control.h> #include <sound/q6adm-v2.h> +#include <sound/q6common.h> #include "msm-ds2-dap-config.h" #include "msm-pcm-routing-v2.h" @@ -196,6 +197,7 @@ static void msm_ds2_dap_check_and_update_ramp_wait(int port_id, int copp_idx, int32_t *update_params_value = NULL; uint32_t params_length = SOFT_VOLUME_PARAM_SIZE * sizeof(uint32_t); uint32_t param_payload_len = PARAM_PAYLOAD_SIZE * sizeof(uint32_t); + struct param_hdr_v3 param_hdr = {0}; int rc = 0; update_params_value = kzalloc(params_length + param_payload_len, @@ -204,11 +206,13 @@ static void msm_ds2_dap_check_and_update_ramp_wait(int port_id, int copp_idx, pr_err("%s: params memory alloc failed\n", __func__); goto end; } - rc = adm_get_params(port_id, copp_idx, - AUDPROC_MODULE_ID_VOL_CTRL, - AUDPROC_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS, - params_length + param_payload_len, - (char *) update_params_value); + + param_hdr.module_id = AUDPROC_MODULE_ID_VOL_CTRL; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS; + param_hdr.param_size = params_length + param_payload_len; + rc = adm_get_pp_params(port_id, copp_idx, ADM_CLIENT_ID_DEFAULT, NULL, + ¶m_hdr, (char *) update_params_value); if (rc == 0) { pr_debug("%s: params_value [0x%x, 0x%x, 0x%x]\n", __func__, update_params_value[0], @@ -229,12 +233,13 @@ end: static int msm_ds2_dap_set_vspe_vdhe(int dev_map_idx, bool is_custom_stereo_enabled) { - int32_t *update_params_value = NULL; - int32_t *param_val = NULL; - int idx, i, j, rc = 0, cdev; - uint32_t params_length = (TOTAL_LENGTH_DOLBY_PARAM + - 2 * DOLBY_PARAM_PAYLOAD_SIZE) * - sizeof(uint32_t); + u8 *packed_param_data = NULL; + u8 *param_data = NULL; + struct param_hdr_v3 param_hdr = {0}; + u32 packed_param_size = 0; + u32 param_size = 0; + int cdev; + int rc = 0; if (dev_map_idx < 0 || dev_map_idx >= DS2_DEVICES_ALL) { pr_err("%s: invalid dev map index %d\n", __func__, dev_map_idx); @@ -262,73 +267,88 @@ static int msm_ds2_dap_set_vspe_vdhe(int dev_map_idx, goto end; } - update_params_value = kzalloc(params_length, GFP_KERNEL); - if (!update_params_value) { - pr_err("%s: params memory alloc failed\n", __func__); - rc = -ENOMEM; + /* Allocate the max space needed */ + packed_param_size = (TOTAL_LENGTH_DOLBY_PARAM * sizeof(uint32_t)) + + (2 * sizeof(union param_hdrs)); + packed_param_data = kzalloc(packed_param_size, GFP_KERNEL); + if (!packed_param_data) + return -ENOMEM; + + packed_param_size = 0; + + /* Set common values */ + cdev = dev_map[dev_map_idx].cache_dev; + param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + + /* Pack VDHE header + data */ + param_hdr.param_id = DOLBY_PARAM_ID_VDHE; + param_size = DOLBY_PARAM_VDHE_LENGTH * sizeof(uint32_t); + param_hdr.param_size = param_size; + + if (is_custom_stereo_enabled) + param_data = NULL; + else + param_data = (u8 *) &ds2_dap_params[cdev] + .params_val[DOLBY_PARAM_VDHE_OFFSET]; + + rc = q6common_pack_pp_params(packed_param_data, ¶m_hdr, param_data, + ¶m_size); + if (rc) { + pr_err("%s: Failed to pack params, error %d\n", __func__, rc); goto end; } - params_length = 0; - param_val = update_params_value; - cdev = dev_map[dev_map_idx].cache_dev; - /* for VDHE and VSPE DAP params at index 0 and 1 in table */ - for (i = 0; i < 2; i++) { - *update_params_value++ = DOLBY_BUNDLE_MODULE_ID; - *update_params_value++ = ds2_dap_params_id[i]; - *update_params_value++ = ds2_dap_params_length[i] * - sizeof(uint32_t); - idx = ds2_dap_params_offset[i]; - for (j = 0; j < ds2_dap_params_length[i]; j++) { - if (is_custom_stereo_enabled) - *update_params_value++ = 0; - else - *update_params_value++ = - ds2_dap_params[cdev].params_val[idx+j]; - } - params_length += (DOLBY_PARAM_PAYLOAD_SIZE + - ds2_dap_params_length[i]) * - sizeof(uint32_t); - } - - pr_debug("%s: valid param length: %d\n", __func__, params_length); - if (params_length) { - rc = adm_dolby_dap_send_params(dev_map[dev_map_idx].port_id, - dev_map[dev_map_idx].copp_idx, - (char *)param_val, - params_length); - if (rc) { - pr_err("%s: send vdhe/vspe params failed with rc=%d\n", - __func__, rc); - rc = -EINVAL; - goto end; - } + packed_param_size += param_size; + + /* Pack VSPE header + data */ + param_hdr.param_id = DOLBY_PARAM_ID_VSPE; + param_size = DOLBY_PARAM_VSPE_LENGTH * sizeof(uint32_t); + param_hdr.param_size = param_size; + + if (is_custom_stereo_enabled) + param_data = NULL; + else + param_data = (u8 *) &ds2_dap_params[cdev] + .params_val[DOLBY_PARAM_VSPE_OFFSET]; + + rc = q6common_pack_pp_params(packed_param_data + packed_param_size, + ¶m_hdr, param_data, ¶m_size); + if (rc) { + pr_err("%s: Failed to pack params, error %d\n", __func__, rc); + goto end; + } + packed_param_size += param_size; + + rc = adm_set_pp_params(dev_map[dev_map_idx].port_id, + dev_map[dev_map_idx].copp_idx, NULL, + packed_param_data, packed_param_size); + if (rc) { + pr_err("%s: send vdhe/vspe params failed with rc=%d\n", + __func__, rc); + rc = -EINVAL; + goto end; } end: - kfree(param_val); + kfree(packed_param_data); return rc; } int qti_set_custom_stereo_on(int port_id, int copp_idx, bool is_custom_stereo_on) { - + struct custom_stereo_param custom_stereo = {0}; + struct param_hdr_v3 param_hdr = {0}; uint16_t op_FL_ip_FL_weight; uint16_t op_FL_ip_FR_weight; uint16_t op_FR_ip_FL_weight; uint16_t op_FR_ip_FR_weight; - - int32_t *update_params_value32 = NULL, rc = 0; - int32_t *param_val = NULL; - int16_t *update_params_value16 = 0; - uint32_t params_length_bytes = CUSTOM_STEREO_PAYLOAD_SIZE * - sizeof(uint32_t); - uint32_t avail_length = params_length_bytes; + int rc = 0; if ((port_id != SLIMBUS_0_RX) && (port_id != RT_PROXY_PORT_001_RX)) { pr_debug("%s:No Custom stereo for port:0x%x\n", __func__, port_id); - goto skip_send_cmd; + return 0; } pr_debug("%s: port 0x%x, copp_idx %d, is_custom_stereo_on %d\n", @@ -349,76 +369,49 @@ int qti_set_custom_stereo_on(int port_id, int copp_idx, op_FR_ip_FR_weight = Q14_GAIN_UNITY; } - update_params_value32 = kzalloc(params_length_bytes, GFP_KERNEL); - if (!update_params_value32) { - pr_err("%s, params memory alloc failed\n", __func__); - rc = -ENOMEM; - goto skip_send_cmd; - } - param_val = update_params_value32; - if (avail_length < 2 * sizeof(uint32_t)) - goto skip_send_cmd; - *update_params_value32++ = MTMX_MODULE_ID_DEFAULT_CHMIXER; - *update_params_value32++ = DEFAULT_CHMIXER_PARAM_ID_COEFF; - avail_length = avail_length - (2 * sizeof(uint32_t)); - - update_params_value16 = (int16_t *)update_params_value32; - if (avail_length < 10 * sizeof(uint16_t)) - goto skip_send_cmd; - *update_params_value16++ = CUSTOM_STEREO_CMD_PARAM_SIZE; - /* for alignment only*/ - *update_params_value16++ = 0; + param_hdr.module_id = MTMX_MODULE_ID_DEFAULT_CHMIXER; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = DEFAULT_CHMIXER_PARAM_ID_COEFF; + param_hdr.param_size = sizeof(struct custom_stereo_param); + /* index is 32-bit param in little endian*/ - *update_params_value16++ = CUSTOM_STEREO_INDEX_PARAM; - *update_params_value16++ = 0; + custom_stereo.index = CUSTOM_STEREO_INDEX_PARAM; + custom_stereo.reserved = 0; /* for stereo mixing num out ch*/ - *update_params_value16++ = CUSTOM_STEREO_NUM_OUT_CH; + custom_stereo.num_out_ch = CUSTOM_STEREO_NUM_OUT_CH; /* for stereo mixing num in ch*/ - *update_params_value16++ = CUSTOM_STEREO_NUM_IN_CH; + custom_stereo.num_in_ch = CUSTOM_STEREO_NUM_IN_CH; /* Out ch map FL/FR*/ - *update_params_value16++ = PCM_CHANNEL_FL; - *update_params_value16++ = PCM_CHANNEL_FR; + custom_stereo.out_fl = PCM_CHANNEL_FL; + custom_stereo.out_fr = PCM_CHANNEL_FR; /* In ch map FL/FR*/ - *update_params_value16++ = PCM_CHANNEL_FL; - *update_params_value16++ = PCM_CHANNEL_FR; - avail_length = avail_length - (10 * sizeof(uint16_t)); + custom_stereo.in_fl = PCM_CHANNEL_FL; + custom_stereo.in_fr = PCM_CHANNEL_FR; + /* weighting coefficients as name suggests, mixing will be done according to these coefficients*/ - if (avail_length < 4 * sizeof(uint16_t)) - goto skip_send_cmd; - *update_params_value16++ = op_FL_ip_FL_weight; - *update_params_value16++ = op_FL_ip_FR_weight; - *update_params_value16++ = op_FR_ip_FL_weight; - *update_params_value16++ = op_FR_ip_FR_weight; - avail_length = avail_length - (4 * sizeof(uint16_t)); - if (params_length_bytes != 0) { - rc = adm_dolby_dap_send_params(port_id, copp_idx, - (char *)param_val, - params_length_bytes); - if (rc) { - pr_err("%s: send params failed rc=%d\n", __func__, rc); - rc = -EINVAL; - goto skip_send_cmd; - } + custom_stereo.op_FL_ip_FL_weight = op_FL_ip_FL_weight; + custom_stereo.op_FL_ip_FR_weight = op_FL_ip_FR_weight; + custom_stereo.op_FR_ip_FL_weight = op_FR_ip_FL_weight; + custom_stereo.op_FR_ip_FR_weight = op_FR_ip_FR_weight; + rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, + (u8 *) &custom_stereo); + if (rc) { + pr_err("%s: send params failed rc=%d\n", __func__, rc); + return -EINVAL; } - kfree(param_val); + return 0; -skip_send_cmd: - pr_err("%s: insufficient memory, send cmd failed\n", - __func__); - kfree(param_val); - return rc; } static int dap_set_custom_stereo_onoff(int dev_map_idx, bool is_custom_stereo_enabled) { + uint32_t enable = is_custom_stereo_enabled ? 1 : 0; + struct param_hdr_v3 param_hdr = {0}; + int rc = 0; - int32_t *update_params_value = NULL, rc = 0; - int32_t *param_val = NULL; - uint32_t params_length_bytes = (TOTAL_LENGTH_DOLBY_PARAM + - DOLBY_PARAM_PAYLOAD_SIZE) * sizeof(uint32_t); if ((dev_map[dev_map_idx].port_id != SLIMBUS_0_RX) && (dev_map[dev_map_idx].port_id != RT_PROXY_PORT_001_RX)) { pr_debug("%s:No Custom stereo for port:0x%x\n", @@ -435,38 +428,21 @@ static int dap_set_custom_stereo_onoff(int dev_map_idx, /* DAP custom stereo */ msm_ds2_dap_set_vspe_vdhe(dev_map_idx, is_custom_stereo_enabled); - update_params_value = kzalloc(params_length_bytes, GFP_KERNEL); - if (!update_params_value) { - pr_err("%s: params memory alloc failed\n", __func__); - rc = -ENOMEM; + param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = DOLBY_ENABLE_CUSTOM_STEREO; + param_hdr.param_size = sizeof(enable); + + rc = adm_pack_and_set_one_pp_param(dev_map[dev_map_idx].port_id, + dev_map[dev_map_idx].copp_idx, + param_hdr, (u8 *) &enable); + if (rc) { + pr_err("%s: set custom stereo enable failed with rc=%d\n", + __func__, rc); + rc = -EINVAL; goto end; } - params_length_bytes = 0; - param_val = update_params_value; - *update_params_value++ = DOLBY_BUNDLE_MODULE_ID; - *update_params_value++ = DOLBY_ENABLE_CUSTOM_STEREO; - *update_params_value++ = sizeof(uint32_t); - if (is_custom_stereo_enabled) - *update_params_value++ = 1; - else - *update_params_value++ = 0; - params_length_bytes += (DOLBY_PARAM_PAYLOAD_SIZE + 1) * - sizeof(uint32_t); - pr_debug("%s: valid param length: %d\n", __func__, params_length_bytes); - if (params_length_bytes) { - rc = adm_dolby_dap_send_params(dev_map[dev_map_idx].port_id, - dev_map[dev_map_idx].copp_idx, - (char *)param_val, - params_length_bytes); - if (rc) { - pr_err("%s: custom stereo param failed with rc=%d\n", - __func__, rc); - rc = -EINVAL; - goto end; - } - } end: - kfree(param_val); return rc; } @@ -654,8 +630,11 @@ static int msm_ds2_dap_init_modules_in_topology(int dev_map_idx) { int rc = 0, i = 0, port_id, copp_idx; /* Account for 32 bit interger allocation */ - int32_t param_sz = (ADM_GET_TOPO_MODULE_LIST_LENGTH / sizeof(uint32_t)); + int32_t param_sz = + (ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH / sizeof(uint32_t)); int32_t *update_param_val = NULL; + struct module_instance_info mod_inst_info = {0}; + int mod_inst_info_sz = 0; if (dev_map_idx < 0 || dev_map_idx >= DS2_DEVICES_ALL) { pr_err("%s: invalid dev map index %d\n", __func__, dev_map_idx); @@ -666,7 +645,8 @@ static int msm_ds2_dap_init_modules_in_topology(int dev_map_idx) port_id = dev_map[dev_map_idx].port_id; copp_idx = dev_map[dev_map_idx].copp_idx; pr_debug("%s: port_id 0x%x copp_idx %d\n", __func__, port_id, copp_idx); - update_param_val = kzalloc(ADM_GET_TOPO_MODULE_LIST_LENGTH, GFP_KERNEL); + update_param_val = + kzalloc(ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH, GFP_KERNEL); if (!update_param_val) { pr_err("%s, param memory alloc failed\n", __func__); rc = -ENOMEM; @@ -675,9 +655,10 @@ static int msm_ds2_dap_init_modules_in_topology(int dev_map_idx) if (!ds2_dap_params_states.dap_bypass) { /* get modules from dsp */ - rc = adm_get_pp_topo_module_list(port_id, copp_idx, - ADM_GET_TOPO_MODULE_LIST_LENGTH, - (char *)update_param_val); + rc = adm_get_pp_topo_module_list_v2( + port_id, copp_idx, + ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH, + update_param_val); if (rc < 0) { pr_err("%s:topo list port %d, err %d,copp_idx %d\n", __func__, port_id, copp_idx, rc); @@ -691,11 +672,15 @@ static int msm_ds2_dap_init_modules_in_topology(int dev_map_idx) rc = -EINVAL; goto end; } + + mod_inst_info_sz = sizeof(struct module_instance_info) / + sizeof(uint32_t); /* Turn off modules */ - for (i = 1; i < update_param_val[0]; i++) { + for (i = 1; i < update_param_val[0] * mod_inst_info_sz; + i += mod_inst_info_sz) { if (!msm_ds2_dap_can_enable_module( - update_param_val[i]) || - (update_param_val[i] == DS2_MODULE_ID)) { + update_param_val[i]) || + (update_param_val[i] == DS2_MODULE_ID)) { pr_debug("%s: Do not enable/disable %d\n", __func__, update_param_val[i]); continue; @@ -703,15 +688,21 @@ static int msm_ds2_dap_init_modules_in_topology(int dev_map_idx) pr_debug("%s: param disable %d\n", __func__, update_param_val[i]); - adm_param_enable(port_id, copp_idx, update_param_val[i], - MODULE_DISABLE); + memcpy(&mod_inst_info, &update_param_val[i], + sizeof(mod_inst_info)); + adm_param_enable_v2(port_id, copp_idx, + mod_inst_info, + MODULE_DISABLE); } } else { msm_ds2_dap_send_cal_data(dev_map_idx); } - adm_param_enable(port_id, copp_idx, DS2_MODULE_ID, - !ds2_dap_params_states.dap_bypass); + + mod_inst_info.module_id = DS2_MODULE_ID; + mod_inst_info.instance_id = INSTANCE_ID_0; + adm_param_enable_v2(port_id, copp_idx, mod_inst_info, + !ds2_dap_params_states.dap_bypass); end: kfree(update_param_val); return rc; @@ -884,17 +875,21 @@ static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data) { int rc = 0, i = 0, j = 0; /*Account for 32 bit interger allocation */ - int32_t param_sz = (ADM_GET_TOPO_MODULE_LIST_LENGTH / sizeof(uint32_t)); + int32_t param_sz = + (ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH / sizeof(uint32_t)); int32_t *mod_list = NULL; int port_id = 0, copp_idx = -1; bool cs_onoff = ds2_dap_params_states.custom_stereo_onoff; int ramp_wait = DOLBY_SOFT_VOLUME_PERIOD; + struct module_instance_info mod_inst_info = {0}; + int mod_inst_info_sz = 0; pr_debug("%s: bypass type %d bypass %d custom stereo %d\n", __func__, ds2_dap_params_states.dap_bypass_type, ds2_dap_params_states.dap_bypass, ds2_dap_params_states.custom_stereo_onoff); - mod_list = kzalloc(ADM_GET_TOPO_MODULE_LIST_LENGTH, GFP_KERNEL); + mod_list = + kzalloc(ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH, GFP_KERNEL); if (!mod_list) { pr_err("%s: param memory alloc failed\n", __func__); rc = -ENOMEM; @@ -921,9 +916,10 @@ static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data) } /* getmodules from dsp */ - rc = adm_get_pp_topo_module_list(port_id, copp_idx, - ADM_GET_TOPO_MODULE_LIST_LENGTH, - (char *)mod_list); + rc = adm_get_pp_topo_module_list_v2( + port_id, copp_idx, + ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH, + mod_list); if (rc < 0) { pr_err("%s:adm get topo list port %d", __func__, port_id); @@ -975,8 +971,11 @@ static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data) /* if dap bypass is set */ if (ds2_dap_params_states.dap_bypass) { /* Turn off dap module */ - adm_param_enable(port_id, copp_idx, - DS2_MODULE_ID, MODULE_DISABLE); + mod_inst_info.module_id = DS2_MODULE_ID; + mod_inst_info.instance_id = INSTANCE_ID_0; + adm_param_enable_v2(port_id, copp_idx, + mod_inst_info, + MODULE_DISABLE); /* * If custom stereo is on at the time of bypass, * switch off custom stereo on dap and turn on @@ -999,8 +998,13 @@ static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data) copp_idx, rc); } } + + mod_inst_info_sz = + sizeof(struct module_instance_info) / + sizeof(uint32_t); /* Turn on qti modules */ - for (j = 1; j < mod_list[0]; j++) { + for (j = 1; j < mod_list[0] * mod_inst_info_sz; + j += mod_inst_info_sz) { if (!msm_ds2_dap_can_enable_module( mod_list[j]) || mod_list[j] == @@ -1008,9 +1012,11 @@ static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data) continue; pr_debug("%s: param enable %d\n", __func__, mod_list[j]); - adm_param_enable(port_id, copp_idx, - mod_list[j], - MODULE_ENABLE); + memcpy(&mod_inst_info, &mod_list[j], + sizeof(mod_inst_info)); + adm_param_enable_v2(port_id, copp_idx, + mod_inst_info, + MODULE_ENABLE); } /* Add adm api to resend calibration on port */ @@ -1025,7 +1031,8 @@ static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data) } } else { /* Turn off qti modules */ - for (j = 1; j < mod_list[0]; j++) { + for (j = 1; j < mod_list[0] * mod_inst_info_sz; + j += mod_inst_info_sz) { if (!msm_ds2_dap_can_enable_module( mod_list[j]) || mod_list[j] == @@ -1033,15 +1040,20 @@ static int msm_ds2_dap_handle_bypass(struct dolby_param_data *dolby_data) continue; pr_debug("%s: param disable %d\n", __func__, mod_list[j]); - adm_param_enable(port_id, copp_idx, - mod_list[j], - MODULE_DISABLE); + memcpy(&mod_inst_info, &mod_list[j], + sizeof(mod_inst_info)); + adm_param_enable_v2(port_id, copp_idx, + mod_inst_info, + MODULE_DISABLE); } /* Enable DAP modules */ pr_debug("%s:DS2 param enable\n", __func__); - adm_param_enable(port_id, copp_idx, - DS2_MODULE_ID, MODULE_ENABLE); + mod_inst_info.module_id = DS2_MODULE_ID; + mod_inst_info.instance_id = INSTANCE_ID_0; + adm_param_enable_v2(port_id, copp_idx, + mod_inst_info, + MODULE_ENABLE); /* * If custom stereo is on at the time of dap on, * switch off custom stereo on qti channel mixer @@ -1100,13 +1112,12 @@ end: static int msm_ds2_dap_send_end_point(int dev_map_idx, int endp_idx) { - int rc = 0; - int32_t *update_params_value = NULL, *params_value = NULL; - uint32_t params_length = (DOLBY_PARAM_INT_ENDP_LENGTH + - DOLBY_PARAM_PAYLOAD_SIZE) * sizeof(uint32_t); + uint32_t offset = 0; + struct param_hdr_v3 param_hdr = {0}; int cache_device = 0; struct ds2_dap_params_s *ds2_ap_params_obj = NULL; int32_t *modified_param = NULL; + int rc = 0; if (dev_map_idx < 0 || dev_map_idx >= DS2_DEVICES_ALL) { pr_err("%s: invalid dev map index %d\n", __func__, dev_map_idx); @@ -1121,13 +1132,6 @@ static int msm_ds2_dap_send_end_point(int dev_map_idx, int endp_idx) pr_debug("%s: endp - %pK %pK\n", __func__, &ds2_dap_params[cache_device], ds2_ap_params_obj); - params_value = kzalloc(params_length, GFP_KERNEL); - if (!params_value) { - pr_err("%s: params memory alloc failed\n", __func__); - rc = -ENOMEM; - goto end; - } - if (dev_map[dev_map_idx].port_id == DOLBY_INVALID_PORT_ID) { pr_err("%s: invalid port\n", __func__); rc = -EINVAL; @@ -1141,21 +1145,20 @@ static int msm_ds2_dap_send_end_point(int dev_map_idx, int endp_idx) goto end; } - update_params_value = params_value; - *update_params_value++ = DOLBY_BUNDLE_MODULE_ID; - *update_params_value++ = DOLBY_PARAM_ID_INIT_ENDP; - *update_params_value++ = DOLBY_PARAM_INT_ENDP_LENGTH * sizeof(uint32_t); - *update_params_value++ = ds2_ap_params_obj->params_val[ - ds2_dap_params_offset[endp_idx]]; + param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = DOLBY_PARAM_ID_INIT_ENDP; + param_hdr.param_size = sizeof(offset); + offset = ds2_ap_params_obj->params_val[ds2_dap_params_offset[endp_idx]]; pr_debug("%s: off %d, length %d\n", __func__, ds2_dap_params_offset[endp_idx], ds2_dap_params_length[endp_idx]); pr_debug("%s: param 0x%x, param val %d\n", __func__, ds2_dap_params_id[endp_idx], ds2_ap_params_obj-> params_val[ds2_dap_params_offset[endp_idx]]); - rc = adm_dolby_dap_send_params(dev_map[dev_map_idx].port_id, - dev_map[dev_map_idx].copp_idx, - (char *)params_value, params_length); + rc = adm_pack_and_set_one_pp_param(dev_map[dev_map_idx].port_id, + dev_map[dev_map_idx].copp_idx, + param_hdr, (u8 *) &offset); if (rc) { pr_err("%s: send dolby params failed rc %d\n", __func__, rc); rc = -EINVAL; @@ -1172,19 +1175,17 @@ static int msm_ds2_dap_send_end_point(int dev_map_idx, int endp_idx) ds2_ap_params_obj->dap_params_modified[endp_idx] = 0x00010001; end: - kfree(params_value); return rc; } static int msm_ds2_dap_send_cached_params(int dev_map_idx, int commit) { - int32_t *update_params_value = NULL, *params_value = NULL; - uint32_t idx, i, j, ret = 0; - uint32_t params_length = (TOTAL_LENGTH_DOLBY_PARAM + - (MAX_DS2_PARAMS - 1) * - DOLBY_PARAM_PAYLOAD_SIZE) * - sizeof(uint32_t); + uint8_t *packed_params = NULL; + uint32_t packed_params_size = 0; + uint32_t param_size = 0; + struct param_hdr_v3 param_hdr = {0}; + uint32_t idx, i, ret = 0; int cache_device = 0; struct ds2_dap_params_s *ds2_ap_params_obj = NULL; int32_t *modified_param = NULL; @@ -1207,12 +1208,16 @@ static int msm_ds2_dap_send_cached_params(int dev_map_idx, pr_debug("%s: cached param - %pK %pK, cache_device %d\n", __func__, &ds2_dap_params[cache_device], ds2_ap_params_obj, cache_device); - params_value = kzalloc(params_length, GFP_KERNEL); - if (!params_value) { - pr_err("%s: params memory alloc failed\n", __func__); - ret = -ENOMEM; - goto end; - } + + /* + * Allocate the max space needed. This is enough space to hold the + * header for each param plus the total size of all the params. + */ + packed_params_size = (sizeof(param_hdr) * (MAX_DS2_PARAMS - 1)) + + (TOTAL_LENGTH_DOLBY_PARAM * sizeof(uint32_t)); + packed_params = kzalloc(packed_params_size, GFP_KERNEL); + if (!packed_params) + return -ENOMEM; if (dev_map[dev_map_idx].port_id == DOLBY_INVALID_PORT_ID) { pr_err("%s: invalid port id\n", __func__); @@ -1227,8 +1232,7 @@ static int msm_ds2_dap_send_cached_params(int dev_map_idx, goto end; } - update_params_value = params_value; - params_length = 0; + packed_params_size = 0; for (i = 0; i < (MAX_DS2_PARAMS-1); i++) { /*get the pointer to the param modified array in the cache*/ modified_param = ds2_ap_params_obj->dap_params_modified; @@ -1241,28 +1245,33 @@ static int msm_ds2_dap_send_cached_params(int dev_map_idx, if (!msm_ds2_dap_check_is_param_modified(modified_param, i, commit)) continue; - *update_params_value++ = DOLBY_BUNDLE_MODULE_ID; - *update_params_value++ = ds2_dap_params_id[i]; - *update_params_value++ = ds2_dap_params_length[i] * - sizeof(uint32_t); + + param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = ds2_dap_params_id[i]; + param_hdr.param_size = + ds2_dap_params_length[i] * sizeof(uint32_t); + idx = ds2_dap_params_offset[i]; - for (j = 0; j < ds2_dap_params_length[i]; j++) { - *update_params_value++ = - ds2_ap_params_obj->params_val[idx+j]; - pr_debug("%s: id 0x%x,val %d\n", __func__, - ds2_dap_params_id[i], - ds2_ap_params_obj->params_val[idx+j]); + ret = q6common_pack_pp_params( + packed_params + packed_params_size, ¶m_hdr, + (u8 *) &ds2_ap_params_obj->params_val[idx], + ¶m_size); + if (ret) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, ret); + goto end; } - params_length += (DOLBY_PARAM_PAYLOAD_SIZE + - ds2_dap_params_length[i]) * sizeof(uint32_t); + + packed_params_size += param_size; } - pr_debug("%s: valid param length: %d\n", __func__, params_length); - if (params_length) { - ret = adm_dolby_dap_send_params(dev_map[dev_map_idx].port_id, - dev_map[dev_map_idx].copp_idx, - (char *)params_value, - params_length); + pr_debug("%s: total packed param length: %d\n", __func__, + packed_params_size); + if (packed_params_size) { + ret = adm_set_pp_params(dev_map[dev_map_idx].port_id, + dev_map[dev_map_idx].copp_idx, NULL, + packed_params, packed_params_size); if (ret) { pr_err("%s: send dolby params failed ret %d\n", __func__, ret); @@ -1285,7 +1294,7 @@ static int msm_ds2_dap_send_cached_params(int dev_map_idx, } } end: - kfree(params_value); + kfree(packed_params); return ret; } @@ -1522,11 +1531,12 @@ static int msm_ds2_dap_get_param(u32 cmd, void *arg) { int rc = 0, i, port_id = 0, copp_idx = -1; struct dolby_param_data *dolby_data = (struct dolby_param_data *)arg; - int32_t *update_params_value = NULL, *params_value = NULL; + int32_t *params_value = NULL; uint32_t params_length = DOLBY_MAX_LENGTH_INDIVIDUAL_PARAM * sizeof(uint32_t); uint32_t param_payload_len = DOLBY_PARAM_PAYLOAD_SIZE * sizeof(uint32_t); + struct param_hdr_v3 param_hdr; /* Return error on get param in soft or hard bypass */ if (ds2_dap_params_states.dap_bypass == true) { @@ -1572,18 +1582,14 @@ static int msm_ds2_dap_get_param(u32 cmd, void *arg) params_value = kzalloc(params_length + param_payload_len, GFP_KERNEL); - if (!params_value) { - pr_err("%s: params memory alloc failed\n", __func__); - rc = -ENOMEM; - goto end; - } + if (!params_value) + return -ENOMEM; if (dolby_data->param_id == DOLBY_PARAM_ID_VER) { - rc = adm_get_params(port_id, copp_idx, - DOLBY_BUNDLE_MODULE_ID, - DOLBY_PARAM_ID_VER, - params_length + param_payload_len, - (char *)params_value); + param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = DOLBY_PARAM_ID_VER; + param_hdr.param_size = params_length + param_payload_len; } else { for (i = 0; i < MAX_DS2_PARAMS; i++) if (ds2_dap_params_id[i] == @@ -1596,25 +1602,25 @@ static int msm_ds2_dap_get_param(u32 cmd, void *arg) goto end; } else { params_length = - ds2_dap_params_length[i] * sizeof(uint32_t); + ds2_dap_params_length[i] * sizeof(uint32_t); - rc = adm_get_params(port_id, copp_idx, - DOLBY_BUNDLE_MODULE_ID, - ds2_dap_params_id[i], - params_length + - param_payload_len, - (char *)params_value); + param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = ds2_dap_params_id[i]; + param_hdr.param_size = + params_length + param_payload_len; } } + rc = adm_get_pp_params(port_id, copp_idx, ADM_CLIENT_ID_DEFAULT, NULL, + ¶m_hdr, (u8 *) params_value); if (rc) { pr_err("%s: get parameters failed rc %d\n", __func__, rc); rc = -EINVAL; goto end; } - update_params_value = params_value; - if (copy_to_user((void *)dolby_data->data, - &update_params_value[DOLBY_PARAM_PAYLOAD_SIZE], - (dolby_data->length * sizeof(uint32_t)))) { + if (copy_to_user((void __user *) dolby_data->data, + ¶ms_value[DOLBY_PARAM_PAYLOAD_SIZE], + (dolby_data->length * sizeof(uint32_t)))) { pr_err("%s: error getting param\n", __func__); rc = -EFAULT; goto end; @@ -1633,6 +1639,7 @@ static int msm_ds2_dap_param_visualizer_control_get(u32 cmd, void *arg) uint32_t offset, length, params_length; uint32_t param_payload_len = DOLBY_PARAM_PAYLOAD_SIZE * sizeof(uint32_t); + struct param_hdr_v3 param_hdr = {0}; for (i = 0; i < DS2_DEVICES_ALL; i++) { if ((dev_map[i].active)) { @@ -1683,11 +1690,13 @@ static int msm_ds2_dap_param_visualizer_control_get(u32 cmd, void *arg) offset = 0; params_length = length * sizeof(uint32_t); - ret = adm_get_params(port_id, copp_idx, - DOLBY_BUNDLE_MODULE_ID, - DOLBY_PARAM_ID_VCBG, - params_length + param_payload_len, - (((char *)(visualizer_data)) + offset)); + param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = DOLBY_PARAM_ID_VCBG; + param_hdr.param_size = length * sizeof(uint32_t) + param_payload_len; + ret = adm_get_pp_params(port_id, copp_idx, ADM_CLIENT_ID_DEFAULT, NULL, + ¶m_hdr, + (((char *) (visualizer_data)) + offset)); if (ret) { pr_err("%s: get parameters failed ret %d\n", __func__, ret); ret = -EINVAL; @@ -1695,11 +1704,13 @@ static int msm_ds2_dap_param_visualizer_control_get(u32 cmd, void *arg) goto end; } offset = length * sizeof(uint32_t); - ret = adm_get_params(port_id, copp_idx, - DOLBY_BUNDLE_MODULE_ID, - DOLBY_PARAM_ID_VCBE, - params_length + param_payload_len, - (((char *)(visualizer_data)) + offset)); + param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = DOLBY_PARAM_ID_VCBE; + param_hdr.param_size = length * sizeof(uint32_t) + param_payload_len; + ret = adm_get_pp_params(port_id, copp_idx, ADM_CLIENT_ID_DEFAULT, NULL, + ¶m_hdr, + (((char *) (visualizer_data)) + offset)); if (ret) { pr_err("%s: get parameters failed ret %d\n", __func__, ret); ret = -EINVAL; diff --git a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.h b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.h index 0eb6017fd383..c2687017c962 100644 --- a/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.h +++ b/sound/soc/msm/qdsp6v2/msm-ds2-dap-config.h @@ -1,4 +1,5 @@ -/* Copyright (c) 2013-2014, 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2014, 2016-2017, The Linux Foundation. All rights + * reserved. * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and * only version 2 as published by the Free Software Foundation. @@ -32,7 +33,6 @@ struct dolby_param_license32 { compat_uptr_t license_key; }; - #define SNDRV_DEVDEP_DAP_IOCTL_SET_PARAM32\ _IOWR('U', 0x10, struct dolby_param_data32) #define SNDRV_DEVDEP_DAP_IOCTL_GET_PARAM32\ @@ -62,6 +62,34 @@ enum { DAP_CMD_SET_BYPASS_TYPE = 5, }; +struct custom_stereo_param { + /* Index is 32-bit param in little endian */ + u16 index; + u16 reserved; + + /* For stereo mixing, the number of out channels */ + u16 num_out_ch; + /* For stereo mixing, the number of in channels */ + u16 num_in_ch; + + /* Out channel map FL/FR*/ + u16 out_fl; + u16 out_fr; + + /* In channel map FL/FR*/ + u16 in_fl; + u16 in_fr; + + /* + * Weighting coefficients. Mixing will be done according to + * these coefficients. + */ + u16 op_FL_ip_FL_weight; + u16 op_FL_ip_FR_weight; + u16 op_FR_ip_FL_weight; + u16 op_FR_ip_FR_weight; +}; + #define DOLBY_PARAM_INT_ENDP_LENGTH 1 #define DOLBY_PARAM_INT_ENDP_OFFSET (DOLBY_PARAM_PSTG_OFFSET + \ DOLBY_PARAM_PSTG_LENGTH) diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c index 13eb97ae3660..2dba05df40e0 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c @@ -11384,22 +11384,23 @@ int msm_routing_get_rms_value_control(struct snd_kcontrol *kcontrol, int be_idx = 0; char *param_value; int *update_param_value; - uint32_t param_length = sizeof(uint32_t); - uint32_t param_payload_len = RMS_PAYLOAD_LEN * sizeof(uint32_t); - param_value = kzalloc(param_length + param_payload_len, GFP_KERNEL); - if (!param_value) { - pr_err("%s, param memory alloc failed\n", __func__); + uint32_t param_size = (RMS_PAYLOAD_LEN + 1) * sizeof(uint32_t); + struct param_hdr_v3 param_hdr = {0}; + + param_value = kzalloc(param_size, GFP_KERNEL); + if (!param_value) return -ENOMEM; - } + for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++) if (msm_bedais[be_idx].port_id == SLIMBUS_0_TX) break; if ((be_idx < MSM_BACKEND_DAI_MAX) && msm_bedais[be_idx].active) { - rc = adm_get_params(SLIMBUS_0_TX, 0, - RMS_MODULEID_APPI_PASSTHRU, - RMS_PARAM_FIRST_SAMPLE, - param_length + param_payload_len, - param_value); + param_hdr.module_id = RMS_MODULEID_APPI_PASSTHRU; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = RMS_PARAM_FIRST_SAMPLE; + param_hdr.param_size = param_size; + rc = adm_get_pp_params(SLIMBUS_0_TX, 0, ADM_CLIENT_ID_DEFAULT, + NULL, ¶m_hdr, (u8 *) param_value); if (rc) { pr_err("%s: get parameters failed:%d\n", __func__, rc); kfree(param_value); diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c index f3ec45b8f9b1..76d8f8d9e33c 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-voice-v2.c @@ -556,12 +556,14 @@ static int msm_voice_slowtalk_put(struct snd_kcontrol *kcontrol, { int st_enable = ucontrol->value.integer.value[0]; uint32_t session_id = ucontrol->value.integer.value[1]; + struct module_instance_info mod_inst_info = {0}; pr_debug("%s: st enable=%d session_id=%#x\n", __func__, st_enable, session_id); - voc_set_pp_enable(session_id, - MODULE_ID_VOICE_MODULE_ST, st_enable); + mod_inst_info.module_id = MODULE_ID_VOICE_MODULE_ST; + mod_inst_info.instance_id = INSTANCE_ID_0; + voc_set_pp_enable(session_id, mod_inst_info, st_enable); return 0; } diff --git a/sound/soc/msm/qdsp6v2/msm-qti-pp-config.c b/sound/soc/msm/qdsp6v2/msm-qti-pp-config.c index 65f5167d9dee..bcfb090d556b 100644 --- a/sound/soc/msm/qdsp6v2/msm-qti-pp-config.c +++ b/sound/soc/msm/qdsp6v2/msm-qti-pp-config.c @@ -18,6 +18,7 @@ #include <sound/q6adm-v2.h> #include <sound/q6asm-v2.h> #include <sound/q6afe-v2.h> +#include <sound/q6common.h> #include <sound/asound.h> #include <sound/q6audio-v2.h> #include <sound/tlv.h> @@ -327,14 +328,13 @@ static int msm_qti_pp_get_rms_value_control(struct snd_kcontrol *kcontrol, int be_idx = 0, copp_idx; char *param_value; int *update_param_value; - uint32_t param_length = sizeof(uint32_t); - uint32_t param_payload_len = RMS_PAYLOAD_LEN * sizeof(uint32_t); + uint32_t param_size = (RMS_PAYLOAD_LEN + 1) * sizeof(uint32_t); struct msm_pcm_routing_bdai_data msm_bedai; - param_value = kzalloc(param_length + param_payload_len, GFP_KERNEL); - if (!param_value) { - pr_err("%s, param memory alloc failed\n", __func__); + struct param_hdr_v3 param_hdr = {0}; + + param_value = kzalloc(param_size, GFP_KERNEL); + if (!param_value) return -ENOMEM; - } msm_pcm_routing_acquire_lock(); for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++) { msm_pcm_routing_get_bedai_info(be_idx, &msm_bedai); @@ -354,11 +354,12 @@ static int msm_qti_pp_get_rms_value_control(struct snd_kcontrol *kcontrol, rc = -EINVAL; goto get_rms_value_err; } - rc = adm_get_params(SLIMBUS_0_TX, copp_idx, - RMS_MODULEID_APPI_PASSTHRU, - RMS_PARAM_FIRST_SAMPLE, - param_length + param_payload_len, - param_value); + param_hdr.module_id = RMS_MODULEID_APPI_PASSTHRU; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = RMS_PARAM_FIRST_SAMPLE; + param_hdr.param_size = param_size; + rc = adm_get_pp_params(SLIMBUS_0_TX, copp_idx, ADM_CLIENT_ID_DEFAULT, + NULL, ¶m_hdr, param_value); if (rc) { pr_err("%s: get parameters failed rc=%d\n", __func__, rc); rc = -EINVAL; @@ -655,64 +656,82 @@ static void msm_qti_pp_asphere_init_state(void) static int msm_qti_pp_asphere_send_params(int port_id, int copp_idx, bool force) { - char *params_value = NULL; - uint32_t *update_params_value = NULL; - uint32_t param_size = sizeof(uint32_t) + - sizeof(struct adm_param_data_v5); - int params_length = 0, param_count = 0, ret = 0; + u8 *packed_params = NULL; + u32 packed_params_size = 0; + u32 param_size = 0; + struct param_hdr_v3 param_hdr = {0}; bool set_enable = force || (asphere_state.enabled != asphere_state.enabled_prev); bool set_strength = asphere_state.enabled == 1 && (set_enable || (asphere_state.strength != asphere_state.strength_prev)); + int param_count = 0; + int ret = 0; if (set_enable) param_count++; if (set_strength) param_count++; - params_length = param_count * param_size; + + if (param_count == 0) { + pr_debug("%s: Nothing to send, exiting\n", __func__); + return 0; + } pr_debug("%s: port_id %d, copp_id %d, forced %d, param_count %d\n", - __func__, port_id, copp_idx, force, param_count); + __func__, port_id, copp_idx, force, param_count); pr_debug("%s: enable prev:%u cur:%u, strength prev:%u cur:%u\n", __func__, asphere_state.enabled_prev, asphere_state.enabled, asphere_state.strength_prev, asphere_state.strength); - if (params_length > 0) - params_value = kzalloc(params_length, GFP_KERNEL); - if (!params_value) { - pr_err("%s, params memory alloc failed\n", __func__); + packed_params_size = + param_count * (sizeof(struct param_hdr_v3) + sizeof(uint32_t)); + packed_params = kzalloc(packed_params_size, GFP_KERNEL); + if (!packed_params) return -ENOMEM; - } - update_params_value = (uint32_t *)params_value; - params_length = 0; + + packed_params_size = 0; + param_hdr.module_id = AUDPROC_MODULE_ID_AUDIOSPHERE; + param_hdr.instance_id = INSTANCE_ID_0; if (set_strength) { /* add strength command */ - *update_params_value++ = AUDPROC_MODULE_ID_AUDIOSPHERE; - *update_params_value++ = AUDPROC_PARAM_ID_AUDIOSPHERE_STRENGTH; - *update_params_value++ = sizeof(uint32_t); - *update_params_value++ = asphere_state.strength; - params_length += param_size; + param_hdr.param_id = AUDPROC_PARAM_ID_AUDIOSPHERE_STRENGTH; + param_hdr.param_size = sizeof(asphere_state.strength); + ret = q6common_pack_pp_params(packed_params + + packed_params_size, + ¶m_hdr, + (u8 *) &asphere_state.strength, + ¶m_size); + if (ret) { + pr_err("%s: Failed to pack params, error %d\n", + __func__, ret); + goto done; + } + packed_params_size += param_size; } if (set_enable) { /* add enable command */ - *update_params_value++ = AUDPROC_MODULE_ID_AUDIOSPHERE; - *update_params_value++ = AUDPROC_PARAM_ID_AUDIOSPHERE_ENABLE; - *update_params_value++ = sizeof(uint32_t); - *update_params_value++ = asphere_state.enabled; - params_length += param_size; - } - pr_debug("%s, param length: %d\n", __func__, params_length); - if (params_length) { - ret = adm_send_params_v5(port_id, copp_idx, - params_value, params_length); + param_hdr.param_id = AUDPROC_PARAM_ID_AUDIOSPHERE_ENABLE; + param_hdr.param_size = sizeof(asphere_state.enabled); + q6common_pack_pp_params(packed_params + packed_params_size, + ¶m_hdr, + (u8 *) &asphere_state.enabled, + ¶m_size); if (ret) { - pr_err("%s: setting param failed with err=%d\n", - __func__, ret); - kfree(params_value); - return -EINVAL; + pr_err("%s: Failed to pack params, error %d\n", + __func__, ret); + goto done; } + packed_params_size += param_size; } - kfree(params_value); + + pr_debug("%s: packed data size: %d\n", __func__, packed_params_size); + ret = adm_set_pp_params(port_id, copp_idx, NULL, packed_params, + packed_params_size); + if (ret) + pr_err("%s: set param failed with err=%d\n", __func__, ret); + +done: + kfree(packed_params); return 0; } diff --git a/sound/soc/msm/qdsp6v2/q6adm.c b/sound/soc/msm/qdsp6v2/q6adm.c index 018681309f2e..dc66c5ad93d5 100644 --- a/sound/soc/msm/qdsp6v2/q6adm.c +++ b/sound/soc/msm/qdsp6v2/q6adm.c @@ -22,6 +22,7 @@ #include <sound/q6adm-v2.h> #include <sound/q6audio-v2.h> #include <sound/q6afe-v2.h> +#include <sound/q6common.h> #include <sound/audio_cal_utils.h> #include <sound/asound.h> #include "msm-dts-srs-tm-config.h" @@ -32,8 +33,8 @@ #define RESET_COPP_ID 99 #define INVALID_COPP_ID 0xFF /* Used for inband payload copy, max size is 4k */ -/* 2 is to account for module & param ID in payload */ -#define ADM_GET_PARAMETER_LENGTH (4096 - APR_HDR_SIZE - 2 * sizeof(uint32_t)) +/* 3 is to account for module, instance & param ID in payload */ +#define ADM_GET_PARAMETER_LENGTH (4096 - APR_HDR_SIZE - 3 * sizeof(uint32_t)) #define ULL_SUPPORTED_BITS_PER_SAMPLE 16 #define ULL_SUPPORTED_SAMPLE_RATE 48000 @@ -119,8 +120,8 @@ static struct adm_multi_ch_map multi_ch_maps[2] = { }; static int adm_get_parameters[MAX_COPPS_PER_PORT * ADM_GET_PARAMETER_LENGTH]; -static int adm_module_topo_list[ - MAX_COPPS_PER_PORT * ADM_GET_TOPO_MODULE_LIST_LENGTH]; +static int adm_module_topo_list[MAX_COPPS_PER_PORT * + ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH]; int adm_validate_and_get_port_index(int port_id) { @@ -258,10 +259,12 @@ static int adm_get_next_available_copp(int port_idx) int srs_trumedia_open(int port_id, int copp_idx, __s32 srs_tech_id, void *srs_params) { - struct adm_cmd_set_pp_params_inband_v5 *adm_params = NULL; - struct adm_cmd_set_pp_params_v5 *adm_params_ = NULL; - __s32 sz = 0, param_id, module_id = SRS_TRUMEDIA_MODULE_ID, outband = 0; - int ret = 0, port_idx; + struct param_hdr_v3 param_hdr = {0}; + struct mem_mapping_hdr mem_hdr = {0}; + u32 total_param_size = 0; + bool outband = false; + int port_idx; + int ret = 0; pr_debug("SRS - %s", __func__); @@ -271,246 +274,92 @@ int srs_trumedia_open(int port_id, int copp_idx, __s32 srs_tech_id, pr_err("%s: Invalid port_id %#x\n", __func__, port_id); return -EINVAL; } + + param_hdr.module_id = SRS_TRUMEDIA_MODULE_ID; + param_hdr.instance_id = INSTANCE_ID_0; + switch (srs_tech_id) { case SRS_ID_GLOBAL: { - struct srs_trumedia_params_GLOBAL *glb_params = NULL; - sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) + + param_hdr.param_id = SRS_TRUMEDIA_PARAMS; + param_hdr.param_size = sizeof(struct srs_trumedia_params_GLOBAL); - adm_params = kzalloc(sz, GFP_KERNEL); - if (!adm_params) { - pr_err("%s, adm params memory alloc failed\n", - __func__); - return -ENOMEM; - } - adm_params->payload_size = - sizeof(struct srs_trumedia_params_GLOBAL) + - sizeof(struct adm_param_data_v5); - param_id = SRS_TRUMEDIA_PARAMS; - adm_params->params.param_size = - sizeof(struct srs_trumedia_params_GLOBAL); - glb_params = (struct srs_trumedia_params_GLOBAL *) - ((u8 *)adm_params + - sizeof(struct adm_cmd_set_pp_params_inband_v5)); - memcpy(glb_params, srs_params, - sizeof(struct srs_trumedia_params_GLOBAL)); break; } case SRS_ID_WOWHD: { - struct srs_trumedia_params_WOWHD *whd_params = NULL; - sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) + - sizeof(struct srs_trumedia_params_WOWHD); - adm_params = kzalloc(sz, GFP_KERNEL); - if (!adm_params) { - pr_err("%s, adm params memory alloc failed\n", - __func__); - return -ENOMEM; - } - adm_params->payload_size = - sizeof(struct srs_trumedia_params_WOWHD) + - sizeof(struct adm_param_data_v5); - param_id = SRS_TRUMEDIA_PARAMS_WOWHD; - adm_params->params.param_size = - sizeof(struct srs_trumedia_params_WOWHD); - whd_params = (struct srs_trumedia_params_WOWHD *) - ((u8 *)adm_params + - sizeof(struct adm_cmd_set_pp_params_inband_v5)); - memcpy(whd_params, srs_params, - sizeof(struct srs_trumedia_params_WOWHD)); + param_hdr.param_id = SRS_TRUMEDIA_PARAMS_WOWHD; + param_hdr.param_size = sizeof(struct srs_trumedia_params_WOWHD); break; } case SRS_ID_CSHP: { - struct srs_trumedia_params_CSHP *chp_params = NULL; - sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) + - sizeof(struct srs_trumedia_params_CSHP); - adm_params = kzalloc(sz, GFP_KERNEL); - if (!adm_params) { - pr_err("%s, adm params memory alloc failed\n", - __func__); - return -ENOMEM; - } - adm_params->payload_size = - sizeof(struct srs_trumedia_params_CSHP) + - sizeof(struct adm_param_data_v5); - param_id = SRS_TRUMEDIA_PARAMS_CSHP; - adm_params->params.param_size = - sizeof(struct srs_trumedia_params_CSHP); - chp_params = (struct srs_trumedia_params_CSHP *) - ((u8 *)adm_params + - sizeof(struct adm_cmd_set_pp_params_inband_v5)); - memcpy(chp_params, srs_params, - sizeof(struct srs_trumedia_params_CSHP)); + param_hdr.param_id = SRS_TRUMEDIA_PARAMS_CSHP; + param_hdr.param_size = sizeof(struct srs_trumedia_params_CSHP); break; } case SRS_ID_HPF: { - struct srs_trumedia_params_HPF *hpf_params = NULL; - sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) + - sizeof(struct srs_trumedia_params_HPF); - adm_params = kzalloc(sz, GFP_KERNEL); - if (!adm_params) { - pr_err("%s, adm params memory alloc failed\n", - __func__); - return -ENOMEM; - } - adm_params->payload_size = - sizeof(struct srs_trumedia_params_HPF) + - sizeof(struct adm_param_data_v5); - param_id = SRS_TRUMEDIA_PARAMS_HPF; - adm_params->params.param_size = - sizeof(struct srs_trumedia_params_HPF); - hpf_params = (struct srs_trumedia_params_HPF *) - ((u8 *)adm_params + - sizeof(struct adm_cmd_set_pp_params_inband_v5)); - memcpy(hpf_params, srs_params, - sizeof(struct srs_trumedia_params_HPF)); + param_hdr.param_id = SRS_TRUMEDIA_PARAMS_HPF; + param_hdr.param_size = sizeof(struct srs_trumedia_params_HPF); break; } case SRS_ID_AEQ: { - int *update_params_ptr = (int *)this_adm.outband_memmap.kvaddr; - outband = 1; - adm_params = kzalloc(sizeof(struct adm_cmd_set_pp_params_v5), - GFP_KERNEL); - adm_params_ = (struct adm_cmd_set_pp_params_v5 *)adm_params; - if (!adm_params_) { - pr_err("%s, adm params memory alloc failed\n", - __func__); - return -ENOMEM; - } + u8 *update_params_ptr = (u8 *) this_adm.outband_memmap.kvaddr; + + outband = true; - sz = sizeof(struct srs_trumedia_params_AEQ); if (update_params_ptr == NULL) { pr_err("ADM_SRS_TRUMEDIA - %s: null memmap for AEQ params\n", __func__); ret = -EINVAL; goto fail_cmd; } - param_id = SRS_TRUMEDIA_PARAMS_AEQ; - *update_params_ptr++ = module_id; - *update_params_ptr++ = param_id; - *update_params_ptr++ = sz; - memcpy(update_params_ptr, srs_params, sz); - adm_params_->payload_size = sz + 12; + param_hdr.param_id = SRS_TRUMEDIA_PARAMS_AEQ; + param_hdr.param_size = sizeof(struct srs_trumedia_params_AEQ); + ret = q6common_pack_pp_params(update_params_ptr, ¶m_hdr, + srs_params, &total_param_size); + if (ret) { + pr_err("%s: Failed to pack param header and data, error %d\n", + __func__, ret); + goto fail_cmd; + } break; } case SRS_ID_HL: { - struct srs_trumedia_params_HL *hl_params = NULL; - sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) + - sizeof(struct srs_trumedia_params_HL); - adm_params = kzalloc(sz, GFP_KERNEL); - if (!adm_params) { - pr_err("%s, adm params memory alloc failed\n", - __func__); - return -ENOMEM; - } - adm_params->payload_size = - sizeof(struct srs_trumedia_params_HL) + - sizeof(struct adm_param_data_v5); - param_id = SRS_TRUMEDIA_PARAMS_HL; - adm_params->params.param_size = - sizeof(struct srs_trumedia_params_HL); - hl_params = (struct srs_trumedia_params_HL *) - ((u8 *)adm_params + - sizeof(struct adm_cmd_set_pp_params_inband_v5)); - memcpy(hl_params, srs_params, - sizeof(struct srs_trumedia_params_HL)); + param_hdr.param_id = SRS_TRUMEDIA_PARAMS_HL; + param_hdr.param_size = sizeof(struct srs_trumedia_params_HL); break; } case SRS_ID_GEQ: { - struct srs_trumedia_params_GEQ *geq_params = NULL; - sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) + - sizeof(struct srs_trumedia_params_GEQ); - adm_params = kzalloc(sz, GFP_KERNEL); - if (!adm_params) { - pr_err("%s, adm params memory alloc failed\n", - __func__); - return -ENOMEM; - } - adm_params->payload_size = - sizeof(struct srs_trumedia_params_GEQ) + - sizeof(struct adm_param_data_v5); - param_id = SRS_TRUMEDIA_PARAMS_GEQ; - adm_params->params.param_size = - sizeof(struct srs_trumedia_params_GEQ); - geq_params = (struct srs_trumedia_params_GEQ *) - ((u8 *)adm_params + - sizeof(struct adm_cmd_set_pp_params_inband_v5)); - memcpy(geq_params, srs_params, - sizeof(struct srs_trumedia_params_GEQ)); - pr_debug("SRS - %s: GEQ params prepared\n", __func__); + param_hdr.param_id = SRS_TRUMEDIA_PARAMS_GEQ; + param_hdr.param_size = sizeof(struct srs_trumedia_params_GEQ); break; } default: goto fail_cmd; } - adm_params->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - 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_idx][copp_idx]); - adm_params->hdr.token = port_idx << 16 | copp_idx; - adm_params->hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; if (outband && this_adm.outband_memmap.paddr) { - adm_params->hdr.pkt_size = - sizeof(struct adm_cmd_set_pp_params_v5); - adm_params->payload_addr_lsw = lower_32_bits( - this_adm.outband_memmap.paddr); - adm_params->payload_addr_msw = msm_audio_populate_upper_32_bits( - this_adm.outband_memmap.paddr); - adm_params->mem_map_handle = atomic_read(&this_adm. - mem_map_handles[ADM_SRS_TRUMEDIA]); + mem_hdr.data_payload_addr_lsw = + lower_32_bits(this_adm.outband_memmap.paddr); + mem_hdr.data_payload_addr_msw = + msm_audio_populate_upper_32_bits( + this_adm.outband_memmap.paddr); + mem_hdr.mem_map_handle = atomic_read( + &this_adm.mem_map_handles[ADM_SRS_TRUMEDIA]); + + ret = adm_set_pp_params(port_id, copp_idx, &mem_hdr, NULL, + total_param_size); } else { - adm_params->hdr.pkt_size = sz; - adm_params->payload_addr_lsw = 0; - adm_params->payload_addr_msw = 0; - adm_params->mem_map_handle = 0; - - adm_params->params.module_id = module_id; - adm_params->params.param_id = param_id; - adm_params->params.reserved = 0; + ret = adm_pack_and_set_one_pp_param(port_id, copp_idx, + param_hdr, + (u8 *) srs_params); } - pr_debug("SRS - %s: Command was sent now check Q6 - port id = %d, size %d, module id %x, param id %x.\n", - __func__, adm_params->hdr.dest_port, - adm_params->payload_size, module_id, param_id); - - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - ret = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params); - if (ret < 0) { + if (ret < 0) pr_err("SRS - %s: ADM enable for port %d failed\n", __func__, port_id); - ret = -EINVAL; - goto fail_cmd; - } - /* 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 - [port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: SRS set params timed out port = %d\n", - __func__, port_id); - ret = -EINVAL; - goto fail_cmd; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto fail_cmd; - } fail_cmd: - kfree(adm_params); return ret; } @@ -570,7 +419,7 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, int channel_index) { struct adm_cmd_set_pspd_mtmx_strtr_params_v5 *adm_params = NULL; - struct adm_param_data_v5 data_v5; + struct param_hdr_v3 data_v5; int ret = 0, port_idx, sz = 0, param_size = 0; u16 *adm_pspd_params; u16 *ptr; @@ -602,8 +451,8 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, roundup(param_size, 4); sz = sizeof(struct adm_cmd_set_pspd_mtmx_strtr_params_v5) + - sizeof(struct default_chmixer_param_id_coeff) + - sizeof(struct adm_param_data_v5) + param_size; + sizeof(struct default_chmixer_param_id_coeff) + + sizeof(struct param_hdr_v3) + param_size; pr_debug("%s: sz = %d\n", __func__, sz); adm_params = kzalloc(sz, GFP_KERNEL); if (!adm_params) @@ -626,8 +475,8 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id, data_v5.reserved = 0; data_v5.param_size = param_size; adm_params->payload_size = - sizeof(struct default_chmixer_param_id_coeff) + - sizeof(struct adm_param_data_v5) + data_v5.param_size; + sizeof(struct default_chmixer_param_id_coeff) + + sizeof(struct param_hdr_v3) + data_v5.param_size; adm_pspd_params = (u16 *)((u8 *)adm_params + sizeof(struct adm_cmd_set_pspd_mtmx_strtr_params_v5)); memcpy(adm_pspd_params, &data_v5, sizeof(data_v5)); @@ -861,286 +710,267 @@ set_stereo_to_custom_stereo_return: return rc; } -int adm_dolby_dap_send_params(int port_id, int copp_idx, char *params, - uint32_t params_length) +/* + * With pre-packed data, only the opcode differes from V5 and V6. + * Use q6common_pack_pp_params to pack the data correctly. + */ +int adm_set_pp_params(int port_id, int copp_idx, + struct mem_mapping_hdr *mem_hdr, u8 *param_data, + u32 param_size) { - struct adm_cmd_set_pp_params_v5 *adm_params = NULL; - int sz, rc = 0; - int port_idx; + struct adm_cmd_set_pp_params *adm_set_params = NULL; + int size = sizeof(struct adm_cmd_set_pp_params); + int port_idx = 0; + atomic_t *copp_stat = NULL; + int ret = 0; - pr_debug("%s:\n", __func__); port_id = afe_convert_virtual_to_portid(port_id); port_idx = adm_validate_and_get_port_index(port_id); - if (port_idx < 0) { - pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); + if (port_idx < 0 || port_idx >= AFE_MAX_PORTS) { + pr_err("%s: Invalid port_idx 0x%x\n", __func__, port_idx); + return -EINVAL; + } else if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + pr_err("%s: Invalid copp_idx 0x%x\n", __func__, copp_idx); return -EINVAL; } - sz = sizeof(struct adm_cmd_set_pp_params_v5) + params_length; - adm_params = kzalloc(sz, GFP_KERNEL); - if (!adm_params) { - pr_err("%s, adm params memory alloc failed", __func__); + /* Only add params_size in inband case */ + if (param_data != NULL) + size += param_size; + adm_set_params = kzalloc(size, GFP_KERNEL); + if (!adm_set_params) return -ENOMEM; - } - memcpy(((u8 *)adm_params + sizeof(struct adm_cmd_set_pp_params_v5)), - params, params_length); - adm_params->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - adm_params->hdr.pkt_size = sz; - 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_idx][copp_idx]); - adm_params->hdr.token = port_idx << 16 | copp_idx; - adm_params->hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - adm_params->payload_addr_lsw = 0; - adm_params->payload_addr_msw = 0; - adm_params->mem_map_handle = 0; - adm_params->payload_size = params_length; + adm_set_params->apr_hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + adm_set_params->apr_hdr.pkt_size = size; + adm_set_params->apr_hdr.src_svc = APR_SVC_ADM; + adm_set_params->apr_hdr.src_domain = APR_DOMAIN_APPS; + adm_set_params->apr_hdr.src_port = port_id; + adm_set_params->apr_hdr.dest_svc = APR_SVC_ADM; + adm_set_params->apr_hdr.dest_domain = APR_DOMAIN_ADSP; + adm_set_params->apr_hdr.dest_port = + atomic_read(&this_adm.copp.id[port_idx][copp_idx]); + adm_set_params->apr_hdr.token = port_idx << 16 | copp_idx; + + if (q6common_is_instance_id_supported()) + adm_set_params->apr_hdr.opcode = ADM_CMD_SET_PP_PARAMS_V6; + else + adm_set_params->apr_hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; + + adm_set_params->payload_size = param_size; + + if (mem_hdr != NULL) { + /* Out of Band Case */ + adm_set_params->mem_hdr = *mem_hdr; + } else if (param_data != NULL) { + /* In band case. Parameter data must be pre-packed with its + * header before calling this function. Use + * q6common_pack_pp_params to pack parameter data and header + * correctly. + */ + memcpy(&adm_set_params->param_data, param_data, param_size); + } else { + pr_err("%s: Received NULL pointers for both memory header and param data\n", + __func__); + ret = -EINVAL; + goto done; + } - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - rc = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params); - if (rc < 0) { - pr_err("%s: Set params failed port = 0x%x rc %d\n", - __func__, port_id, rc); - rc = -EINVAL; - goto dolby_dap_send_param_return; + copp_stat = &this_adm.copp.stat[port_idx][copp_idx]; + atomic_set(copp_stat, -1); + ret = apr_send_pkt(this_adm.apr, (uint32_t *) adm_set_params); + if (ret < 0) { + pr_err("%s: Set params APR send failed port = 0x%x ret %d\n", + __func__, port_id, ret); + goto done; } - /* Wait for the callback */ - rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!rc) { - pr_err("%s: Set params timed out port = 0x%x\n", - __func__, port_id); - rc = -EINVAL; - goto dolby_dap_send_param_return; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - rc = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto dolby_dap_send_param_return; + ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(copp_stat) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: Set params timed out port = 0x%x\n", __func__, + port_id); + ret = -ETIMEDOUT; + goto done; } - rc = 0; -dolby_dap_send_param_return: - kfree(adm_params); - return rc; + if (atomic_read(copp_stat) > 0) { + pr_err("%s: DSP returned error[%s]\n", __func__, + adsp_err_get_err_str(atomic_read(copp_stat))); + ret = adsp_err_get_lnx_err_code(atomic_read(copp_stat)); + goto done; + } + + ret = 0; +done: + kfree(adm_set_params); + return ret; } +EXPORT_SYMBOL(adm_set_pp_params); -int adm_send_params_v5(int port_id, int copp_idx, char *params, - uint32_t params_length) +int adm_pack_and_set_one_pp_param(int port_id, int copp_idx, + struct param_hdr_v3 param_hdr, u8 *param_data) { - struct adm_cmd_set_pp_params_v5 *adm_params = NULL; - int rc = 0; - int sz, port_idx; - - pr_debug("%s:\n", __func__); - port_id = afe_convert_virtual_to_portid(port_id); - port_idx = adm_validate_and_get_port_index(port_id); - if (port_idx < 0) { - pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); - return -EINVAL; - } + u8 *packed_data = NULL; + u32 total_size = 0; + int ret = 0; - sz = sizeof(struct adm_cmd_set_pp_params_v5) + params_length; - adm_params = kzalloc(sz, GFP_KERNEL); - if (!adm_params) { - pr_err("%s, adm params memory alloc failed", __func__); + total_size = sizeof(union param_hdrs) + param_hdr.param_size; + packed_data = kzalloc(total_size, GFP_KERNEL); + if (!packed_data) return -ENOMEM; - } - memcpy(((u8 *)adm_params + sizeof(struct adm_cmd_set_pp_params_v5)), - params, params_length); - adm_params->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - adm_params->hdr.pkt_size = sz; - 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_idx][copp_idx]); - adm_params->hdr.token = port_idx << 16 | copp_idx; - adm_params->hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - adm_params->payload_addr_lsw = 0; - adm_params->payload_addr_msw = 0; - adm_params->mem_map_handle = 0; - adm_params->payload_size = params_length; - - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - rc = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params); - if (rc < 0) { - pr_err("%s: Set params failed port = 0x%x rc %d\n", - __func__, port_id, rc); - rc = -EINVAL; - goto send_param_return; - } - /* Wait for the callback */ - rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!rc) { - pr_err("%s: Set params timed out port = 0x%x\n", - __func__, port_id); - rc = -EINVAL; - goto send_param_return; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - rc = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto send_param_return; + ret = q6common_pack_pp_params(packed_data, ¶m_hdr, param_data, + &total_size); + if (ret) { + pr_err("%s: Failed to pack parameter data, error %d\n", + __func__, ret); + goto done; } - rc = 0; -send_param_return: - kfree(adm_params); - return rc; + + ret = adm_set_pp_params(port_id, copp_idx, NULL, packed_data, + total_size); + if (ret) + pr_err("%s: Failed to set parameter data, error %d\n", __func__, + ret); +done: + kfree(packed_data); + return ret; } +EXPORT_SYMBOL(adm_pack_and_set_one_pp_param); -int adm_get_params_v2(int port_id, int copp_idx, uint32_t module_id, - uint32_t param_id, uint32_t params_length, - char *params, uint32_t client_id) +/* + * Only one parameter can be requested at a time. Therefore, packing and sending + * the request can be handled locally. + */ +int adm_get_pp_params(int port_id, int copp_idx, uint32_t client_id, + struct mem_mapping_hdr *mem_hdr, + struct param_hdr_v3 *param_hdr, u8 *returned_param_data) { - struct adm_cmd_get_pp_params_v5 *adm_params = NULL; - int rc = 0, i = 0; - int port_idx, idx; - int *params_data = (int *)params; - uint64_t sz = 0; + struct adm_cmd_get_pp_params adm_get_params; + int total_size = 0; + int get_param_array_sz = ARRAY_SIZE(adm_get_parameters); + int returned_param_size = 0; + int returned_param_size_in_bytes = 0; + int port_idx = 0; + int idx = 0; + atomic_t *copp_stat = NULL; + int ret = 0; - port_id = afe_convert_virtual_to_portid(port_id); - port_idx = adm_validate_and_get_port_index(port_id); - if (port_idx < 0) { - pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); + if (param_hdr == NULL) { + pr_err("%s: Received NULL pointer for parameter header\n", + __func__); return -EINVAL; } - sz = (uint64_t)sizeof(struct adm_cmd_get_pp_params_v5) + - (uint64_t)params_length; - /* - * Check if the value of "sz" (which is ultimately assigned to - * "hdr.pkt_size") crosses U16_MAX. - */ - if (sz > U16_MAX) { - pr_err("%s: Invalid params_length\n", __func__); + port_id = afe_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0 || port_idx >= AFE_MAX_PORTS) { + pr_err("%s: Invalid port_idx 0x%x\n", __func__, port_idx); return -EINVAL; } - adm_params = kzalloc(sz, GFP_KERNEL); - if (!adm_params) { - pr_err("%s: adm params memory alloc failed", __func__); - return -ENOMEM; + if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + pr_err("%s: Invalid copp_idx 0x%x\n", __func__, copp_idx); + return -EINVAL; } - memcpy(((u8 *)adm_params + sizeof(struct adm_cmd_get_pp_params_v5)), - params, params_length); - adm_params->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - adm_params->hdr.pkt_size = sz; - 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_idx][copp_idx]); - adm_params->hdr.token = port_idx << 16 | client_id << 8 | copp_idx; - adm_params->hdr.opcode = ADM_CMD_GET_PP_PARAMS_V5; - adm_params->data_payload_addr_lsw = 0; - adm_params->data_payload_addr_msw = 0; - adm_params->mem_map_handle = 0; - adm_params->module_id = module_id; - adm_params->param_id = param_id; - adm_params->param_max_size = params_length; - adm_params->reserved = 0; + memset(&adm_get_params, 0, sizeof(adm_get_params)); - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - rc = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params); - if (rc < 0) { - pr_err("%s: Failed to Get Params on port_id 0x%x %d\n", - __func__, port_id, rc); - rc = -EINVAL; - goto adm_get_param_return; + if (mem_hdr != NULL) + adm_get_params.mem_hdr = *mem_hdr; + + q6common_pack_pp_params((u8 *) &adm_get_params.param_hdr, param_hdr, + NULL, &total_size); + + /* Pack APR header after filling body so total_size has correct value */ + adm_get_params.apr_hdr.pkt_size = total_size; + adm_get_params.apr_hdr.src_svc = APR_SVC_ADM; + adm_get_params.apr_hdr.src_domain = APR_DOMAIN_APPS; + adm_get_params.apr_hdr.src_port = port_id; + adm_get_params.apr_hdr.dest_svc = APR_SVC_ADM; + adm_get_params.apr_hdr.dest_domain = APR_DOMAIN_ADSP; + adm_get_params.apr_hdr.dest_port = + atomic_read(&this_adm.copp.id[port_idx][copp_idx]); + adm_get_params.apr_hdr.token = + port_idx << 16 | client_id << 8 | copp_idx; + + if (q6common_is_instance_id_supported()) + adm_get_params.apr_hdr.opcode = ADM_CMD_GET_PP_PARAMS_V6; + else + adm_get_params.apr_hdr.opcode = ADM_CMD_GET_PP_PARAMS_V5; + + copp_stat = &this_adm.copp.stat[port_idx][copp_idx]; + atomic_set(copp_stat, -1); + ret = apr_send_pkt(this_adm.apr, (uint32_t *) &adm_get_params); + if (ret) { + pr_err("%s: Get params APR send failed port = 0x%x ret %d\n", + __func__, port_id, ret); + ret = -EINVAL; + goto done; } - /* Wait for the callback with copp id */ - rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!rc) { - pr_err("%s: get params timed out port_id = 0x%x\n", __func__, - port_id); - rc = -EINVAL; - goto adm_get_param_return; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - rc = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto adm_get_param_return; + ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(copp_stat) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: Get params timed out port = 0x%x\n", __func__, + port_id); + ret = -ETIMEDOUT; + goto done; + } + if (atomic_read(copp_stat) > 0) { + pr_err("%s: DSP returned error[%s]\n", __func__, + adsp_err_get_err_str(atomic_read(copp_stat))); + ret = adsp_err_get_lnx_err_code(atomic_read(copp_stat)); + goto done; } - idx = ADM_GET_PARAMETER_LENGTH * copp_idx; - if (adm_get_parameters[idx] < 0) { - pr_err("%s: Size is invalid %d\n", __func__, - adm_get_parameters[idx]); - rc = -EINVAL; - goto adm_get_param_return; - } - if ((params_data) && - (ARRAY_SIZE(adm_get_parameters) > - idx) && - (ARRAY_SIZE(adm_get_parameters) >= - 1+adm_get_parameters[idx]+idx) && - (params_length/sizeof(uint32_t) >= - adm_get_parameters[idx])) { - for (i = 0; i < adm_get_parameters[idx]; i++) - params_data[i] = adm_get_parameters[1+i+idx]; + ret = 0; - } else { - pr_err("%s: Get param data not copied! get_param array size %zd, index %d, params array size %zd, index %d\n", - __func__, ARRAY_SIZE(adm_get_parameters), - (1+adm_get_parameters[idx]+idx), - params_length/sizeof(int), - adm_get_parameters[idx]); + /* Copy data to caller if sent in band */ + if (!returned_param_data) { + pr_debug("%s: Received NULL pointer for param destination, not copying payload\n", + __func__); + return 0; } - rc = 0; -adm_get_param_return: - kfree(adm_params); - return rc; -} + idx = ADM_GET_PARAMETER_LENGTH * copp_idx; + returned_param_size = adm_get_parameters[idx]; + if (returned_param_size < 0 || + returned_param_size + idx + 1 > get_param_array_sz) { + pr_err("%s: Invalid parameter size %d\n", __func__, + returned_param_size); + return -EINVAL; + } -int adm_get_params(int port_id, int copp_idx, uint32_t module_id, - uint32_t param_id, uint32_t params_length, char *params) -{ - return adm_get_params_v2(port_id, copp_idx, module_id, param_id, - params_length, params, 0); + returned_param_size_in_bytes = returned_param_size * sizeof(uint32_t); + if (param_hdr->param_size < returned_param_size_in_bytes) { + pr_err("%s: Provided buffer is not big enough, provided buffer size(%d) size needed(%d)\n", + __func__, param_hdr->param_size, + returned_param_size_in_bytes); + return -EINVAL; + } + + memcpy(returned_param_data, &adm_get_parameters[idx + 1], + returned_param_size_in_bytes); +done: + return ret; } +EXPORT_SYMBOL(adm_get_pp_params); -int adm_get_pp_topo_module_list(int port_id, int copp_idx, int32_t param_length, - char *params) +int adm_get_pp_topo_module_list_v2(int port_id, int copp_idx, + int32_t param_length, + int32_t *returned_params) { - struct adm_cmd_get_pp_topo_module_list_t *adm_pp_module_list = NULL; - int sz, rc = 0, i = 0; - int port_idx, idx; - int32_t *params_data = (int32_t *)params; + struct adm_cmd_get_pp_topo_module_list adm_get_module_list; + bool iid_supported = q6common_is_instance_id_supported(); int *topo_list; + int num_modules = 0; + int list_size = 0; + int port_idx, idx; + int i = 0; + atomic_t *copp_stat = NULL; + int ret = 0; pr_debug("%s : port_id %x", __func__, port_id); port_id = afe_convert_virtual_to_portid(port_id); @@ -1149,86 +979,102 @@ int adm_get_pp_topo_module_list(int port_id, int copp_idx, int32_t param_length, pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); return -EINVAL; } - if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx); return -EINVAL; } - sz = sizeof(struct adm_cmd_get_pp_topo_module_list_t) + param_length; - adm_pp_module_list = kzalloc(sz, GFP_KERNEL); - if (!adm_pp_module_list) { - pr_err("%s, adm params memory alloc failed", __func__); - return -ENOMEM; - } + memset(&adm_get_module_list, 0, sizeof(adm_get_module_list)); - memcpy(((u8 *)adm_pp_module_list + - sizeof(struct adm_cmd_get_pp_topo_module_list_t)), - params, param_length); - adm_pp_module_list->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - adm_pp_module_list->hdr.pkt_size = sz; - adm_pp_module_list->hdr.src_svc = APR_SVC_ADM; - adm_pp_module_list->hdr.src_domain = APR_DOMAIN_APPS; - adm_pp_module_list->hdr.src_port = port_id; - adm_pp_module_list->hdr.dest_svc = APR_SVC_ADM; - adm_pp_module_list->hdr.dest_domain = APR_DOMAIN_ADSP; - adm_pp_module_list->hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - adm_pp_module_list->hdr.token = port_idx << 16 | copp_idx; - adm_pp_module_list->hdr.opcode = ADM_CMD_GET_PP_TOPO_MODULE_LIST; - adm_pp_module_list->param_max_size = param_length; - /* Payload address and mmap handle set to zero by kzalloc */ + adm_get_module_list.apr_hdr.pkt_size = sizeof(adm_get_module_list); + adm_get_module_list.apr_hdr.src_svc = APR_SVC_ADM; + adm_get_module_list.apr_hdr.src_domain = APR_DOMAIN_APPS; + adm_get_module_list.apr_hdr.src_port = port_id; + adm_get_module_list.apr_hdr.dest_svc = APR_SVC_ADM; + adm_get_module_list.apr_hdr.dest_domain = APR_DOMAIN_ADSP; + adm_get_module_list.apr_hdr.dest_port = + atomic_read(&this_adm.copp.id[port_idx][copp_idx]); + adm_get_module_list.apr_hdr.token = port_idx << 16 | copp_idx; + /* + * Out of band functionality is not currently utilized. + * Assume in band. + */ + if (iid_supported) { + adm_get_module_list.apr_hdr.opcode = + ADM_CMD_GET_PP_TOPO_MODULE_LIST_V2; + adm_get_module_list.param_max_size = param_length; + } else { + adm_get_module_list.apr_hdr.opcode = + ADM_CMD_GET_PP_TOPO_MODULE_LIST; - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + if (param_length > U16_MAX) { + pr_err("%s: Invalid param length for V1 %d\n", __func__, + param_length); + return -EINVAL; + } + adm_get_module_list.param_max_size = param_length << 16; + } - rc = apr_send_pkt(this_adm.apr, (uint32_t *)adm_pp_module_list); - if (rc < 0) { - pr_err("%s: Failed to Get Params on port %d\n", __func__, - port_id); - rc = -EINVAL; - goto adm_pp_module_list_l; + copp_stat = &this_adm.copp.stat[port_idx][copp_idx]; + atomic_set(copp_stat, -1); + ret = apr_send_pkt(this_adm.apr, (uint32_t *) &adm_get_module_list); + if (ret) { + pr_err("%s: APR send pkt failed for port_id: 0x%x failed ret %d\n", + __func__, port_id, ret); + ret = -EINVAL; + goto done; } - /* Wait for the callback with copp id */ - rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!rc) { - pr_err("%s: get params timed out port = %d\n", __func__, - port_id); - rc = -EINVAL; - goto adm_pp_module_list_l; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - rc = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto adm_pp_module_list_l; - } - if (params_data) { - idx = ADM_GET_TOPO_MODULE_LIST_LENGTH * copp_idx; - topo_list = (int *)(adm_module_topo_list + idx); - if (param_length <= ADM_GET_TOPO_MODULE_LIST_LENGTH && - idx < - (MAX_COPPS_PER_PORT * ADM_GET_TOPO_MODULE_LIST_LENGTH)) - memcpy(params_data, topo_list, param_length); - else - pr_debug("%s: i/p size:%d > MAX param size:%d\n", - __func__, param_length, - (int)ADM_GET_TOPO_MODULE_LIST_LENGTH); - for (i = 1; i <= params_data[0]; i++) - pr_debug("module = 0x%x\n", params_data[i]); + ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], + atomic_read(copp_stat) >= 0, + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: Timeout for port_id: 0x%x\n", __func__, port_id); + ret = -ETIMEDOUT; + goto done; } - rc = 0; -adm_pp_module_list_l: - kfree(adm_pp_module_list); - pr_debug("%s : rc = %d ", __func__, rc); - return rc; + if (atomic_read(copp_stat) > 0) { + pr_err("%s: DSP returned error[%s]\n", __func__, + adsp_err_get_err_str(atomic_read(copp_stat))); + ret = adsp_err_get_lnx_err_code(atomic_read(copp_stat)); + goto done; + } + + ret = 0; + + if (returned_params) { + /* + * When processing ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST IID is + * added since it is not present. Therefore, there is no need to + * do anything different if IID is not supported here as it is + * already taken care of. + */ + idx = ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH * copp_idx; + num_modules = adm_module_topo_list[idx]; + if (num_modules < 0 || num_modules > MAX_MODULES_IN_TOPO) { + pr_err("%s: Invalid number of modules returned %d\n", + __func__, num_modules); + return -EINVAL; + } + + list_size = num_modules * sizeof(struct module_instance_info); + if (param_length < list_size) { + pr_err("%s: Provided buffer not big enough to hold module-instance list, provided size %d, needed size %d\n", + __func__, param_length, list_size); + return -EINVAL; + } + + topo_list = (int32_t *) (&adm_module_topo_list[idx]); + memcpy(returned_params, topo_list, list_size); + for (i = 1; i <= num_modules; i += 2) { + pr_debug("module = 0x%x instance = 0x%x\n", + returned_params[i], returned_params[i + 1]); + } + } +done: + return ret; } +EXPORT_SYMBOL(adm_get_pp_topo_module_list_v2); + static void adm_callback_debug_print(struct apr_client_data *data) { uint32_t *payload; @@ -1288,13 +1134,122 @@ int adm_get_multi_ch_map(char *channel_map, int path) return 0; } +static int adm_process_get_param_response(u32 opcode, u32 idx, u32 *payload, + u32 payload_size) +{ + struct adm_cmd_rsp_get_pp_params_v5 *v5_rsp = NULL; + struct adm_cmd_rsp_get_pp_params_v6 *v6_rsp = NULL; + u32 *param_data = NULL; + int data_size; + int struct_size; + + if (payload == NULL) { + pr_err("%s: Payload is NULL\n", __func__); + return -EINVAL; + } + + switch (opcode) { + case ADM_CMDRSP_GET_PP_PARAMS_V5: + struct_size = sizeof(struct adm_cmd_rsp_get_pp_params_v5); + v5_rsp = (struct adm_cmd_rsp_get_pp_params_v5 *) payload; + data_size = v5_rsp->param_hdr.param_size; + param_data = v5_rsp->param_data; + break; + case ADM_CMDRSP_GET_PP_PARAMS_V6: + struct_size = sizeof(struct adm_cmd_rsp_get_pp_params_v6); + v6_rsp = (struct adm_cmd_rsp_get_pp_params_v6 *) payload; + data_size = v6_rsp->param_hdr.param_size; + param_data = v6_rsp->param_data; + break; + default: + pr_err("%s: Invalid opcode %d\n", __func__, opcode); + return -EINVAL; + } + + /* + * Just store the returned parameter data, not the header. The calling + * function is expected to know what it asked for. Therefore, there is + * no difference between V5 and V6. + */ + if ((payload_size >= struct_size + data_size) && + (ARRAY_SIZE(adm_get_parameters) > idx) && + (ARRAY_SIZE(adm_get_parameters) >= idx + 1 + data_size)) { + /* + * data_size is expressed in number of bytes, store in number of + * ints + */ + adm_get_parameters[idx] = + data_size / sizeof(*adm_get_parameters); + pr_debug("%s: GET_PP PARAM: received parameter length: 0x%x\n", + __func__, adm_get_parameters[idx]); + /* store params after param_size */ + memcpy(&adm_get_parameters[idx + 1], param_data, data_size); + return 0; + } + + pr_err("%s: Invlaid parameter combination, payload_size %d, idx %d\n", + __func__, payload_size, idx); + return -EINVAL; +} + +static int adm_process_get_topo_list_response(u32 opcode, int copp_idx, + u32 num_modules, u32 *payload, + u32 payload_size) +{ + u32 *fill_list = NULL; + int idx = 0; + int i = 0; + int j = 0; + + if (payload == NULL) { + pr_err("%s: Payload is NULL\n", __func__); + return -EINVAL; + } else if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) + pr_err("%s: Invalid COPP index %d\n", __func__, copp_idx); + return -EINVAL; + + idx = ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH * copp_idx; + fill_list = adm_module_topo_list + idx; + *fill_list++ = num_modules; + for (i = 0; i < num_modules; i++) { + if (j > payload_size / sizeof(u32)) { + pr_err("%s: Invalid number of modules specified %d\n", + __func__, num_modules); + return -EINVAL; + } + + /* store module ID */ + *fill_list++ = payload[j]; + j++; + + switch (opcode) { + case ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST_V2: + /* store instance ID */ + *fill_list++ = payload[j]; + j++; + break; + case ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST: + /* Insert IID 0 when repacking */ + *fill_list++ = INSTANCE_ID_0; + break; + default: + pr_err("%s: Invalid opcode %d\n", __func__, opcode); + return -EINVAL; + } + } + + return 0; +} + static int32_t adm_callback(struct apr_client_data *data, void *priv) { uint32_t *payload; int i, j, port_idx, copp_idx, idx, client_id; + int num_modules; + int ret; if (data == NULL) { - pr_err("%s: data paramter is null\n", __func__); + pr_err("%s: data parameter is null\n", __func__); return -EINVAL; } @@ -1312,7 +1267,8 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) RESET_COPP_ID); atomic_set(&this_adm.copp.cnt[i][j], 0); atomic_set( - &this_adm.copp.topology[i][j], 0); + &this_adm.copp.topology[i][j], + 0); atomic_set(&this_adm.copp.mode[i][j], 0); atomic_set(&this_adm.copp.stat[i][j], @@ -1320,8 +1276,8 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) atomic_set(&this_adm.copp.rate[i][j], 0); atomic_set( - &this_adm.copp.channels[i][j], - 0); + &this_adm.copp.channels[i][j], + 0); atomic_set( &this_adm.copp.bit_width[i][j], 0); atomic_set( @@ -1392,8 +1348,9 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) } switch (payload[0]) { case ADM_CMD_SET_PP_PARAMS_V5: - pr_debug("%s: ADM_CMD_SET_PP_PARAMS_V5\n", - __func__); + case ADM_CMD_SET_PP_PARAMS_V6: + pr_debug("%s: ADM_CMD_SET_PP_PARAMS\n", + __func__); if (client_id == ADM_CLIENT_ID_SOURCE_TRACKING) this_adm.sourceTrackingData. apr_cmd_status = payload[1]; @@ -1450,8 +1407,9 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) } break; case ADM_CMD_GET_PP_PARAMS_V5: - pr_debug("%s: ADM_CMD_GET_PP_PARAMS_V5\n", - __func__); + case ADM_CMD_GET_PP_PARAMS_V6: + pr_debug("%s: ADM_CMD_GET_PP_PARAMS\n", + __func__); /* Should only come here if there is an APR */ /* error or malformed APR packet. Otherwise */ /* response will be returned as */ @@ -1488,11 +1446,12 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) &this_adm.copp.wait[port_idx][copp_idx]); break; case ADM_CMD_GET_PP_TOPO_MODULE_LIST: + case ADM_CMD_GET_PP_TOPO_MODULE_LIST_V2: pr_debug("%s:ADM_CMD_GET_PP_TOPO_MODULE_LIST\n", __func__); if (payload[1] != 0) - pr_err("%s: ADM get topo list error = %d,\n", - __func__, payload[1]); + pr_err("%s: ADM get topo list error = %d\n", + __func__, payload[1]); break; default: pr_err("%s: Unknown Cmd: 0x%x\n", __func__, @@ -1527,80 +1486,60 @@ static int32_t adm_callback(struct apr_client_data *data, void *priv) } break; case ADM_CMDRSP_GET_PP_PARAMS_V5: - pr_debug("%s: ADM_CMDRSP_GET_PP_PARAMS_V5\n", __func__); - if (payload[0] != 0) - pr_err("%s: ADM_CMDRSP_GET_PP_PARAMS_V5 returned error = 0x%x\n", - __func__, payload[0]); + case ADM_CMDRSP_GET_PP_PARAMS_V6: + pr_debug("%s: ADM_CMDRSP_GET_PP_PARAMS\n", __func__); if (client_id == ADM_CLIENT_ID_SOURCE_TRACKING) this_adm.sourceTrackingData.apr_cmd_status = - payload[0]; + payload[0]; else if (rtac_make_adm_callback(payload, - data->payload_size)) + data->payload_size)) break; idx = ADM_GET_PARAMETER_LENGTH * copp_idx; - if ((payload[0] == 0) && (data->payload_size > - (4 * sizeof(*payload))) && - (data->payload_size - 4 >= - payload[3]) && - (ARRAY_SIZE(adm_get_parameters) > - idx) && - (ARRAY_SIZE(adm_get_parameters)-idx-1 >= - payload[3])) { - adm_get_parameters[idx] = payload[3] / - sizeof(uint32_t); - /* - * payload[3] is param_size which is - * expressed in number of bytes - */ - pr_debug("%s: GET_PP PARAM:received parameter length: 0x%x\n", - __func__, adm_get_parameters[idx]); - /* storing param size then params */ - for (i = 0; i < payload[3] / - sizeof(uint32_t); i++) - adm_get_parameters[idx+1+i] = - payload[4+i]; - } else if (payload[0] == 0) { + if (payload[0] == 0 && data->payload_size > 0) { + pr_debug("%s: Received parameter data in band\n", + __func__); + ret = adm_process_get_param_response( + data->opcode, idx, payload, + data->payload_size); + if (ret) + pr_err("%s: Failed to process get param response, error %d\n", + __func__, ret); + } else if (payload[0] == 0 && data->payload_size == 0) { adm_get_parameters[idx] = -1; - pr_err("%s: Out of band case, setting size to %d\n", + pr_debug("%s: Out of band case, setting size to %d\n", __func__, adm_get_parameters[idx]); } else { adm_get_parameters[idx] = -1; - pr_err("%s: GET_PP_PARAMS failed, setting size to %d\n", - __func__, adm_get_parameters[idx]); + pr_err("%s: ADM_CMDRSP_GET_PP_PARAMS returned error 0x%x\n", + __func__, payload[0]); } - atomic_set(&this_adm.copp.stat - [port_idx][copp_idx], payload[0]); + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], + payload[0]); wake_up(&this_adm.copp.wait[port_idx][copp_idx]); break; case ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST: + case ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST_V2: pr_debug("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST\n", __func__); - if (payload[0] != 0) { - pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST", - __func__); - pr_err(":err = 0x%x\n", payload[0]); - } else if (payload[1] > - ((ADM_GET_TOPO_MODULE_LIST_LENGTH / - sizeof(uint32_t)) - 1)) { - pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST", - __func__); - pr_err(":size = %d\n", payload[1]); + num_modules = payload[1]; + pr_debug("%s: Num modules %d\n", __func__, num_modules); + if (payload[0]) { + pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST, error = %d\n", + __func__, payload[0]); + } else if (num_modules > MAX_MODULES_IN_TOPO) { + pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST invalid num modules received, num modules = %d\n", + __func__, num_modules); } else { - idx = ADM_GET_TOPO_MODULE_LIST_LENGTH * - copp_idx; - pr_debug("%s:Num modules payload[1] %d\n", - __func__, payload[1]); - adm_module_topo_list[idx] = payload[1]; - for (i = 1; i <= payload[1]; i++) { - adm_module_topo_list[idx+i] = - payload[1+i]; - pr_debug("%s:payload[%d] = %x\n", - __func__, (i+1), payload[1+i]); - } + ret = adm_process_get_topo_list_response( + data->opcode, copp_idx, num_modules, + payload, data->payload_size); + if (ret) + pr_err("%s: Failed to process get topo modules list response, error %d\n", + __func__, ret); } - atomic_set(&this_adm.copp.stat - [port_idx][copp_idx], payload[0]); + atomic_set(&this_adm.copp.stat[port_idx][copp_idx], + payload[0]); wake_up(&this_adm.copp.wait[port_idx][copp_idx]); break; case ADM_CMDRSP_SHARED_MEM_MAP_REGIONS: @@ -1882,21 +1821,16 @@ done: } static int send_adm_cal_block(int port_id, int copp_idx, - struct cal_block_data *cal_block, int perf_mode, - int app_type, int acdb_id, int sample_rate) + struct cal_block_data *cal_block, int perf_mode) { - s32 result = 0; - struct adm_cmd_set_pp_params_v5 adm_params; - int port_idx; + struct mem_mapping_hdr mem_hdr = {0}; + int payload_size = 0; + int port_idx = 0; + int topology; + int result = 0; + + pr_debug("%s: Port id 0x%x,\n", __func__, port_id); - pr_debug("%s: Port id 0x%x sample_rate %d ,\n", __func__, - port_id, sample_rate); - port_id = afe_convert_virtual_to_portid(port_id); - port_idx = adm_validate_and_get_port_index(port_id); - if (port_idx < 0) { - pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); - return -EINVAL; - } if (!cal_block) { pr_debug("%s: No ADM cal to send for port_id = 0x%x!\n", __func__, port_id); @@ -1904,75 +1838,38 @@ static int send_adm_cal_block(int port_id, int copp_idx, goto done; } if (cal_block->cal_data.size <= 0) { - pr_debug("%s: No ADM cal send for port_id = 0x%x!\n", - __func__, port_id); + pr_debug("%s: No ADM cal sent for port_id = 0x%x!\n", __func__, + port_id); result = -EINVAL; goto done; } + port_id = afe_convert_virtual_to_portid(port_id); + port_idx = adm_validate_and_get_port_index(port_id); + if (port_idx < 0 || port_idx >= AFE_MAX_PORTS) { + pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); + return -EINVAL; + } else if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + pr_err("%s: Invalid copp_idx 0x%x\n", __func__, copp_idx); + return -EINVAL; + } + + topology = atomic_read(&this_adm.copp.topology[port_idx][copp_idx]); if (perf_mode == LEGACY_PCM_MODE && - ((atomic_read(&this_adm.copp.topology[port_idx][copp_idx])) == - DS2_ADM_COPP_TOPOLOGY_ID)) { + topology == DS2_ADM_COPP_TOPOLOGY_ID) { pr_err("%s: perf_mode %d, topology 0x%x\n", __func__, perf_mode, - atomic_read( - &this_adm.copp.topology[port_idx][copp_idx])); + topology); 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 = 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.token = port_idx << 16 | copp_idx; - adm_params.hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - adm_params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - adm_params.payload_addr_lsw = lower_32_bits(cal_block->cal_data.paddr); - adm_params.payload_addr_msw = msm_audio_populate_upper_32_bits( - cal_block->cal_data.paddr); - adm_params.mem_map_handle = cal_block->map_data.q6map_handle; - adm_params.payload_size = cal_block->cal_data.size; + mem_hdr.data_payload_addr_lsw = + lower_32_bits(cal_block->cal_data.paddr); + mem_hdr.data_payload_addr_msw = + msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr); + mem_hdr.mem_map_handle = cal_block->map_data.q6map_handle; + payload_size = cal_block->cal_data.size; - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - pr_debug("%s: Sending SET_PARAMS payload = 0x%pK, size = %d\n", - __func__, &cal_block->cal_data.paddr, - 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 0x%x result %d\n", - __func__, port_id, result); - pr_debug("%s: Set params failed port = 0x%x payload = 0x%pK result %d\n", - __func__, port_id, &cal_block->cal_data.paddr, result); - result = -EINVAL; - goto done; - } - /* Wait for the callback */ - result = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!result) { - pr_err("%s: Set params timed out port = 0x%x\n", - __func__, port_id); - pr_debug("%s: Set params timed out port = 0x%x, payload = 0x%pK\n", - __func__, port_id, &cal_block->cal_data.paddr); - result = -EINVAL; - goto done; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - result = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto done; - } + adm_set_pp_params(port_id, copp_idx, &mem_hdr, NULL, payload_size); done: return result; @@ -2089,8 +1986,7 @@ static int adm_remap_and_send_cal_block(int cal_index, int port_id, __func__, cal_index); goto done; } - ret = send_adm_cal_block(port_id, copp_idx, cal_block, perf_mode, - app_type, acdb_id, sample_rate); + ret = send_adm_cal_block(port_id, copp_idx, cal_block, perf_mode); if (ret < 0) pr_debug("%s: No cal sent for cal_index %d, port_id = 0x%x! ret %d sample_rate %d\n", __func__, cal_index, port_id, ret, sample_rate); @@ -2600,10 +2496,10 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology, void adm_copp_mfc_cfg(int port_id, int copp_idx, int dst_sample_rate) { - struct audproc_mfc_output_media_fmt mfc_cfg; + struct audproc_mfc_param_media_fmt mfc_cfg = {0}; struct adm_cmd_device_open_v5 open; + struct param_hdr_v3 param_hdr = {0}; int port_idx; - int sz = 0; int rc = 0; int i = 0; @@ -2620,32 +2516,13 @@ void adm_copp_mfc_cfg(int port_id, int copp_idx, int dst_sample_rate) goto fail_cmd; } - sz = sizeof(struct audproc_mfc_output_media_fmt); + memset(&open, 0, sizeof(open)); + + param_hdr.module_id = AUDPROC_MODULE_ID_MFC; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT; + param_hdr.param_size = sizeof(mfc_cfg); - mfc_cfg.params.hdr.hdr_field = - APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - mfc_cfg.params.hdr.pkt_size = sz; - mfc_cfg.params.hdr.src_svc = APR_SVC_ADM; - mfc_cfg.params.hdr.src_domain = APR_DOMAIN_APPS; - mfc_cfg.params.hdr.src_port = port_id; - mfc_cfg.params.hdr.dest_svc = APR_SVC_ADM; - mfc_cfg.params.hdr.dest_domain = APR_DOMAIN_ADSP; - mfc_cfg.params.hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - mfc_cfg.params.hdr.token = port_idx << 16 | copp_idx; - mfc_cfg.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - mfc_cfg.params.payload_addr_lsw = 0; - mfc_cfg.params.payload_addr_msw = 0; - mfc_cfg.params.mem_map_handle = 0; - mfc_cfg.params.payload_size = sizeof(mfc_cfg) - - sizeof(mfc_cfg.params); - mfc_cfg.data.module_id = AUDPROC_MODULE_ID_MFC; - mfc_cfg.data.param_id = - AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT; - mfc_cfg.data.param_size = mfc_cfg.params.payload_size - - sizeof(mfc_cfg.data); - mfc_cfg.data.reserved = 0; mfc_cfg.sampling_rate = dst_sample_rate; mfc_cfg.bits_per_sample = atomic_read(&this_adm.copp.bit_width[port_idx][copp_idx]); @@ -2671,31 +2548,12 @@ void adm_copp_mfc_cfg(int port_id, int copp_idx, int dst_sample_rate) mfc_cfg.bits_per_sample, mfc_cfg.num_channels, mfc_cfg.sampling_rate); - rc = apr_send_pkt(this_adm.apr, (uint32_t *)&mfc_cfg); + rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, + (uint8_t *) &mfc_cfg); + if (rc) + pr_err("%s: Failed to set media format configuration data, err %d\n", + __func__, rc); - if (rc < 0) { - pr_err("%s: port_id: for[0x%x] failed %d\n", - __func__, port_id, rc); - goto fail_cmd; - } - /* Wait for the callback with copp id */ - rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!rc) { - pr_err("%s: mfc_cfg Set params timed out for port_id: for [0x%x]\n", - __func__, port_id); - goto fail_cmd; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - goto fail_cmd; - } - rc = 0; fail_cmd: return; } @@ -3545,134 +3403,43 @@ err: int adm_set_volume(int port_id, int copp_idx, int volume) { - struct audproc_volume_ctrl_master_gain audproc_vol; - int sz = 0; + struct audproc_volume_ctrl_master_gain audproc_vol = {0}; + struct param_hdr_v3 param_hdr = {0}; int rc = 0; - int port_idx; pr_debug("%s: port_id %d, volume %d\n", __func__, port_id, volume); - port_id = afe_convert_virtual_to_portid(port_id); - port_idx = adm_validate_and_get_port_index(port_id); - if (port_idx < 0) { - pr_err("%s: Invalid port_id %#x\n", __func__, port_id); - rc = -EINVAL; - goto fail_cmd; - } - if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { - pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx); - return -EINVAL; - } + param_hdr.module_id = AUDPROC_MODULE_ID_VOL_CTRL; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_VOL_CTRL_MASTER_GAIN; + param_hdr.param_size = sizeof(audproc_vol); - sz = sizeof(struct audproc_volume_ctrl_master_gain); - audproc_vol.params.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - audproc_vol.params.hdr.pkt_size = sz; - audproc_vol.params.hdr.src_svc = APR_SVC_ADM; - audproc_vol.params.hdr.src_domain = APR_DOMAIN_APPS; - audproc_vol.params.hdr.src_port = port_id; - audproc_vol.params.hdr.dest_svc = APR_SVC_ADM; - audproc_vol.params.hdr.dest_domain = APR_DOMAIN_ADSP; - audproc_vol.params.hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - audproc_vol.params.hdr.token = port_idx << 16 | copp_idx; - audproc_vol.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - audproc_vol.params.payload_addr_lsw = 0; - audproc_vol.params.payload_addr_msw = 0; - audproc_vol.params.mem_map_handle = 0; - audproc_vol.params.payload_size = sizeof(audproc_vol) - - sizeof(audproc_vol.params); - audproc_vol.data.module_id = AUDPROC_MODULE_ID_VOL_CTRL; - audproc_vol.data.param_id = AUDPROC_PARAM_ID_VOL_CTRL_MASTER_GAIN; - audproc_vol.data.param_size = audproc_vol.params.payload_size - - sizeof(audproc_vol.data); - audproc_vol.data.reserved = 0; audproc_vol.master_gain = volume; - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - rc = apr_send_pkt(this_adm.apr, (uint32_t *)&audproc_vol); - if (rc < 0) { - pr_err("%s: Set params failed port = %#x\n", - __func__, port_id); - rc = -EINVAL; - goto fail_cmd; - } - /* Wait for the callback */ - rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!rc) { - pr_err("%s: Vol cntrl Set params timed out port = %#x\n", - __func__, port_id); - rc = -EINVAL; - goto fail_cmd; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - rc = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto fail_cmd; - } - rc = 0; -fail_cmd: + rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, + (uint8_t *) &audproc_vol); + if (rc) + pr_err("%s: Failed to set volume, err %d\n", __func__, rc); + return rc; } int adm_set_softvolume(int port_id, int copp_idx, struct audproc_softvolume_params *softvol_param) { - struct audproc_soft_step_volume_params audproc_softvol; - int sz = 0; + struct audproc_soft_step_volume_params audproc_softvol = {0}; + struct param_hdr_v3 param_hdr = {0}; int rc = 0; - int port_idx; pr_debug("%s: period %d step %d curve %d\n", __func__, softvol_param->period, softvol_param->step, softvol_param->rampingcurve); - port_id = afe_convert_virtual_to_portid(port_id); - port_idx = adm_validate_and_get_port_index(port_id); - if (port_idx < 0) { - pr_err("%s: Invalid port_id %#x\n", __func__, port_id); - rc = -EINVAL; - goto fail_cmd; - } + param_hdr.module_id = AUDPROC_MODULE_ID_VOL_CTRL; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS; + param_hdr.param_size = sizeof(audproc_softvol); - if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { - pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx); - return -EINVAL; - } - - sz = sizeof(struct audproc_soft_step_volume_params); - - audproc_softvol.params.hdr.hdr_field = - APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - audproc_softvol.params.hdr.pkt_size = sz; - audproc_softvol.params.hdr.src_svc = APR_SVC_ADM; - audproc_softvol.params.hdr.src_domain = APR_DOMAIN_APPS; - audproc_softvol.params.hdr.src_port = port_id; - audproc_softvol.params.hdr.dest_svc = APR_SVC_ADM; - audproc_softvol.params.hdr.dest_domain = APR_DOMAIN_ADSP; - audproc_softvol.params.hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - audproc_softvol.params.hdr.token = port_idx << 16 | copp_idx; - audproc_softvol.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - audproc_softvol.params.payload_addr_lsw = 0; - audproc_softvol.params.payload_addr_msw = 0; - audproc_softvol.params.mem_map_handle = 0; - audproc_softvol.params.payload_size = sizeof(audproc_softvol) - - sizeof(audproc_softvol.params); - audproc_softvol.data.module_id = AUDPROC_MODULE_ID_VOL_CTRL; - audproc_softvol.data.param_id = - AUDPROC_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS; - audproc_softvol.data.param_size = audproc_softvol.params.payload_size - - sizeof(audproc_softvol.data); - audproc_softvol.data.reserved = 0; audproc_softvol.period = softvol_param->period; audproc_softvol.step = softvol_param->step; audproc_softvol.ramping_curve = softvol_param->rampingcurve; @@ -3681,315 +3448,122 @@ int adm_set_softvolume(int port_id, int copp_idx, audproc_softvol.period, audproc_softvol.step, audproc_softvol.ramping_curve); - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - rc = apr_send_pkt(this_adm.apr, (uint32_t *)&audproc_softvol); - if (rc < 0) { - pr_err("%s: Set params failed port = %#x\n", - __func__, port_id); - rc = -EINVAL; - goto fail_cmd; - } - /* Wait for the callback */ - rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!rc) { - pr_err("%s: Soft volume Set params timed out port = %#x\n", - __func__, port_id); - rc = -EINVAL; - goto fail_cmd; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - rc = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto fail_cmd; - } - rc = 0; -fail_cmd: + rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, + (uint8_t *) &audproc_softvol); + if (rc) + pr_err("%s: Failed to set soft volume, err %d\n", __func__, rc); + return rc; } int adm_set_mic_gain(int port_id, int copp_idx, int volume) { - struct adm_set_mic_gain_params mic_gain_params; + struct admx_mic_gain mic_gain_params = {0}; + struct param_hdr_v3 param_hdr = {0}; int rc = 0; - int sz, port_idx; - pr_debug("%s:\n", __func__); - port_id = afe_convert_virtual_to_portid(port_id); - port_idx = adm_validate_and_get_port_index(port_id); - if (port_idx < 0) { - pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); - return -EINVAL; - } + pr_debug("%s: Setting mic gain to %d at port_id 0x%x\n", __func__, + volume, port_id); - sz = sizeof(struct adm_set_mic_gain_params); + param_hdr.module_id = ADM_MODULE_IDX_MIC_GAIN_CTRL; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = ADM_PARAM_IDX_MIC_GAIN; + param_hdr.param_size = sizeof(mic_gain_params); - mic_gain_params.params.hdr.hdr_field = - APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - mic_gain_params.params.hdr.pkt_size = sz; - mic_gain_params.params.hdr.src_svc = APR_SVC_ADM; - mic_gain_params.params.hdr.src_domain = APR_DOMAIN_APPS; - mic_gain_params.params.hdr.src_port = port_id; - mic_gain_params.params.hdr.dest_svc = APR_SVC_ADM; - mic_gain_params.params.hdr.dest_domain = APR_DOMAIN_ADSP; - mic_gain_params.params.hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - mic_gain_params.params.hdr.token = port_idx << 16 | copp_idx; - mic_gain_params.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - mic_gain_params.params.payload_addr_lsw = 0; - mic_gain_params.params.payload_addr_msw = 0; - mic_gain_params.params.mem_map_handle = 0; - mic_gain_params.params.payload_size = - sizeof(struct adm_param_data_v5) + - sizeof(struct admx_mic_gain); - mic_gain_params.data.module_id = ADM_MODULE_IDX_MIC_GAIN_CTRL; - mic_gain_params.data.param_id = ADM_PARAM_IDX_MIC_GAIN; - mic_gain_params.data.param_size = - sizeof(struct admx_mic_gain); - mic_gain_params.data.reserved = 0; - mic_gain_params.mic_gain_data.tx_mic_gain = volume; - mic_gain_params.mic_gain_data.reserved = 0; - pr_debug("%s: Mic Gain set to %d at port_id 0x%x\n", - __func__, volume, port_id); + mic_gain_params.tx_mic_gain = volume; + + rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, + (uint8_t *) &mic_gain_params); + if (rc) + pr_err("%s: Failed to set mic gain, err %d\n", __func__, rc); - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - rc = apr_send_pkt(this_adm.apr, (uint32_t *)&mic_gain_params); - if (rc < 0) { - pr_err("%s: Set params failed port = %#x\n", - __func__, port_id); - rc = -EINVAL; - goto fail_cmd; - } - /* Wait for the callback */ - rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!rc) { - pr_err("%s: Mic Gain Set params timed out port = %#x\n", - __func__, port_id); - rc = -EINVAL; - goto fail_cmd; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - rc = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto fail_cmd; - } - rc = 0; -fail_cmd: return rc; } int adm_send_set_multichannel_ec_primary_mic_ch(int port_id, int copp_idx, int primary_mic_ch) { - struct adm_set_sec_primary_ch_params sec_primary_ch_params; + struct admx_sec_primary_mic_ch sec_primary_ch_params = {0}; + struct param_hdr_v3 param_hdr = {0}; int rc = 0; - int sz, port_idx; pr_debug("%s port_id 0x%x, copp_idx 0x%x, primary_mic_ch %d\n", __func__, port_id, copp_idx, primary_mic_ch); - port_id = afe_convert_virtual_to_portid(port_id); - port_idx = adm_validate_and_get_port_index(port_id); - if (port_idx < 0) { - pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id); - return -EINVAL; - } - if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { - pr_err("%s: Invalid copp_idx 0x%x\n", __func__, copp_idx); - return -EINVAL; - } + param_hdr.module_id = AUDPROC_MODULE_ID_VOICE_TX_SECNS; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_IDX_SEC_PRIMARY_MIC_CH; + param_hdr.param_size = sizeof(sec_primary_ch_params); - sz = sizeof(struct adm_set_sec_primary_ch_params); + sec_primary_ch_params.version = 0; + sec_primary_ch_params.sec_primary_mic_ch = primary_mic_ch; - sec_primary_ch_params.params.hdr.hdr_field = - APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - sec_primary_ch_params.params.hdr.pkt_size = sz; - sec_primary_ch_params.params.hdr.src_svc = APR_SVC_ADM; - sec_primary_ch_params.params.hdr.src_domain = APR_DOMAIN_APPS; - sec_primary_ch_params.params.hdr.src_port = port_id; - sec_primary_ch_params.params.hdr.dest_svc = APR_SVC_ADM; - sec_primary_ch_params.params.hdr.dest_domain = APR_DOMAIN_ADSP; - sec_primary_ch_params.params.hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - sec_primary_ch_params.params.hdr.token = port_idx << 16 | copp_idx; - sec_primary_ch_params.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - sec_primary_ch_params.params.payload_addr_lsw = 0; - sec_primary_ch_params.params.payload_addr_msw = 0; - sec_primary_ch_params.params.mem_map_handle = 0; - sec_primary_ch_params.params.payload_size = - sizeof(struct adm_param_data_v5) + - sizeof(struct admx_sec_primary_mic_ch); - sec_primary_ch_params.data.module_id = - AUDPROC_MODULE_ID_VOICE_TX_SECNS; - sec_primary_ch_params.data.param_id = - AUDPROC_PARAM_IDX_SEC_PRIMARY_MIC_CH; - sec_primary_ch_params.data.param_size = - sizeof(struct admx_sec_primary_mic_ch); - sec_primary_ch_params.data.reserved = 0; - sec_primary_ch_params.sec_primary_mic_ch_data.version = 0; - sec_primary_ch_params.sec_primary_mic_ch_data.reserved = 0; - sec_primary_ch_params.sec_primary_mic_ch_data.sec_primary_mic_ch = - primary_mic_ch; - sec_primary_ch_params.sec_primary_mic_ch_data.reserved1 = 0; + rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, + (uint8_t *) &sec_primary_ch_params); + if (rc) + pr_err("%s: Failed to set primary mic chanel, err %d\n", + __func__, rc); - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - rc = apr_send_pkt(this_adm.apr, (uint32_t *)&sec_primary_ch_params); - if (rc < 0) { - pr_err("%s: Set params failed port = %#x\n", - __func__, port_id); - rc = -EINVAL; - goto fail_cmd; - } - /* Wait for the callback */ - rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!rc) { - pr_err("%s: Mic Set params timed out port = %#x\n", - __func__, port_id); - rc = -EINVAL; - goto fail_cmd; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - rc = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto fail_cmd; - } - rc = 0; -fail_cmd: return rc; } - -int adm_param_enable(int port_id, int copp_idx, int module_id, int enable) +int adm_param_enable(int port_id, int copp_idx, int module_id, int enable) { - struct audproc_enable_param_t adm_mod_enable; - int sz = 0; - int rc = 0; - int port_idx; + struct module_instance_info mod_inst_info = {0}; - pr_debug("%s port_id %d, module_id 0x%x, enable %d\n", - __func__, port_id, module_id, enable); - port_id = afe_convert_virtual_to_portid(port_id); - port_idx = adm_validate_and_get_port_index(port_id); - if (port_idx < 0) { - pr_err("%s: Invalid port_id %#x\n", __func__, port_id); - rc = -EINVAL; - goto fail_cmd; - } + mod_inst_info.module_id = module_id; + mod_inst_info.instance_id = INSTANCE_ID_0; - if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { - pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx); + return adm_param_enable_v2(port_id, copp_idx, mod_inst_info, enable); +} + +int adm_param_enable_v2(int port_id, int copp_idx, + struct module_instance_info mod_inst_info, int enable) +{ + uint32_t enable_param; + struct param_hdr_v3 param_hdr = {0}; + int rc = 0; + + if (enable < 0 || enable > 1) { + pr_err("%s: Invalid value for enable %d\n", __func__, enable); return -EINVAL; } - sz = sizeof(struct audproc_enable_param_t); + pr_debug("%s port_id %d, module_id 0x%x, instance_id 0x%x, enable %d\n", + __func__, port_id, mod_inst_info.module_id, + mod_inst_info.instance_id, enable); - adm_mod_enable.pp_params.hdr.hdr_field = - APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - adm_mod_enable.pp_params.hdr.pkt_size = sz; - adm_mod_enable.pp_params.hdr.src_svc = APR_SVC_ADM; - adm_mod_enable.pp_params.hdr.src_domain = APR_DOMAIN_APPS; - adm_mod_enable.pp_params.hdr.src_port = port_id; - adm_mod_enable.pp_params.hdr.dest_svc = APR_SVC_ADM; - adm_mod_enable.pp_params.hdr.dest_domain = APR_DOMAIN_ADSP; - adm_mod_enable.pp_params.hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - adm_mod_enable.pp_params.hdr.token = port_idx << 16 | copp_idx; - adm_mod_enable.pp_params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - adm_mod_enable.pp_params.payload_addr_lsw = 0; - adm_mod_enable.pp_params.payload_addr_msw = 0; - adm_mod_enable.pp_params.mem_map_handle = 0; - adm_mod_enable.pp_params.payload_size = sizeof(adm_mod_enable) - - sizeof(adm_mod_enable.pp_params) + - sizeof(adm_mod_enable.pp_params.params); - adm_mod_enable.pp_params.params.module_id = module_id; - adm_mod_enable.pp_params.params.param_id = AUDPROC_PARAM_ID_ENABLE; - adm_mod_enable.pp_params.params.param_size = - adm_mod_enable.pp_params.payload_size - - sizeof(adm_mod_enable.pp_params.params); - adm_mod_enable.pp_params.params.reserved = 0; - adm_mod_enable.enable = enable; + param_hdr.module_id = mod_inst_info.module_id; + param_hdr.instance_id = mod_inst_info.instance_id; + param_hdr.param_id = AUDPROC_PARAM_ID_ENABLE; + param_hdr.param_size = sizeof(enable_param); - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); + enable_param = enable; + + rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, + (uint8_t *) &enable_param); + if (rc) + pr_err("%s: Failed to set enable of module(%d) instance(%d) to %d, err %d\n", + __func__, mod_inst_info.module_id, + mod_inst_info.instance_id, enable, rc); - rc = apr_send_pkt(this_adm.apr, (uint32_t *)&adm_mod_enable); - if (rc < 0) { - pr_err("%s: Set params failed port = %#x\n", - __func__, port_id); - rc = -EINVAL; - goto fail_cmd; - } - /* Wait for the callback */ - rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!rc) { - pr_err("%s: module %x enable %d timed out on port = %#x\n", - __func__, module_id, enable, port_id); - rc = -EINVAL; - goto fail_cmd; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - rc = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto fail_cmd; - } - rc = 0; -fail_cmd: return rc; } +/* Parameter data must be pre-packed at the specified location with its + * header before calling this function. Use + * q6common_pack_pp_params to pack parameter data and header + * correctly. + */ int adm_send_calibration(int port_id, int copp_idx, int path, int perf_mode, int cal_type, char *params, int size) { - struct adm_cmd_set_pp_params_v5 *adm_params = NULL; - int sz, rc = 0; - int port_idx; + int rc = 0; pr_debug("%s:port_id %d, path %d, perf_mode %d, cal_type %d, size %d\n", __func__, port_id, path, perf_mode, cal_type, size); - port_id = afe_convert_virtual_to_portid(port_id); - port_idx = adm_validate_and_get_port_index(port_id); - if (port_idx < 0) { - pr_err("%s: Invalid port_id %#x\n", __func__, port_id); - rc = -EINVAL; - goto end; - } - - if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { - pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx); - return -EINVAL; - } - /* Maps audio_dev_ctrl path definition to ACDB definition */ if (get_cal_path(path) != RX_DEVICE) { pr_err("%s: acdb_path %d\n", __func__, path); @@ -3997,64 +3571,9 @@ int adm_send_calibration(int port_id, int copp_idx, int path, int perf_mode, goto end; } - sz = sizeof(struct adm_cmd_set_pp_params_v5) + size; - adm_params = kzalloc(sz, GFP_KERNEL); - if (!adm_params) { - pr_err("%s, adm params memory alloc failed", __func__); - rc = -ENOMEM; - goto end; - } - - memcpy(((u8 *)adm_params + sizeof(struct adm_cmd_set_pp_params_v5)), - params, size); - - adm_params->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - adm_params->hdr.pkt_size = sz; - 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_idx][copp_idx]); - adm_params->hdr.token = port_idx << 16 | copp_idx; - adm_params->hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - /* payload address and mmap handle initialized to zero by kzalloc */ - adm_params->payload_size = size; - - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - rc = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params); - if (rc < 0) { - pr_err("%s: Set params failed port = %#x\n", - __func__, port_id); - rc = -EINVAL; - goto end; - } - /* Wait for the callback */ - rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!rc) { - pr_err("%s: Set params timed out port = %#x\n", - __func__, port_id); - rc = -EINVAL; - goto end; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - rc = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto end; - } - rc = 0; + rc = adm_set_pp_params(port_id, copp_idx, NULL, (u8 *) params, size); end: - kfree(adm_params); return rc; } @@ -4236,155 +3755,52 @@ end: int adm_send_compressed_device_mute(int port_id, int copp_idx, bool mute_on) { - struct adm_set_compressed_device_mute mute_params; + u32 mute_param = mute_on ? 1 : 0; + struct param_hdr_v3 param_hdr = {0}; int ret = 0; - int port_idx; pr_debug("%s port_id: 0x%x, copp_idx %d, mute_on: %d\n", __func__, port_id, copp_idx, mute_on); - port_id = afe_convert_virtual_to_portid(port_id); - port_idx = adm_validate_and_get_port_index(port_id); - if (port_idx < 0 || port_idx >= AFE_MAX_PORTS) { - pr_err("%s: Invalid port_id %#x copp_idx %d\n", - __func__, port_id, copp_idx); - ret = -EINVAL; - goto end; - } - mute_params.command.hdr.hdr_field = - APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - mute_params.command.hdr.pkt_size = - sizeof(struct adm_set_compressed_device_mute); - mute_params.command.hdr.src_svc = APR_SVC_ADM; - mute_params.command.hdr.src_domain = APR_DOMAIN_APPS; - mute_params.command.hdr.src_port = port_id; - mute_params.command.hdr.dest_svc = APR_SVC_ADM; - mute_params.command.hdr.dest_domain = APR_DOMAIN_ADSP; - mute_params.command.hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - mute_params.command.hdr.token = port_idx << 16 | copp_idx; - mute_params.command.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - mute_params.command.payload_addr_lsw = 0; - mute_params.command.payload_addr_msw = 0; - mute_params.command.mem_map_handle = 0; - mute_params.command.payload_size = sizeof(mute_params) - - sizeof(mute_params.command); - mute_params.params.module_id = AUDPROC_MODULE_ID_COMPRESSED_MUTE; - mute_params.params.param_id = AUDPROC_PARAM_ID_COMPRESSED_MUTE; - mute_params.params.param_size = mute_params.command.payload_size - - sizeof(mute_params.params); - mute_params.params.reserved = 0; - mute_params.mute_on = mute_on; + param_hdr.module_id = AUDPROC_MODULE_ID_COMPRESSED_MUTE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_COMPRESSED_MUTE; + param_hdr.param_size = sizeof(mute_param); - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - ret = apr_send_pkt(this_adm.apr, (uint32_t *)&mute_params); - if (ret < 0) { - pr_err("%s: device mute for port %d copp %d failed, ret %d\n", - __func__, port_id, copp_idx, ret); - ret = -EINVAL; - goto end; - } + ret = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, + (uint8_t *) &mute_param); + if (ret) + pr_err("%s: Failed to set mute, err %d\n", __func__, ret); - /* Wait for the callback */ - ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: send device mute for port %d copp %d failed\n", - __func__, port_id, copp_idx); - ret = -EINVAL; - goto end; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto end; - } - ret = 0; -end: return ret; } int adm_send_compressed_device_latency(int port_id, int copp_idx, int latency) { - struct adm_set_compressed_device_latency latency_params; - int port_idx; + u32 latency_param; + struct param_hdr_v3 param_hdr = {0}; int ret = 0; pr_debug("%s port_id: 0x%x, copp_idx %d latency: %d\n", __func__, port_id, copp_idx, latency); - port_id = afe_convert_virtual_to_portid(port_id); - port_idx = adm_validate_and_get_port_index(port_id); - if (port_idx < 0 || port_idx >= AFE_MAX_PORTS) { - pr_err("%s: Invalid port_id %#x copp_idx %d\n", - __func__, port_id, copp_idx); - ret = -EINVAL; - goto end; + + if (latency < 0) { + pr_err("%s: Invalid value for latency %d", __func__, latency); + return -EINVAL; } - latency_params.command.hdr.hdr_field = - APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - latency_params.command.hdr.pkt_size = - sizeof(struct adm_set_compressed_device_latency); - latency_params.command.hdr.src_svc = APR_SVC_ADM; - latency_params.command.hdr.src_domain = APR_DOMAIN_APPS; - latency_params.command.hdr.src_port = port_id; - latency_params.command.hdr.dest_svc = APR_SVC_ADM; - latency_params.command.hdr.dest_domain = APR_DOMAIN_ADSP; - latency_params.command.hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - latency_params.command.hdr.token = port_idx << 16 | copp_idx; - latency_params.command.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - latency_params.command.payload_addr_lsw = 0; - latency_params.command.payload_addr_msw = 0; - latency_params.command.mem_map_handle = 0; - latency_params.command.payload_size = sizeof(latency_params) - - sizeof(latency_params.command); - latency_params.params.module_id = AUDPROC_MODULE_ID_COMPRESSED_LATENCY; - latency_params.params.param_id = AUDPROC_PARAM_ID_COMPRESSED_LATENCY; - latency_params.params.param_size = latency_params.command.payload_size - - sizeof(latency_params.params); - latency_params.params.reserved = 0; - latency_params.latency = latency; + param_hdr.module_id = AUDPROC_MODULE_ID_COMPRESSED_LATENCY; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_COMPRESSED_LATENCY; + param_hdr.param_size = sizeof(latency_param); - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - ret = apr_send_pkt(this_adm.apr, (uint32_t *)&latency_params); - if (ret < 0) { - pr_err("%s: send device latency err %d for port %d copp %d\n", - __func__, port_id, copp_idx, ret); - ret = -EINVAL; - goto end; - } + latency_param = latency; + + ret = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, + (uint8_t *) &latency_param); + if (ret) + pr_err("%s: Failed to set latency, err %d\n", __func__, ret); - /* Wait for the callback */ - ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: send device latency for port %d failed\n", __func__, - port_id); - ret = -EINVAL; - goto end; - } else if (atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto end; - } - ret = 0; -end: return ret; } @@ -4403,9 +3819,10 @@ end: int adm_swap_speaker_channels(int port_id, int copp_idx, int sample_rate, bool spk_swap) { - struct audproc_mfc_output_media_fmt mfc_cfg; + struct audproc_mfc_param_media_fmt mfc_cfg; + struct param_hdr_v3 param_hdr = {0}; uint16_t num_channels; - int port_idx; + int port_idx = 0; int ret = 0; pr_debug("%s: Enter, port_id %d, copp_idx %d\n", @@ -4414,50 +3831,26 @@ int adm_swap_speaker_channels(int port_id, int copp_idx, port_idx = adm_validate_and_get_port_index(port_id); if (port_idx < 0 || port_idx >= AFE_MAX_PORTS) { pr_err("%s: Invalid port_id %#x\n", __func__, port_id); - ret = -EINVAL; - goto done; - } - - if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { - pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx); - ret = -EINVAL; - goto done; + return -EINVAL; + } else if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { + pr_err("%s: Invalid copp_idx 0x%x\n", __func__, copp_idx); + return -EINVAL; } - num_channels = atomic_read( - &this_adm.copp.channels[port_idx][copp_idx]); + num_channels = atomic_read(&this_adm.copp.channels[port_idx][copp_idx]); if (num_channels != 2) { pr_debug("%s: Invalid number of channels: %d\n", __func__, num_channels); - ret = -EINVAL; - goto done; + return -EINVAL; } memset(&mfc_cfg, 0, sizeof(mfc_cfg)); - mfc_cfg.params.hdr.hdr_field = - APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - mfc_cfg.params.hdr.pkt_size = - sizeof(mfc_cfg); - mfc_cfg.params.hdr.src_svc = APR_SVC_ADM; - mfc_cfg.params.hdr.src_domain = APR_DOMAIN_APPS; - mfc_cfg.params.hdr.src_port = port_id; - mfc_cfg.params.hdr.dest_svc = APR_SVC_ADM; - mfc_cfg.params.hdr.dest_domain = APR_DOMAIN_ADSP; - mfc_cfg.params.hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - mfc_cfg.params.hdr.token = port_idx << 16 | copp_idx; - mfc_cfg.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - mfc_cfg.params.payload_addr_lsw = 0; - mfc_cfg.params.payload_addr_msw = 0; - mfc_cfg.params.mem_map_handle = 0; - mfc_cfg.params.payload_size = sizeof(mfc_cfg) - - sizeof(mfc_cfg.params); - mfc_cfg.data.module_id = AUDPROC_MODULE_ID_MFC; - mfc_cfg.data.param_id = AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT; - mfc_cfg.data.param_size = mfc_cfg.params.payload_size - - sizeof(mfc_cfg.data); - mfc_cfg.data.reserved = 0; + + param_hdr.module_id = AUDPROC_MODULE_ID_MFC; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT; + param_hdr.param_size = sizeof(mfc_cfg); + mfc_cfg.sampling_rate = sample_rate; mfc_cfg.bits_per_sample = atomic_read(&this_adm.copp.bit_width[port_idx][copp_idx]); @@ -4476,153 +3869,56 @@ int adm_swap_speaker_channels(int port_id, int copp_idx, (uint16_t) PCM_CHANNEL_FR; } - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - pr_debug("%s: mfc config: port_idx %d copp_idx %d copp SR %d copp BW %d copp chan %d\n", - __func__, port_idx, copp_idx, mfc_cfg.sampling_rate, - mfc_cfg.bits_per_sample, mfc_cfg.num_channels); - - ret = apr_send_pkt(this_adm.apr, (uint32_t *)&mfc_cfg); + ret = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, + (u8 *) &mfc_cfg); if (ret < 0) { - pr_err("%s: port_id: for[0x%x] failed %d\n", - __func__, port_id, ret); - goto done; - } - /* 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 - [port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: mfc_cfg Set params timed out for port_id: for [0x%x]\n", - __func__, port_id); - ret = -ETIMEDOUT; - goto done; - } - - if (atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx]))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [port_idx][copp_idx])); - goto done; + pr_err("%s: Failed to set swap speaker channels on port[0x%x] failed %d\n", + __func__, port_id, ret); + return ret; } pr_debug("%s: mfc_cfg Set params returned success", __func__); - ret = 0; - -done: - return ret; + return 0; } EXPORT_SYMBOL(adm_swap_speaker_channels); int adm_set_sound_focus(int port_id, int copp_idx, struct sound_focus_param soundFocusData) { - struct adm_set_fluence_soundfocus_param soundfocus_params; - int sz = 0; + struct adm_param_fluence_soundfocus_t soundfocus_params; + struct param_hdr_v3 param_hdr = {0}; int ret = 0; - int port_idx; int i; pr_debug("%s: Enter, port_id %d, copp_idx %d\n", __func__, port_id, copp_idx); - port_id = afe_convert_virtual_to_portid(port_id); - port_idx = adm_validate_and_get_port_index(port_id); - if (port_idx < 0) { - pr_err("%s: Invalid port_id %#x\n", __func__, port_id); + param_hdr.module_id = VOICEPROC_MODULE_ID_GENERIC_TX; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = VOICEPROC_PARAM_ID_FLUENCE_SOUNDFOCUS; + param_hdr.param_size = sizeof(soundfocus_params); - ret = -EINVAL; - goto done; - } - - if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) { - pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx); - - ret = -EINVAL; - goto done; - } - - sz = sizeof(struct adm_set_fluence_soundfocus_param); - soundfocus_params.params.hdr.hdr_field = - APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), - APR_PKT_VER); - soundfocus_params.params.hdr.pkt_size = sz; - soundfocus_params.params.hdr.src_svc = APR_SVC_ADM; - soundfocus_params.params.hdr.src_domain = APR_DOMAIN_APPS; - soundfocus_params.params.hdr.src_port = port_id; - soundfocus_params.params.hdr.dest_svc = APR_SVC_ADM; - soundfocus_params.params.hdr.dest_domain = APR_DOMAIN_ADSP; - soundfocus_params.params.hdr.dest_port = - atomic_read(&this_adm.copp.id[port_idx][copp_idx]); - soundfocus_params.params.hdr.token = port_idx << 16 | - ADM_CLIENT_ID_SOURCE_TRACKING << 8 | copp_idx; - soundfocus_params.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5; - soundfocus_params.params.payload_addr_lsw = 0; - soundfocus_params.params.payload_addr_msw = 0; - soundfocus_params.params.mem_map_handle = 0; - soundfocus_params.params.payload_size = sizeof(soundfocus_params) - - sizeof(soundfocus_params.params); - soundfocus_params.data.module_id = VOICEPROC_MODULE_ID_GENERIC_TX; - soundfocus_params.data.param_id = VOICEPROC_PARAM_ID_FLUENCE_SOUNDFOCUS; - soundfocus_params.data.param_size = - soundfocus_params.params.payload_size - - sizeof(soundfocus_params.data); - soundfocus_params.data.reserved = 0; - - memset(&(soundfocus_params.soundfocus_data), 0xFF, - sizeof(struct adm_param_fluence_soundfocus_t)); + memset(&(soundfocus_params), 0xFF, sizeof(soundfocus_params)); for (i = 0; i < MAX_SECTORS; i++) { - soundfocus_params.soundfocus_data.start_angles[i] = + soundfocus_params.start_angles[i] = soundFocusData.start_angle[i]; - soundfocus_params.soundfocus_data.enables[i] = - soundFocusData.enable[i]; + soundfocus_params.enables[i] = soundFocusData.enable[i]; pr_debug("%s: start_angle[%d] = %d\n", __func__, i, soundFocusData.start_angle[i]); pr_debug("%s: enable[%d] = %d\n", __func__, i, soundFocusData.enable[i]); } - soundfocus_params.soundfocus_data.gain_step = - soundFocusData.gain_step; + soundfocus_params.gain_step = soundFocusData.gain_step; pr_debug("%s: gain_step = %d\n", __func__, soundFocusData.gain_step); - soundfocus_params.soundfocus_data.reserved = 0; + soundfocus_params.reserved = 0; - atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1); - ret = apr_send_pkt(this_adm.apr, (uint32_t *)&soundfocus_params); - if (ret < 0) { - pr_err("%s: Set params failed\n", __func__); + ret = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr, + (uint8_t *) &soundfocus_params); + if (ret) + pr_err("%s: Failed to set sound focus params, err %d\n", + __func__, ret); - ret = -EINVAL; - goto done; - } - /* Wait for the callback */ - ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx], - atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: Set params timed out\n", __func__); - - ret = -EINVAL; - goto done; - } - - if (this_adm.sourceTrackingData.apr_cmd_status != 0) { - pr_err("%s - set params returned error [%s]\n", - __func__, adsp_err_get_err_str( - this_adm.sourceTrackingData.apr_cmd_status)); - - ret = adsp_err_get_lnx_err_code( - this_adm.sourceTrackingData.apr_cmd_status); - goto done; - } - - ret = 0; - -done: pr_debug("%s: Exit, ret=%d\n", __func__, ret); return ret; @@ -4633,30 +3929,28 @@ int adm_get_sound_focus(int port_id, int copp_idx, { int ret = 0, i; char *params_value; - uint32_t param_payload_len = sizeof(struct adm_param_data_v5) + - sizeof(struct adm_param_fluence_soundfocus_t); - struct adm_param_fluence_soundfocus_t *soundfocus_params; + uint32_t max_param_size = 0; + struct adm_param_fluence_soundfocus_t *soundfocus_params = NULL; + struct param_hdr_v3 param_hdr = {0}; pr_debug("%s: Enter, port_id %d, copp_idx %d\n", __func__, port_id, copp_idx); - params_value = kzalloc(param_payload_len, GFP_KERNEL); - if (!params_value) { - pr_err("%s, params memory alloc failed\n", __func__); + max_param_size = sizeof(struct adm_param_fluence_soundfocus_t) + + sizeof(union param_hdrs); + params_value = kzalloc(max_param_size, GFP_KERNEL); + if (!params_value) + return -ENOMEM; - ret = -ENOMEM; - goto done; - } - ret = adm_get_params_v2(port_id, copp_idx, - VOICEPROC_MODULE_ID_GENERIC_TX, - VOICEPROC_PARAM_ID_FLUENCE_SOUNDFOCUS, - param_payload_len, - params_value, - ADM_CLIENT_ID_SOURCE_TRACKING); + param_hdr.module_id = VOICEPROC_MODULE_ID_GENERIC_TX; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = VOICEPROC_PARAM_ID_FLUENCE_SOUNDFOCUS; + param_hdr.param_size = max_param_size; + ret = adm_get_pp_params(port_id, copp_idx, + ADM_CLIENT_ID_SOURCE_TRACKING, NULL, ¶m_hdr, + params_value); if (ret) { pr_err("%s: get parameters failed ret:%d\n", __func__, ret); - - kfree(params_value); ret = -EINVAL; goto done; } @@ -4665,8 +3959,6 @@ int adm_get_sound_focus(int port_id, int copp_idx, pr_err("%s - get params returned error [%s]\n", __func__, adsp_err_get_err_str( this_adm.sourceTrackingData.apr_cmd_status)); - - kfree(params_value); ret = adsp_err_get_lnx_err_code( this_adm.sourceTrackingData.apr_cmd_status); goto done; @@ -4686,11 +3978,10 @@ int adm_get_sound_focus(int port_id, int copp_idx, soundFocusData->gain_step = soundfocus_params->gain_step; pr_debug("%s: gain_step = %d\n", __func__, soundFocusData->gain_step); - kfree(params_value); - done: pr_debug("%s: Exit, ret = %d\n", __func__, ret); + kfree(params_value); return ret; } @@ -4755,9 +4046,12 @@ done: int adm_get_source_tracking(int port_id, int copp_idx, struct source_tracking_param *sourceTrackingData) { - struct adm_cmd_get_pp_params_v5 admp; - int p_idx, ret = 0, i; - struct adm_param_fluence_sourcetracking_t *source_tracking_params; + struct adm_param_fluence_sourcetracking_t *source_tracking_params = + NULL; + struct mem_mapping_hdr mem_hdr = {0}; + struct param_hdr_v3 param_hdr = {0}; + int i = 0; + int ret = 0; pr_debug("%s: Enter, port_id %d, copp_idx %d\n", __func__, port_id, copp_idx); @@ -4771,68 +4065,34 @@ int adm_get_source_tracking(int port_id, int copp_idx, } } - port_id = afe_convert_virtual_to_portid(port_id); - p_idx = adm_validate_and_get_port_index(port_id); - if (p_idx < 0) { - pr_err("%s - invalid port index %i, port id %i, copp idx %i\n", - __func__, p_idx, port_id, copp_idx); - - ret = -EINVAL; - goto done; - } - - admp.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - admp.hdr.pkt_size = sizeof(admp); - admp.hdr.src_svc = APR_SVC_ADM; - admp.hdr.src_domain = APR_DOMAIN_APPS; - admp.hdr.src_port = port_id; - admp.hdr.dest_svc = APR_SVC_ADM; - admp.hdr.dest_domain = APR_DOMAIN_ADSP; - admp.hdr.dest_port = atomic_read(&this_adm.copp.id[p_idx][copp_idx]); - admp.hdr.token = p_idx << 16 | ADM_CLIENT_ID_SOURCE_TRACKING << 8 | - copp_idx; - admp.hdr.opcode = ADM_CMD_GET_PP_PARAMS_V5; - admp.data_payload_addr_lsw = + mem_hdr.data_payload_addr_lsw = lower_32_bits(this_adm.sourceTrackingData.memmap.paddr); - admp.data_payload_addr_msw = - msm_audio_populate_upper_32_bits( - this_adm.sourceTrackingData.memmap.paddr); - admp.mem_map_handle = atomic_read(&this_adm.mem_map_handles[ - ADM_MEM_MAP_INDEX_SOURCE_TRACKING]); - admp.module_id = VOICEPROC_MODULE_ID_GENERIC_TX; - admp.param_id = VOICEPROC_PARAM_ID_FLUENCE_SOURCETRACKING; - admp.param_max_size = sizeof(struct adm_param_fluence_sourcetracking_t) - + sizeof(struct adm_param_data_v5); - admp.reserved = 0; - - atomic_set(&this_adm.copp.stat[p_idx][copp_idx], -1); - - ret = apr_send_pkt(this_adm.apr, (uint32_t *)&admp); - if (ret < 0) { - pr_err("%s - failed to get Source Tracking Params\n", - __func__); - - ret = -EINVAL; - goto done; - } - ret = wait_event_timeout(this_adm.copp.wait[p_idx][copp_idx], - atomic_read(&this_adm.copp.stat[p_idx][copp_idx]) >= 0, - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s - get params timed out\n", __func__); + mem_hdr.data_payload_addr_msw = msm_audio_populate_upper_32_bits( + this_adm.sourceTrackingData.memmap.paddr); + mem_hdr.mem_map_handle = atomic_read( + &this_adm.mem_map_handles[ADM_MEM_MAP_INDEX_SOURCE_TRACKING]); + + param_hdr.module_id = VOICEPROC_MODULE_ID_GENERIC_TX; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = VOICEPROC_PARAM_ID_FLUENCE_SOURCETRACKING; + /* + * This size should be the max size of the calibration data + header. + * Use the union size to ensure max size is used. + */ + param_hdr.param_size = + sizeof(struct adm_param_fluence_sourcetracking_t) + + sizeof(union param_hdrs); - ret = -EINVAL; - goto done; - } else if (atomic_read(&this_adm.copp.stat - [p_idx][copp_idx]) > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_adm.copp.stat - [p_idx][copp_idx]))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_adm.copp.stat - [p_idx][copp_idx])); + /* + * Retrieving parameters out of band, so no need to provide a buffer for + * the returned parameter data as it will be at the memory location + * provided. + */ + ret = adm_get_pp_params(port_id, copp_idx, + ADM_CLIENT_ID_SOURCE_TRACKING, &mem_hdr, + ¶m_hdr, NULL); + if (ret) { + pr_err("%s: Failed to get params, error %d\n", __func__, ret); goto done; } @@ -4846,9 +4106,11 @@ int adm_get_source_tracking(int port_id, int copp_idx, goto done; } - source_tracking_params = (struct adm_param_fluence_sourcetracking_t *) - (this_adm.sourceTrackingData.memmap.kvaddr + - sizeof(struct adm_param_data_v5)); + /* How do we know what the param data was retrieved with for hdr size */ + source_tracking_params = + (struct adm_param_fluence_sourcetracking_t + *) (this_adm.sourceTrackingData.memmap.kvaddr + + sizeof(struct param_hdr_v1)); for (i = 0; i < MAX_SECTORS; i++) { sourceTrackingData->vad[i] = source_tracking_params->vad[i]; pr_debug("%s: vad[%d] = %d\n", @@ -4882,49 +4144,24 @@ done: static int __init adm_init(void) { int i = 0, j; - this_adm.apr = NULL; + this_adm.ec_ref_rx = -1; - this_adm.num_ec_ref_rx_chans = 0; - this_adm.ec_ref_rx_bit_width = 0; - this_adm.ec_ref_rx_sampling_rate = 0; - atomic_set(&this_adm.matrix_map_stat, 0); init_waitqueue_head(&this_adm.matrix_map_wait); - atomic_set(&this_adm.adm_stat, 0); init_waitqueue_head(&this_adm.adm_wait); for (i = 0; i < AFE_MAX_PORTS; i++) { for (j = 0; j < MAX_COPPS_PER_PORT; j++) { atomic_set(&this_adm.copp.id[i][j], RESET_COPP_ID); - atomic_set(&this_adm.copp.cnt[i][j], 0); - atomic_set(&this_adm.copp.topology[i][j], 0); - atomic_set(&this_adm.copp.mode[i][j], 0); - atomic_set(&this_adm.copp.stat[i][j], 0); - atomic_set(&this_adm.copp.rate[i][j], 0); - atomic_set(&this_adm.copp.channels[i][j], 0); - atomic_set(&this_adm.copp.bit_width[i][j], 0); - atomic_set(&this_adm.copp.app_type[i][j], 0); - atomic_set(&this_adm.copp.acdb_id[i][j], 0); init_waitqueue_head(&this_adm.copp.wait[i][j]); - atomic_set(&this_adm.copp.adm_delay_stat[i][j], 0); init_waitqueue_head( &this_adm.copp.adm_delay_wait[i][j]); - atomic_set(&this_adm.copp.topology[i][j], 0); - this_adm.copp.adm_delay[i][j] = 0; - this_adm.copp.adm_status[i][j] = 0; } } if (adm_init_cal_data()) pr_err("%s: could not init cal data!\n", __func__); - this_adm.sourceTrackingData.ion_client = NULL; - this_adm.sourceTrackingData.ion_handle = NULL; - this_adm.sourceTrackingData.memmap.size = 0; - this_adm.sourceTrackingData.memmap.kvaddr = NULL; - this_adm.sourceTrackingData.memmap.paddr = 0; this_adm.sourceTrackingData.apr_cmd_status = -1; - atomic_set(&this_adm.mem_map_handles[ADM_MEM_MAP_INDEX_SOURCE_TRACKING], - 0); return 0; } diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c index f0a78dc8aee8..93553f53d68b 100644 --- a/sound/soc/msm/qdsp6v2/q6afe.c +++ b/sound/soc/msm/qdsp6v2/q6afe.c @@ -23,6 +23,7 @@ #include <sound/apr_audio-v2.h> #include <sound/q6afe-v2.h> #include <sound/q6audio-v2.h> +#include <sound/q6common.h> #include "msm-pcm-routing-v2.h" #include <sound/audio_cal_utils.h> #include <sound/adsp_err.h> @@ -190,100 +191,125 @@ static void afe_callback_debug_print(struct apr_client_data *data) __func__, data->opcode, data->payload_size); } -static void av_dev_drift_afe_cb_handler(uint32_t *payload, +static void av_dev_drift_afe_cb_handler(uint32_t opcode, uint32_t *payload, uint32_t payload_size) { u32 param_id; - struct afe_av_dev_drift_get_param_resp *resp = - (struct afe_av_dev_drift_get_param_resp *) payload; - - if (!(&(resp->pdata))) { - pr_err("%s: Error: resp pdata is NULL\n", __func__); + size_t expected_size = + sizeof(u32) + sizeof(struct afe_param_id_dev_timing_stats); + + /* Get param ID depending on command type */ + param_id = (opcode == AFE_PORT_CMDRSP_GET_PARAM_V3) ? payload[3] : + payload[2]; + if (param_id != AFE_PARAM_ID_DEV_TIMING_STATS) { + pr_err("%s: Unrecognized param ID %d\n", __func__, param_id); return; } - param_id = resp->pdata.param_id; - if (param_id == AFE_PARAM_ID_DEV_TIMING_STATS) { - if (payload_size < sizeof(this_afe.av_dev_drift_resp)) { - pr_err("%s: Error: received size %d, resp size %zu\n", - __func__, payload_size, - sizeof(this_afe.av_dev_drift_resp)); + switch (opcode) { + case AFE_PORT_CMDRSP_GET_PARAM_V2: + expected_size += sizeof(struct param_hdr_v1); + if (payload_size < expected_size) { + pr_err("%s: Error: received size %d, expected size %zu\n", + __func__, payload_size, expected_size); + return; + } + /* Repack response to add IID */ + this_afe.av_dev_drift_resp.status = payload[0]; + this_afe.av_dev_drift_resp.pdata.module_id = payload[1]; + this_afe.av_dev_drift_resp.pdata.instance_id = INSTANCE_ID_0; + this_afe.av_dev_drift_resp.pdata.param_id = payload[2]; + this_afe.av_dev_drift_resp.pdata.param_size = payload[3]; + memcpy(&this_afe.av_dev_drift_resp.timing_stats, &payload[4], + sizeof(struct afe_param_id_dev_timing_stats)); + break; + case AFE_PORT_CMDRSP_GET_PARAM_V3: + expected_size += sizeof(struct param_hdr_v3); + if (payload_size < expected_size) { + pr_err("%s: Error: received size %d, expected size %zu\n", + __func__, payload_size, expected_size); return; } memcpy(&this_afe.av_dev_drift_resp, payload, sizeof(this_afe.av_dev_drift_resp)); - if (!this_afe.av_dev_drift_resp.status) { - atomic_set(&this_afe.state, 0); - } else { - pr_debug("%s: av_dev_drift_resp status: %d", __func__, - this_afe.av_dev_drift_resp.status); - atomic_set(&this_afe.state, -1); - } + break; + default: + pr_err("%s: Unrecognized command %d\n", __func__, opcode); + return; + } + + if (!this_afe.av_dev_drift_resp.status) { + atomic_set(&this_afe.state, 0); + } else { + pr_debug("%s: av_dev_drift_resp status: %d", __func__, + this_afe.av_dev_drift_resp.status); + atomic_set(&this_afe.state, -1); } } -static int32_t sp_make_afe_callback(uint32_t *payload, uint32_t payload_size) +static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload, + uint32_t payload_size) { - u32 param_id; - struct afe_spkr_prot_calib_get_resp *resp = - (struct afe_spkr_prot_calib_get_resp *) payload; - - if (!(&(resp->pdata))) { - pr_err("%s: Error: resp pdata is NULL\n", __func__); + struct param_hdr_v3 param_hdr = {0}; + u32 *data_dest = NULL; + u32 *data_start = NULL; + size_t expected_size = sizeof(u32); + + /* Set command specific details */ + switch (opcode) { + case AFE_PORT_CMDRSP_GET_PARAM_V2: + expected_size += sizeof(struct param_hdr_v1); + param_hdr.module_id = payload[1]; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = payload[2]; + param_hdr.param_size = payload[3]; + data_start = &payload[4]; + break; + case AFE_PORT_CMDRSP_GET_PARAM_V3: + expected_size += sizeof(struct param_hdr_v3); + memcpy(¶m_hdr, &payload[1], sizeof(struct param_hdr_v3)); + data_start = &payload[5]; + break; + default: + pr_err("%s: Unrecognized command %d\n", __func__, opcode); return -EINVAL; } - param_id = resp->pdata.param_id; - if (param_id == AFE_PARAM_ID_CALIB_RES_CFG_V2) { - if (payload_size < sizeof(this_afe.calib_data)) { - pr_err("%s: Error: received size %d, calib_data size %zu\n", - __func__, payload_size, - sizeof(this_afe.calib_data)); - return -EINVAL; - } - memcpy(&this_afe.calib_data, payload, - sizeof(this_afe.calib_data)); - if (!this_afe.calib_data.status) { - atomic_set(&this_afe.state, 0); - } else { - pr_debug("%s: calib resp status: %d", __func__, - this_afe.calib_data.status); - atomic_set(&this_afe.state, -1); - } + switch (param_hdr.param_id) { + case AFE_PARAM_ID_CALIB_RES_CFG_V2: + expected_size += sizeof(struct asm_calib_res_cfg); + data_dest = (u32 *) &this_afe.calib_data; + break; + case AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS: + expected_size += sizeof(struct afe_sp_th_vi_ftm_params); + data_dest = (u32 *) &this_afe.th_vi_resp; + break; + case AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS: + expected_size += sizeof(struct afe_sp_ex_vi_ftm_params); + data_dest = (u32 *) &this_afe.ex_vi_resp; + break; + default: + pr_err("%s: Unrecognized param ID %d\n", __func__, + param_hdr.param_id); + return -EINVAL; } - if (param_id == AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS) { - if (payload_size < sizeof(this_afe.th_vi_resp)) { - pr_err("%s: Error: received size %d, th_vi_resp size %zu\n", - __func__, payload_size, - sizeof(this_afe.th_vi_resp)); - return -EINVAL; - } - memcpy(&this_afe.th_vi_resp, payload, - sizeof(this_afe.th_vi_resp)); - if (!this_afe.th_vi_resp.status) { - atomic_set(&this_afe.state, 0); - } else { - pr_debug("%s: th vi resp status: %d", __func__, - this_afe.th_vi_resp.status); - atomic_set(&this_afe.state, -1); - } + + if (payload_size < expected_size) { + pr_err("%s: Error: received size %d, expected size %zu for param %d\n", + __func__, payload_size, expected_size, + param_hdr.param_id); + return -EINVAL; } - if (param_id == AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS) { - if (payload_size < sizeof(this_afe.ex_vi_resp)) { - pr_err("%s: Error: received size %d, ex_vi_resp size %zu\n", - __func__, payload_size, - sizeof(this_afe.ex_vi_resp)); - return -EINVAL; - } - memcpy(&this_afe.ex_vi_resp, payload, - sizeof(this_afe.ex_vi_resp)); - if (!this_afe.ex_vi_resp.status) { - atomic_set(&this_afe.state, 0); - } else { - pr_debug("%s: ex vi resp status: %d", __func__, - this_afe.ex_vi_resp.status); - atomic_set(&this_afe.state, -1); - } + + data_dest[0] = payload[0]; + memcpy(&data_dest[1], ¶m_hdr, sizeof(struct param_hdr_v3)); + memcpy(&data_dest[5], data_start, param_hdr.param_size); + + if (!data_dest[0]) { + atomic_set(&this_afe.state, 0); + } else { + pr_debug("%s: status: %d", __func__, data_dest[0]); + atomic_set(&this_afe.state, -1); } return 0; @@ -341,8 +367,10 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) return 0; } afe_callback_debug_print(data); - if (data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V2) { + if (data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V2 || + data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V3) { uint32_t *payload = data->payload; + uint32_t param_id; if (!payload || (data->token >= AFE_MAX_PORTS)) { pr_err("%s: Error: size %d payload %pK token %d\n", @@ -351,15 +379,18 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) return -EINVAL; } - if (payload[2] == AFE_PARAM_ID_DEV_TIMING_STATS) { - av_dev_drift_afe_cb_handler(data->payload, + param_id = (data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V3) ? + payload[3] : + payload[2]; + if (param_id == AFE_PARAM_ID_DEV_TIMING_STATS) { + av_dev_drift_afe_cb_handler(data->opcode, data->payload, data->payload_size); } else { if (rtac_make_afe_callback(data->payload, data->payload_size)) return 0; - if (sp_make_afe_callback(data->payload, + if (sp_make_afe_callback(data->opcode, data->payload, data->payload_size)) return -EINVAL; } @@ -380,8 +411,9 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) } switch (payload[0]) { case AFE_PORT_CMD_SET_PARAM_V2: + case AFE_PORT_CMD_SET_PARAM_V3: if (rtac_make_afe_callback(payload, - data->payload_size)) + data->payload_size)) return 0; case AFE_PORT_CMD_DEVICE_STOP: case AFE_PORT_CMD_DEVICE_START: @@ -392,6 +424,7 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) case AFE_SERVICE_CMD_UNREGISTER_RT_PORT_DRIVER: case AFE_PORTS_CMD_DTMF_CTL: case AFE_SVC_CMD_SET_PARAM: + case AFE_SVC_CMD_SET_PARAM_V2: atomic_set(&this_afe.state, 0); wake_up(&this_afe.wait[data->token]); break; @@ -409,6 +442,28 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv) pr_debug("%s: AFE_CMD_ADD_TOPOLOGIES cmd 0x%x\n", __func__, payload[1]); break; + case AFE_PORT_CMD_GET_PARAM_V2: + case AFE_PORT_CMD_GET_PARAM_V3: + /* + * Should only come here if there is an APR + * error or malformed APR packet. Otherwise + * response will be returned as + * AFE_PORT_CMDRSP_GET_PARAM_V2/3 + */ + pr_debug("%s: AFE Get Param opcode 0x%x token 0x%x src %d dest %d\n", + __func__, data->opcode, data->token, + data->src_port, data->dest_port); + if (payload[1] != 0) { + pr_err("%s: ADM Get Param failed with error %d\n", + __func__, payload[1]); + if (rtac_make_afe_callback( + payload, + data->payload_size)) + return 0; + } + atomic_set(&this_afe.state, payload[1]); + wake_up(&this_afe.wait[data->token]); + break; default: pr_err("%s: Unknown cmd 0x%x\n", __func__, payload[0]); @@ -749,11 +804,402 @@ static int afe_apr_send_pkt(void *data, wait_queue_head_t *wait) 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, + struct mem_mapping_hdr *mem_hdr, + u8 *packed_param_data, u32 packed_data_size) +{ + struct afe_port_cmd_set_param_v2 *set_param = NULL; + uint32_t size = sizeof(struct afe_port_cmd_set_param_v2); + int rc = 0; + + if (packed_param_data != NULL) + size += packed_data_size; + set_param = kzalloc(size, GFP_KERNEL); + if (set_param == NULL) + return -ENOMEM; + + set_param->apr_hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + set_param->apr_hdr.pkt_size = size; + set_param->apr_hdr.src_port = 0; + set_param->apr_hdr.dest_port = 0; + set_param->apr_hdr.token = index; + set_param->apr_hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + set_param->port_id = port_id; + if (packed_data_size > U16_MAX) { + pr_err("%s: Invalid data size for set params V2 %d\n", __func__, + packed_data_size); + rc = -EINVAL; + goto done; + } + set_param->payload_size = packed_data_size; + if (mem_hdr != NULL) { + set_param->mem_hdr = *mem_hdr; + } else if (packed_param_data != NULL) { + memcpy(&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_pkt(set_param, &this_afe.wait[index]); +done: + kfree(set_param); + return rc; +} + +/* This function shouldn't be called directly. Instead call q6afe_set_params. */ +static int q6afe_set_params_v3(u16 port_id, int index, + struct mem_mapping_hdr *mem_hdr, + u8 *packed_param_data, u32 packed_data_size) +{ + struct afe_port_cmd_set_param_v3 *set_param = NULL; + uint32_t size = sizeof(struct afe_port_cmd_set_param_v3); + int rc = 0; + + if (packed_param_data != NULL) + size += packed_data_size; + set_param = kzalloc(size, GFP_KERNEL); + if (set_param == NULL) + return -ENOMEM; + + set_param->apr_hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + set_param->apr_hdr.pkt_size = size; + set_param->apr_hdr.src_port = 0; + set_param->apr_hdr.dest_port = 0; + set_param->apr_hdr.token = index; + set_param->apr_hdr.opcode = AFE_PORT_CMD_SET_PARAM_V3; + set_param->port_id = port_id; + set_param->payload_size = packed_data_size; + if (mem_hdr != NULL) { + set_param->mem_hdr = *mem_hdr; + } else if (packed_param_data != NULL) { + memcpy(&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_pkt(set_param, &this_afe.wait[index]); +done: + kfree(set_param); + return rc; +} + +static int q6afe_set_params(u16 port_id, int index, + struct mem_mapping_hdr *mem_hdr, + u8 *packed_param_data, u32 packed_data_size) +{ + int ret = 0; + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + ; + } + + port_id = q6audio_get_port_id(port_id); + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: Not a valid port id = 0x%x ret %d\n", __func__, + port_id, ret); + return -EINVAL; + } + + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid\n", __func__, index); + return -EINVAL; + } + + if (q6common_is_instance_id_supported()) + return q6afe_set_params_v3(port_id, index, mem_hdr, + packed_param_data, packed_data_size); + else + return q6afe_set_params_v2(port_id, index, mem_hdr, + packed_param_data, packed_data_size); +} + +static int q6afe_pack_and_set_param_in_band(u16 port_id, int index, + struct param_hdr_v3 param_hdr, + u8 *param_data) +{ + u8 *packed_param_data = NULL; + int packed_data_size = sizeof(union param_hdrs) + param_hdr.param_size; + int ret; + + packed_param_data = kzalloc(packed_data_size, GFP_KERNEL); + if (packed_param_data == NULL) + return -ENOMEM; + + ret = q6common_pack_pp_params(packed_param_data, ¶m_hdr, param_data, + &packed_data_size); + if (ret) { + pr_err("%s: Failed to pack param header and data, error %d\n", + __func__, ret); + goto fail_cmd; + } + + ret = q6afe_set_params(port_id, index, NULL, packed_param_data, + packed_data_size); + +fail_cmd: + kfree(packed_param_data); + return ret; +} + +/* This function shouldn't be called directly. Instead call q6afe_get_param. */ +static int q6afe_get_params_v2(u16 port_id, int index, + struct mem_mapping_hdr *mem_hdr, + struct param_hdr_v3 *param_hdr) +{ + struct afe_port_cmd_get_param_v2 afe_get_param; + u32 param_size = param_hdr->param_size; + + memset(&afe_get_param, 0, sizeof(afe_get_param)); + afe_get_param.apr_hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + afe_get_param.apr_hdr.pkt_size = sizeof(afe_get_param) + param_size; + afe_get_param.apr_hdr.src_port = 0; + afe_get_param.apr_hdr.dest_port = 0; + afe_get_param.apr_hdr.token = index; + afe_get_param.apr_hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2; + afe_get_param.port_id = port_id; + afe_get_param.payload_size = sizeof(struct param_hdr_v1) + param_size; + if (mem_hdr != NULL) + afe_get_param.mem_hdr = *mem_hdr; + /* Set MID and PID in command */ + afe_get_param.module_id = param_hdr->module_id; + afe_get_param.param_id = param_hdr->param_id; + /* Set param header in payload */ + afe_get_param.param_hdr.module_id = param_hdr->module_id; + afe_get_param.param_hdr.param_id = param_hdr->param_id; + afe_get_param.param_hdr.param_size = param_size; + + return afe_apr_send_pkt(&afe_get_param, &this_afe.wait[index]); +} + +/* This function shouldn't be called directly. Instead call q6afe_get_param. */ +static int q6afe_get_params_v3(u16 port_id, int index, + struct mem_mapping_hdr *mem_hdr, + struct param_hdr_v3 *param_hdr) +{ + struct afe_port_cmd_get_param_v3 afe_get_param; + + memset(&afe_get_param, 0, sizeof(afe_get_param)); + afe_get_param.apr_hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + afe_get_param.apr_hdr.pkt_size = sizeof(afe_get_param); + afe_get_param.apr_hdr.src_port = 0; + afe_get_param.apr_hdr.dest_port = 0; + afe_get_param.apr_hdr.token = index; + afe_get_param.apr_hdr.opcode = AFE_PORT_CMD_GET_PARAM_V3; + afe_get_param.port_id = port_id; + if (mem_hdr != NULL) + afe_get_param.mem_hdr = *mem_hdr; + /* Set param header in command, no payload in V3 */ + afe_get_param.param_hdr = *param_hdr; + + return afe_apr_send_pkt(&afe_get_param, &this_afe.wait[index]); +} + +/* + * Calling functions copy param data directly from this_afe. Do not copy data + * back to caller here. + */ +static int q6afe_get_params(u16 port_id, struct mem_mapping_hdr *mem_hdr, + struct param_hdr_v3 *param_hdr) +{ + int index; + int ret; + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + + port_id = q6audio_get_port_id(port_id); + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: Not a valid port id = 0x%x ret %d\n", __func__, + port_id, ret); + return -EINVAL; + } + + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid\n", __func__, index); + return -EINVAL; + } + + if (q6common_is_instance_id_supported()) + return q6afe_get_params_v3(port_id, index, NULL, param_hdr); + else + return q6afe_get_params_v2(port_id, index, NULL, param_hdr); +} + +/* + * This function shouldn't be called directly. Instead call + * q6afe_svc_set_params. + */ +static int q6afe_svc_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 = IDX_GLOBAL_CFG; + 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_pkt(svc_set_param, &this_afe.wait[index]); +done: + kfree(svc_set_param); + return rc; +} + +/* + * This function shouldn't be called directly. Instead call + * q6afe_svc_set_params. + */ +static int q6afe_svc_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 = IDX_GLOBAL_CFG; + 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_pkt(svc_set_param, &this_afe.wait[index]); +done: + kfree(svc_set_param); + return rc; +} + +static int q6afe_svc_set_params(int index, struct mem_mapping_hdr *mem_hdr, + u8 *packed_param_data, u32 packed_data_size) +{ + int ret; + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + + if (q6common_is_instance_id_supported()) + return q6afe_svc_set_params_v2(index, mem_hdr, + packed_param_data, + packed_data_size); + else + return q6afe_svc_set_params_v1(index, mem_hdr, + packed_param_data, + packed_data_size); +} + +static int q6afe_svc_pack_and_set_param_in_band(int index, + struct param_hdr_v3 param_hdr, + u8 *param_data) +{ + u8 *packed_param_data = NULL; + u32 packed_data_size = + sizeof(struct param_hdr_v3) + param_hdr.param_size; + int ret = 0; + + packed_param_data = kzalloc(packed_data_size, GFP_KERNEL); + if (!packed_param_data) + return -ENOMEM; + + ret = q6common_pack_pp_params(packed_param_data, ¶m_hdr, param_data, + &packed_data_size); + if (ret) { + pr_err("%s: Failed to pack parameter header and data, error %d\n", + __func__, ret); + goto done; + } + + ret = q6afe_svc_set_params(index, NULL, packed_param_data, + packed_data_size); + +done: + kfree(packed_param_data); + return ret; +} + static int afe_send_cal_block(u16 port_id, struct cal_block_data *cal_block) { - int result = 0; - int index = 0; - struct afe_audioif_config_command_no_payload afe_cal; + struct mem_mapping_hdr mem_hdr = {0}; + int payload_size = 0; + int result = 0; if (!cal_block) { pr_debug("%s: No AFE cal to send!\n", __func__); @@ -766,34 +1212,19 @@ static int afe_send_cal_block(u16 port_id, struct cal_block_data *cal_block) goto done; } - index = q6audio_get_port_index(port_id); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - result = -EINVAL; - goto done; - } - - afe_cal.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - afe_cal.hdr.pkt_size = sizeof(afe_cal); - afe_cal.hdr.src_port = 0; - afe_cal.hdr.dest_port = 0; - afe_cal.hdr.token = index; - afe_cal.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - afe_cal.param.port_id = port_id; - afe_cal.param.payload_size = cal_block->cal_data.size; - afe_cal.param.payload_address_lsw = + payload_size = cal_block->cal_data.size; + mem_hdr.data_payload_addr_lsw = lower_32_bits(cal_block->cal_data.paddr); - afe_cal.param.payload_address_msw = + mem_hdr.data_payload_addr_msw = msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr); - afe_cal.param.mem_map_handle = cal_block->map_data.q6map_handle; + mem_hdr.mem_map_handle = cal_block->map_data.q6map_handle; pr_debug("%s: AFE cal sent for device port = 0x%x, cal size = %zd, cal addr = 0x%pK\n", __func__, port_id, cal_block->cal_data.size, &cal_block->cal_data.paddr); - result = afe_apr_send_pkt(&afe_cal, &this_afe.wait[index]); + result = q6afe_set_params(port_id, q6audio_get_port_index(port_id), + &mem_hdr, NULL, payload_size); if (result) pr_err("%s: AFE cal for port 0x%x failed %d\n", __func__, port_id, result); @@ -889,9 +1320,8 @@ unlock: static int afe_spk_ramp_dn_cfg(int port) { + struct param_hdr_v3 param_info = {0}; int ret = -EINVAL; - int index = 0; - struct afe_spkr_prot_config_command config; if (afe_get_port_type(port) != MSM_AFE_PORT_TYPE_RX) { pr_debug("%s: port doesn't match 0x%x\n", __func__, port); @@ -903,84 +1333,39 @@ static int afe_spk_ramp_dn_cfg(int port) __func__, port, ret, this_afe.vi_rx_port); return 0; } - memset(&config, 0 , sizeof(config)); - ret = q6audio_validate_port(port); - if (ret < 0) { - pr_err("%s: Invalid port 0x%x ret %d", __func__, port, ret); - ret = -EINVAL; - goto fail_cmd; - } - index = q6audio_get_port_index(port); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - ret = -EINVAL; - goto fail_cmd; - } - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = index; - - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = q6audio_get_port_id(port); - config.param.payload_size = - sizeof(config) - sizeof(config.hdr) - sizeof(config.param) - - sizeof(config.prot_config); - config.pdata.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX; - config.pdata.param_id = AFE_PARAM_ID_FBSP_PTONE_RAMP_CFG; - config.pdata.param_size = 0; - atomic_set(&this_afe.state, 1); - atomic_set(&this_afe.status, 0); - ret = apr_send_pkt(this_afe.apr, (uint32_t *) &config); - if (ret < 0) { - pr_err("%s: port = 0x%x param = 0x%x failed %d\n", - __func__, port, config.pdata.param_id, ret); - goto fail_cmd; - } - 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; - goto fail_cmd; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); + param_info.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = AFE_PARAM_ID_FBSP_PTONE_RAMP_CFG; + param_info.param_size = 0; + + ret = q6afe_pack_and_set_param_in_band(port, + q6audio_get_port_index(port), + param_info, NULL); + if (ret) { + pr_err("%s: Failed to set speaker ramp duration param, err %d\n", + __func__, ret); goto fail_cmd; } + /* dsp needs atleast 15ms to ramp down pilot tone*/ usleep_range(15000, 15010); ret = 0; fail_cmd: - pr_debug("%s: config.pdata.param_id 0x%x status %d\n", - __func__, config.pdata.param_id, ret); -return ret; + pr_debug("%s: config.pdata.param_id 0x%x status %d\n", __func__, + param_info.param_id, ret); + return ret; } static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id, - union afe_spkr_prot_config *prot_config) + union afe_spkr_prot_config *prot_config) { + struct param_hdr_v3 param_info = {0}; int ret = -EINVAL; - int index = 0; - struct afe_spkr_prot_config_command config; - memset(&config, 0 , sizeof(config)); - if (!prot_config) { - pr_err("%s: Invalid params\n", __func__); - goto fail_cmd; - } ret = q6audio_validate_port(src_port); if (ret < 0) { - pr_err("%s: Invalid src port 0x%x ret %d", - __func__, src_port, ret); + pr_err("%s: Invalid src port 0x%x ret %d", __func__, src_port, + ret); ret = -EINVAL; goto fail_cmd; } @@ -991,21 +1376,15 @@ static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id, ret = -EINVAL; goto fail_cmd; } - index = q6audio_get_port_index(src_port); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - ret = -EINVAL; - goto fail_cmd; - } + switch (param_id) { case AFE_PARAM_ID_FBSP_MODE_RX_CFG: - config.pdata.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX; + param_info.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX; break; case AFE_PARAM_ID_FEEDBACK_PATH_CFG: this_afe.vi_tx_port = src_port; this_afe.vi_rx_port = dst_port; - config.pdata.module_id = AFE_MODULE_FEEDBACK; + param_info.module_id = AFE_MODULE_FEEDBACK; break; /* * AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG_V2 is same as @@ -1013,11 +1392,11 @@ static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id, */ case AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG_V2: case AFE_PARAM_ID_SP_V2_TH_VI_FTM_CFG: - config.pdata.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI; + param_info.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI; break; case AFE_PARAM_ID_SP_V2_EX_VI_MODE_CFG: case AFE_PARAM_ID_SP_V2_EX_VI_FTM_CFG: - config.pdata.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI; + param_info.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI; break; default: pr_err("%s: default case 0x%x\n", __func__, param_id); @@ -1025,48 +1404,20 @@ static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id, break; } - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = index; - - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = q6audio_get_port_id(src_port); - config.param.payload_size = sizeof(config) - sizeof(config.hdr) - - sizeof(config.param); - config.pdata.param_id = param_id; - config.pdata.param_size = sizeof(config.prot_config); - config.prot_config = *prot_config; - atomic_set(&this_afe.state, 1); - atomic_set(&this_afe.status, 0); - ret = apr_send_pkt(this_afe.apr, (uint32_t *) &config); - if (ret < 0) { - pr_err("%s: port = 0x%x param = 0x%x failed %d\n", - __func__, src_port, param_id, ret); - goto fail_cmd; - } - 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; - goto fail_cmd; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); - goto fail_cmd; - } - ret = 0; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = param_id; + param_info.param_size = sizeof(union afe_spkr_prot_config); + + ret = q6afe_pack_and_set_param_in_band(src_port, + q6audio_get_port_index(src_port), + param_info, (u8 *) prot_config); + if (ret) + pr_err("%s: port = 0x%x param = 0x%x failed %d\n", __func__, + src_port, param_id, ret); + fail_cmd: - pr_debug("%s: config.pdata.param_id 0x%x status %d 0x%x\n", - __func__, config.pdata.param_id, ret, src_port); + pr_debug("%s: config.pdata.param_id 0x%x status %d 0x%x\n", __func__, + param_info.param_id, ret, src_port); return ret; } @@ -1212,14 +1563,13 @@ done: static int afe_send_hw_delay(u16 port_id, u32 rate) { - struct audio_cal_hw_delay_entry delay_entry; - struct afe_audioif_config_command config; - int index = 0; + struct audio_cal_hw_delay_entry delay_entry = {0}; + struct afe_param_id_device_hw_delay_cfg hw_delay; + struct param_hdr_v3 param_info = {0}; int ret = -EINVAL; pr_debug("%s:\n", __func__); - memset(&delay_entry, 0, sizeof(delay_entry)); delay_entry.sample_rate = rate; if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_TX) ret = afe_get_cal_hw_delay(TX_DEVICE, &delay_entry); @@ -1237,42 +1587,21 @@ static int afe_send_hw_delay(u16 port_id, u32 rate) goto fail_cmd; } - index = q6audio_get_port_index(port_id); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - ret = -EINVAL; - goto fail_cmd; - } + param_info.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = AFE_PARAM_ID_DEVICE_HW_DELAY; + param_info.param_size = sizeof(hw_delay); - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = index; - - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = q6audio_get_port_id(port_id); - config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - config.pdata.param_id = AFE_PARAM_ID_DEVICE_HW_DELAY; - config.pdata.param_size = sizeof(config.port); - - config.port.hw_delay.delay_in_us = delay_entry.delay_usec; - config.port.hw_delay.device_hw_delay_minor_version = - AFE_API_VERSION_DEVICE_HW_DELAY; - - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); - if (ret) { + hw_delay.delay_in_us = delay_entry.delay_usec; + hw_delay.device_hw_delay_minor_version = + AFE_API_VERSION_DEVICE_HW_DELAY; + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_info, (u8 *) &hw_delay); + if (ret) pr_err("%s: AFE hw delay for port 0x%x failed %d\n", __func__, port_id, ret); - goto fail_cmd; - } fail_cmd: pr_debug("%s: port_id 0x%x rate %u delay_usec %d status %d\n", @@ -1371,10 +1700,11 @@ unlock: static int afe_send_port_topology_id(u16 port_id) { - struct afe_audioif_config_command config; + struct afe_param_id_set_topology_cfg topology = {0}; + struct param_hdr_v3 param_info = {0}; + u32 topology_id = 0; int index = 0; int ret = 0; - u32 topology_id = 0; index = q6audio_get_port_index(port_id); if (index < 0 || index >= AFE_MAX_PORTS) { @@ -1390,32 +1720,17 @@ static int afe_send_port_topology_id(u16 port_id) goto done; } - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = index; - - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = q6audio_get_port_id(port_id); - config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - config.pdata.param_id = AFE_PARAM_ID_SET_TOPOLOGY; - config.pdata.param_size = sizeof(config.port); - config.port.topology.minor_version = AFE_API_VERSION_TOPOLOGY_V1; - config.port.topology.topology_id = topology_id; - - pr_debug("%s: param PL size=%d iparam_size[%d][%zd %zd %zd %zd] param_id[0x%x]\n", - __func__, config.param.payload_size, config.pdata.param_size, - sizeof(config), sizeof(config.param), sizeof(config.port), - sizeof(struct apr_hdr), config.pdata.param_id); - - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + param_info.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = AFE_PARAM_ID_SET_TOPOLOGY; + param_info.param_size = sizeof(topology); + + topology.minor_version = AFE_API_VERSION_TOPOLOGY_V1; + topology.topology_id = topology_id; + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_info, (u8 *) &topology); if (ret) { pr_err("%s: AFE set topology id enable for port 0x%x failed %d\n", __func__, port_id, ret); @@ -1568,33 +1883,24 @@ void afe_send_cal(u16 port_id) int afe_turn_onoff_hw_mad(u16 mad_type, u16 enable) { + struct afe_param_hw_mad_ctrl mad_enable_param = {0}; + struct param_hdr_v3 param_info = {0}; int ret; - struct afe_cmd_hw_mad_ctrl config; pr_debug("%s: enter\n", __func__); - memset(&config, 0, sizeof(config)); - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), - APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = IDX_GLOBAL_CFG; - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = SLIMBUS_5_TX; - config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_HW_MAD; - config.pdata.param_id = AFE_PARAM_ID_HW_MAD_CTRL; - config.pdata.param_size = sizeof(config.payload); - config.payload.minor_version = 1; - config.payload.mad_type = mad_type; - config.payload.mad_enable = enable; - - ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]); + + param_info.module_id = AFE_MODULE_HW_MAD; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = AFE_PARAM_ID_HW_MAD_CTRL; + param_info.param_size = sizeof(mad_enable_param); + + mad_enable_param.minor_version = 1; + mad_enable_param.mad_type = mad_type; + mad_enable_param.mad_enable = enable; + + ret = q6afe_pack_and_set_param_in_band(SLIMBUS_5_TX, IDX_GLOBAL_CFG, + param_info, + (u8 *) &mad_enable_param); if (ret) pr_err("%s: AFE_PARAM_ID_HW_MAD_CTRL failed %d\n", __func__, ret); @@ -1604,31 +1910,18 @@ int afe_turn_onoff_hw_mad(u16 mad_type, u16 enable) static int afe_send_slimbus_slave_cfg( struct afe_param_cdc_slimbus_slave_cfg *sb_slave_cfg) { + struct param_hdr_v3 param_hdr = {0}; int ret; - struct afe_svc_cmd_sb_slave_cfg config; pr_debug("%s: enter\n", __func__); - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), - APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = IDX_GLOBAL_CFG; - config.hdr.opcode = AFE_SVC_CMD_SET_PARAM; - config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_CDC_DEV_CFG; - config.pdata.param_id = AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG; - config.pdata.param_size = - sizeof(struct afe_param_cdc_slimbus_slave_cfg); - config.sb_slave_cfg = *sb_slave_cfg; - - ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]); + param_hdr.module_id = AFE_MODULE_CDC_DEV_CFG; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG; + param_hdr.param_size = sizeof(struct afe_param_cdc_slimbus_slave_cfg); + + ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr, + (u8 *) sb_slave_cfg); if (ret) pr_err("%s: AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG failed %d\n", __func__, ret); @@ -1640,29 +1933,16 @@ static int afe_send_slimbus_slave_cfg( static int afe_send_codec_reg_page_config( struct afe_param_cdc_reg_page_cfg *cdc_reg_page_cfg) { - struct afe_svc_cmd_cdc_reg_page_cfg config; + struct param_hdr_v3 param_hdr = {0}; int ret; - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), - APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = IDX_GLOBAL_CFG; - config.hdr.opcode = AFE_SVC_CMD_SET_PARAM; - config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_CDC_DEV_CFG; - config.pdata.param_id = AFE_PARAM_ID_CDC_REG_PAGE_CFG; - config.pdata.param_size = - sizeof(struct afe_param_cdc_reg_page_cfg); - config.cdc_reg_page_cfg = *cdc_reg_page_cfg; - - ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]); + param_hdr.module_id = AFE_MODULE_CDC_DEV_CFG; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_CDC_REG_PAGE_CFG; + param_hdr.param_size = sizeof(struct afe_param_cdc_reg_page_cfg); + + ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr, + (u8 *) cdc_reg_page_cfg); if (ret) pr_err("%s: AFE_PARAM_ID_CDC_REG_PAGE_CFG failed %d\n", __func__, ret); @@ -1673,186 +1953,116 @@ static int afe_send_codec_reg_page_config( static int afe_send_codec_reg_config( struct afe_param_cdc_reg_cfg_data *cdc_reg_cfg) { - int i, j, ret = -EINVAL; - int pkt_size, payload_size, reg_per_pkt, num_pkts, num_regs; - struct afe_svc_cmd_cdc_reg_cfg *config; - struct afe_svc_cmd_set_param *param; + u8 *packed_param_data = NULL; + u32 packed_data_size = 0; + u32 single_param_size = 0; + u32 max_data_size = 0; + u32 max_single_param = 0; + struct param_hdr_v3 param_hdr = {0}; + int idx = 0; + int ret = -EINVAL; - reg_per_pkt = (APR_MAX_BUF - sizeof(*config)) / - sizeof(struct afe_param_cdc_reg_cfg_payload); - if (reg_per_pkt > 0) { - num_pkts = (cdc_reg_cfg->num_registers / reg_per_pkt) + - (cdc_reg_cfg->num_registers % reg_per_pkt == 0 ? 0 : 1); - } else { - pr_err("%s: Failed to build codec reg config APR packet\n", - __func__); - return -EINVAL; - } + max_single_param = sizeof(struct param_hdr_v3) + + sizeof(struct afe_param_cdc_reg_cfg); + max_data_size = APR_MAX_BUF - sizeof(struct afe_svc_cmd_set_param_v2); + packed_param_data = kzalloc(max_data_size, GFP_KERNEL); + if (!packed_param_data) + return -ENOMEM; - for (j = 0; j < num_pkts; ++j) { - /* - * num_regs is set to reg_per_pkt on each pass through the loop - * except the last, when it is set to the number of registers - * remaining from the total - */ - num_regs = (j < (num_pkts - 1) ? reg_per_pkt : - cdc_reg_cfg->num_registers - (reg_per_pkt * j)); - payload_size = sizeof(struct afe_param_cdc_reg_cfg_payload) * - num_regs; - pkt_size = sizeof(*config) + payload_size; - pr_debug("%s: pkt_size %d, payload_size %d\n", __func__, - pkt_size, payload_size); - config = kzalloc(pkt_size, GFP_KERNEL); - if (!config) - return -ENOMEM; - - config->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), - APR_PKT_VER); - config->hdr.pkt_size = pkt_size; - config->hdr.src_port = 0; - config->hdr.dest_port = 0; - config->hdr.token = IDX_GLOBAL_CFG; - config->hdr.opcode = AFE_SVC_CMD_SET_PARAM; - - param = &config->param; - param->payload_size = payload_size; - param->payload_address_lsw = 0x00; - param->payload_address_msw = 0x00; - param->mem_map_handle = 0x00; - - for (i = 0; i < num_regs; i++) { - config->reg_data[i].common.module_id = - AFE_MODULE_CDC_DEV_CFG; - config->reg_data[i].common.param_id = - AFE_PARAM_ID_CDC_REG_CFG; - config->reg_data[i].common.param_size = - sizeof(config->reg_data[i].reg_cfg); - config->reg_data[i].reg_cfg = - cdc_reg_cfg->reg_data[i + (j * reg_per_pkt)]; + /* param_hdr is the same for all params sent, set once at top */ + param_hdr.module_id = AFE_MODULE_CDC_DEV_CFG; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_CDC_REG_CFG; + param_hdr.param_size = sizeof(struct afe_param_cdc_reg_cfg); + + while (idx < cdc_reg_cfg->num_registers) { + memset(packed_param_data, 0, max_data_size); + packed_data_size = 0; + single_param_size = 0; + + while (packed_data_size + max_single_param < max_data_size && + idx < cdc_reg_cfg->num_registers) { + ret = q6common_pack_pp_params( + packed_param_data + packed_data_size, + ¶m_hdr, (u8 *) &cdc_reg_cfg->reg_data[idx], + &single_param_size); + if (ret) { + pr_err("%s: Failed to pack parameters with error %d\n", + __func__, ret); + goto done; + } + packed_data_size += single_param_size; + idx++; } - ret = afe_apr_send_pkt(config, &this_afe.wait[IDX_GLOBAL_CFG]); + ret = q6afe_svc_set_params(IDX_GLOBAL_CFG, NULL, + packed_param_data, packed_data_size); if (ret) { pr_err("%s: AFE_PARAM_ID_CDC_REG_CFG failed %d\n", __func__, ret); - kfree(config); break; } - kfree(config); } - +done: + kfree(packed_param_data); return ret; } static int afe_init_cdc_reg_config(void) { + struct param_hdr_v3 param_hdr = {0}; int ret; - struct afe_svc_cmd_init_cdc_reg_cfg config; pr_debug("%s: enter\n", __func__); - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), - APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = IDX_GLOBAL_CFG; - config.hdr.opcode = AFE_SVC_CMD_SET_PARAM; - - config.param.payload_size = sizeof(struct afe_port_param_data_v2); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - - config.init.module_id = AFE_MODULE_CDC_DEV_CFG; - config.init.param_id = AFE_PARAM_ID_CDC_REG_CFG_INIT; - config.init.param_size = 0; - - ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]); - if (ret) { + param_hdr.module_id = AFE_MODULE_CDC_DEV_CFG; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_CDC_REG_CFG_INIT; + + ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr, + NULL); + if (ret) pr_err("%s: AFE_PARAM_ID_CDC_INIT_REG_CFG failed %d\n", __func__, ret); - } return ret; } static int afe_send_slimbus_slave_port_cfg( - struct afe_param_slimbus_slave_port_cfg *port_config, u16 port_id) + struct afe_param_slimbus_slave_port_cfg *slim_slave_config, u16 port_id) { - int ret, index; - struct afe_cmd_hw_mad_slimbus_slave_port_cfg config; + struct param_hdr_v3 param_hdr = {0}; + int ret; pr_debug("%s: enter, port_id = 0x%x\n", __func__, port_id); - index = q6audio_get_port_index(port_id); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - return -EINVAL; - } - ret = q6audio_validate_port(port_id); - if (ret < 0) { - pr_err("%s: port id = 0x%x ret %d\n", __func__, port_id, ret); - return -EINVAL; - } - - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), - APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = index; - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = port_id; - config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_HW_MAD; - config.pdata.param_id = AFE_PARAM_ID_SLIMBUS_SLAVE_PORT_CFG; - config.pdata.param_size = sizeof(*port_config); - config.sb_port_cfg = *port_config; - - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); - if (ret) { + param_hdr.module_id = AFE_MODULE_HW_MAD; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.reserved = 0; + param_hdr.param_id = AFE_PARAM_ID_SLIMBUS_SLAVE_PORT_CFG; + param_hdr.param_size = sizeof(struct afe_param_slimbus_slave_port_cfg); + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) slim_slave_config); + if (ret) pr_err("%s: AFE_PARAM_ID_SLIMBUS_SLAVE_PORT_CFG failed %d\n", __func__, ret); - } + pr_debug("%s: leave %d\n", __func__, ret); return ret; } static int afe_aanc_port_cfg(void *apr, uint16_t tx_port, uint16_t rx_port) { - struct afe_port_cmd_set_aanc_param cfg; + struct afe_param_aanc_port_cfg aanc_port_cfg = {0}; + struct param_hdr_v3 param_hdr = {0}; int ret = 0; - int index = 0; pr_debug("%s: tx_port 0x%x, rx_port 0x%x\n", __func__, tx_port, rx_port); - ret = afe_q6_interface_prepare(); - if (ret != 0) { - pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); - return -EINVAL; - } - - index = q6audio_get_port_index(tx_port); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - return -EINVAL; - } - ret = q6audio_validate_port(tx_port); - if (ret < 0) { - pr_err("%s: port id: 0x%x ret %d\n", __func__, tx_port, ret); - return -EINVAL; - } - pr_debug("%s: AANC sample rate tx rate: %d rx rate %d\n", - __func__, this_afe.aanc_info.aanc_tx_port_sample_rate, - this_afe.aanc_info.aanc_rx_port_sample_rate); + pr_debug("%s: AANC sample rate tx rate: %d rx rate %d\n", __func__, + this_afe.aanc_info.aanc_tx_port_sample_rate, + this_afe.aanc_info.aanc_rx_port_sample_rate); /* * If aanc tx sample rate or rx sample rate is zero, skip aanc * configuration as AFE resampler will fail for invalid sample @@ -1863,176 +2073,103 @@ static int afe_aanc_port_cfg(void *apr, uint16_t tx_port, uint16_t rx_port) return -EINVAL; } - cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - cfg.hdr.pkt_size = sizeof(cfg); - cfg.hdr.src_port = 0; - cfg.hdr.dest_port = 0; - cfg.hdr.token = index; - cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - - cfg.param.port_id = tx_port; - cfg.param.payload_size = sizeof(struct afe_port_param_data_v2) + - sizeof(struct afe_param_aanc_port_cfg); - cfg.param.payload_address_lsw = 0; - cfg.param.payload_address_msw = 0; - cfg.param.mem_map_handle = 0; + param_hdr.module_id = AFE_MODULE_AANC; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_AANC_PORT_CONFIG; + param_hdr.param_size = sizeof(struct afe_param_aanc_port_cfg); - cfg.pdata.module_id = AFE_MODULE_AANC; - cfg.pdata.param_id = AFE_PARAM_ID_AANC_PORT_CONFIG; - cfg.pdata.param_size = sizeof(struct afe_param_aanc_port_cfg); - cfg.pdata.reserved = 0; - - cfg.data.aanc_port_cfg.aanc_port_cfg_minor_version = + aanc_port_cfg.aanc_port_cfg_minor_version = AFE_API_VERSION_AANC_PORT_CONFIG; - cfg.data.aanc_port_cfg.tx_port_sample_rate = + aanc_port_cfg.tx_port_sample_rate = this_afe.aanc_info.aanc_tx_port_sample_rate; - cfg.data.aanc_port_cfg.tx_port_channel_map[0] = AANC_TX_VOICE_MIC; - cfg.data.aanc_port_cfg.tx_port_channel_map[1] = AANC_TX_NOISE_MIC; - cfg.data.aanc_port_cfg.tx_port_channel_map[2] = AANC_TX_ERROR_MIC; - cfg.data.aanc_port_cfg.tx_port_channel_map[3] = AANC_TX_MIC_UNUSED; - cfg.data.aanc_port_cfg.tx_port_channel_map[4] = AANC_TX_MIC_UNUSED; - cfg.data.aanc_port_cfg.tx_port_channel_map[5] = AANC_TX_MIC_UNUSED; - cfg.data.aanc_port_cfg.tx_port_channel_map[6] = AANC_TX_MIC_UNUSED; - cfg.data.aanc_port_cfg.tx_port_channel_map[7] = AANC_TX_MIC_UNUSED; - cfg.data.aanc_port_cfg.tx_port_num_channels = 3; - cfg.data.aanc_port_cfg.rx_path_ref_port_id = rx_port; - cfg.data.aanc_port_cfg.ref_port_sample_rate = - this_afe.aanc_info.aanc_rx_port_sample_rate; - - ret = afe_apr_send_pkt((uint32_t *) &cfg, &this_afe.wait[index]); - if (ret) { + aanc_port_cfg.tx_port_channel_map[0] = AANC_TX_VOICE_MIC; + aanc_port_cfg.tx_port_channel_map[1] = AANC_TX_NOISE_MIC; + aanc_port_cfg.tx_port_channel_map[2] = AANC_TX_ERROR_MIC; + aanc_port_cfg.tx_port_channel_map[3] = AANC_TX_MIC_UNUSED; + aanc_port_cfg.tx_port_channel_map[4] = AANC_TX_MIC_UNUSED; + aanc_port_cfg.tx_port_channel_map[5] = AANC_TX_MIC_UNUSED; + aanc_port_cfg.tx_port_channel_map[6] = AANC_TX_MIC_UNUSED; + aanc_port_cfg.tx_port_channel_map[7] = AANC_TX_MIC_UNUSED; + aanc_port_cfg.tx_port_num_channels = 3; + aanc_port_cfg.rx_path_ref_port_id = rx_port; + aanc_port_cfg.ref_port_sample_rate = + this_afe.aanc_info.aanc_rx_port_sample_rate; + + ret = q6afe_pack_and_set_param_in_band(tx_port, + q6audio_get_port_index(tx_port), + param_hdr, + (u8 *) &aanc_port_cfg); + if (ret) pr_err("%s: AFE AANC port config failed for tx_port 0x%x, rx_port 0x%x ret %d\n", - __func__, tx_port, rx_port, ret); - } + __func__, tx_port, rx_port, ret); return ret; } static int afe_aanc_mod_enable(void *apr, uint16_t tx_port, uint16_t enable) { - struct afe_port_cmd_set_aanc_param cfg; + struct afe_mod_enable_param mod_enable = {0}; + struct param_hdr_v3 param_hdr = {0}; int ret = 0; - int index = 0; - - pr_debug("%s: tx_port 0x%x\n", - __func__, tx_port); - - ret = afe_q6_interface_prepare(); - if (ret != 0) { - pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); - return -EINVAL; - } - - index = q6audio_get_port_index(tx_port); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - return -EINVAL; - } - ret = q6audio_validate_port(tx_port); - if (ret < 0) { - pr_err("%s: port id: 0x%x ret %d\n", __func__, tx_port, ret); - return -EINVAL; - } - - cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - cfg.hdr.pkt_size = sizeof(cfg); - cfg.hdr.src_port = 0; - cfg.hdr.dest_port = 0; - cfg.hdr.token = index; - cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - cfg.param.port_id = tx_port; - cfg.param.payload_size = sizeof(struct afe_port_param_data_v2) + - sizeof(struct afe_mod_enable_param); - cfg.param.payload_address_lsw = 0; - cfg.param.payload_address_lsw = 0; - cfg.param.mem_map_handle = 0; + pr_debug("%s: tx_port 0x%x\n", __func__, tx_port); - cfg.pdata.module_id = AFE_MODULE_AANC; - cfg.pdata.param_id = AFE_PARAM_ID_ENABLE; - cfg.pdata.param_size = sizeof(struct afe_mod_enable_param); - cfg.pdata.reserved = 0; + param_hdr.module_id = AFE_MODULE_AANC; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_ENABLE; + param_hdr.param_size = sizeof(struct afe_mod_enable_param); - cfg.data.mod_enable.enable = enable; - cfg.data.mod_enable.reserved = 0; + mod_enable.enable = enable; + mod_enable.reserved = 0; - ret = afe_apr_send_pkt((uint32_t *) &cfg, &this_afe.wait[index]); - if (ret) { + ret = q6afe_pack_and_set_param_in_band(tx_port, + q6audio_get_port_index(tx_port), + param_hdr, (u8 *) &mod_enable); + if (ret) pr_err("%s: AFE AANC enable failed for tx_port 0x%x ret %d\n", __func__, tx_port, ret); - } return ret; } static int afe_send_bank_selection_clip( struct afe_param_id_clip_bank_sel *param) { + struct param_hdr_v3 param_hdr = {0}; int ret; - struct afe_svc_cmd_set_clip_bank_selection config; + if (!param) { pr_err("%s: Invalid params", __func__); return -EINVAL; } - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = IDX_GLOBAL_CFG; - config.hdr.opcode = AFE_SVC_CMD_SET_PARAM; - - config.param.payload_size = sizeof(struct afe_port_param_data_v2) + - sizeof(struct afe_param_id_clip_bank_sel); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - - config.pdata.module_id = AFE_MODULE_CDC_DEV_CFG; - config.pdata.param_id = AFE_PARAM_ID_CLIP_BANK_SEL_CFG; - config.pdata.param_size = - sizeof(struct afe_param_id_clip_bank_sel); - config.bank_sel = *param; - ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]); - if (ret) { + param_hdr.module_id = AFE_MODULE_CDC_DEV_CFG; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_CLIP_BANK_SEL_CFG; + param_hdr.param_size = sizeof(struct afe_param_id_clip_bank_sel); + + ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr, + (u8 *) param); + if (ret) pr_err("%s: AFE_PARAM_ID_CLIP_BANK_SEL_CFG failed %d\n", __func__, ret); - } return ret; } int afe_send_aanc_version( struct afe_param_id_cdc_aanc_version *version_cfg) { + struct param_hdr_v3 param_hdr = {0}; int ret; - struct afe_svc_cmd_cdc_aanc_version config; pr_debug("%s: enter\n", __func__); - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = IDX_GLOBAL_CFG; - config.hdr.opcode = AFE_SVC_CMD_SET_PARAM; - - config.param.payload_size = sizeof(struct afe_port_param_data_v2) + - sizeof(struct afe_param_id_cdc_aanc_version); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - - config.pdata.module_id = AFE_MODULE_CDC_DEV_CFG; - config.pdata.param_id = AFE_PARAM_ID_CDC_AANC_VERSION; - config.pdata.param_size = - sizeof(struct afe_param_id_cdc_aanc_version); - config.version = *version_cfg; - ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]); - if (ret) { + param_hdr.module_id = AFE_MODULE_CDC_DEV_CFG; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_CDC_AANC_VERSION; + param_hdr.param_size = sizeof(struct afe_param_id_cdc_aanc_version); + + ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr, + (u8 *) version_cfg); + if (ret) pr_err("%s: AFE_PARAM_ID_CDC_AANC_VERSION failed %d\n", __func__, ret); - } return ret; } @@ -2139,166 +2276,54 @@ bool afe_has_config(enum afe_config_type config) int afe_send_spdif_clk_cfg(struct afe_param_id_spdif_clk_cfg *cfg, u16 port_id) { - struct afe_spdif_clk_config_command clk_cfg; + struct afe_param_id_spdif_clk_cfg clk_cfg = {0}; + struct param_hdr_v3 param_hdr = {0}; int ret = 0; - int index = 0; if (!cfg) { pr_err("%s: Error, no configuration data\n", __func__); - ret = -EINVAL; - return ret; - } - index = q6audio_get_port_index(port_id); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - return -EINVAL; - } - ret = q6audio_validate_port(port_id); - if (ret < 0) { - pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret); return -EINVAL; } - ret = afe_q6_interface_prepare(); - if (ret) { - pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); - return ret; - } - clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - clk_cfg.hdr.pkt_size = sizeof(clk_cfg); - clk_cfg.hdr.src_port = 0; - clk_cfg.hdr.dest_port = 0; - clk_cfg.hdr.token = index; - - clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - clk_cfg.param.port_id = q6audio_get_port_id(port_id); - clk_cfg.param.payload_address_lsw = 0x00; - clk_cfg.param.payload_address_msw = 0x00; - clk_cfg.param.mem_map_handle = 0x00; - clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - clk_cfg.pdata.param_id = AFE_PARAM_ID_SPDIF_CLK_CONFIG; - clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg); - clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr) - - sizeof(clk_cfg.param); - clk_cfg.clk_cfg = *cfg; - - pr_debug("%s: Minor version = 0x%x clk val = %d\n" - "clk root = 0x%x\n port id = 0x%x\n", - __func__, cfg->clk_cfg_minor_version, - cfg->clk_value, cfg->clk_root, - q6audio_get_port_id(port_id)); + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_SPDIF_CLK_CONFIG; + param_hdr.param_size = sizeof(struct afe_param_id_spdif_clk_cfg); - atomic_set(&this_afe.state, 1); - atomic_set(&this_afe.status, 0); - ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg); - if (ret < 0) { + pr_debug("%s: Minor version = 0x%x clk val = %d clk root = 0x%x port id = 0x%x\n", + __func__, clk_cfg.clk_cfg_minor_version, clk_cfg.clk_value, + clk_cfg.clk_root, q6audio_get_port_id(port_id)); + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &clk_cfg); + if (ret < 0) pr_err("%s: AFE send clock config for port 0x%x failed ret = %d\n", __func__, port_id, ret); - ret = -EINVAL; - goto fail_cmd; - } - - 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; - goto fail_cmd; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); - goto fail_cmd; - } - -fail_cmd: return ret; } int afe_send_spdif_ch_status_cfg(struct afe_param_id_spdif_ch_status_cfg *ch_status_cfg, u16 port_id) { - struct afe_spdif_chstatus_config_command ch_status; + struct param_hdr_v3 param_hdr = {0}; int ret = 0; - int index = 0; - if (!ch_status_cfg) { + if (!ch_status_cfg) pr_err("%s: Error, no configuration data\n", __func__); - ret = -EINVAL; - return ret; - } - index = q6audio_get_port_index(port_id); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - return -EINVAL; - } - ret = q6audio_validate_port(port_id); - if (ret < 0) { - pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret); - return -EINVAL; - } + return -EINVAL; - ret = afe_q6_interface_prepare(); - if (ret != 0) { - pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); - return ret; - } - ch_status.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - ch_status.hdr.pkt_size = sizeof(ch_status_cfg); - ch_status.hdr.src_port = 0; - ch_status.hdr.dest_port = 0; - ch_status.hdr.token = index; - - ch_status.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - ch_status.param.port_id = q6audio_get_port_id(port_id); - ch_status.param.payload_address_lsw = 0x00; - ch_status.param.payload_address_msw = 0x00; - ch_status.param.mem_map_handle = 0x00; - ch_status.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - ch_status.pdata.param_id = AFE_PARAM_ID_SPDIF_CLK_CONFIG; - ch_status.pdata.param_size = sizeof(ch_status.ch_status); - ch_status.param.payload_size = sizeof(ch_status) - - sizeof(struct apr_hdr) - sizeof(ch_status.param); - ch_status.ch_status = *ch_status_cfg; + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_SPDIF_CLK_CONFIG; + param_hdr.param_size = sizeof(struct afe_param_id_spdif_ch_status_cfg); - atomic_set(&this_afe.state, 1); - atomic_set(&this_afe.status, 0); - ret = apr_send_pkt(this_afe.apr, (uint32_t *) &ch_status); - if (ret < 0) { + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) ch_status_cfg); + if (ret < 0) pr_err("%s: AFE send channel status for port 0x%x failed ret = %d\n", __func__, port_id, ret); - ret = -EINVAL; - goto fail_cmd; - } - - 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; - goto fail_cmd; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); - goto fail_cmd; - } - -fail_cmd: return ret; } @@ -2366,10 +2391,9 @@ fail_cmd: int afe_spdif_port_start(u16 port_id, struct afe_spdif_port_config *spdif_port, u32 rate) { - struct afe_audioif_config_command config; - int ret = 0; - int index = 0; + struct param_hdr_v3 param_hdr = {0}; uint16_t port_index; + int ret = 0; if (!spdif_port) { pr_err("%s: Error, no configuration data\n", __func__); @@ -2379,12 +2403,6 @@ int afe_spdif_port_start(u16 port_id, struct afe_spdif_port_config *spdif_port, pr_debug("%s: port id: 0x%x\n", __func__, port_id); - index = q6audio_get_port_index(port_id); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - return -EINVAL; - } ret = q6audio_validate_port(port_id); if (ret < 0) { pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret); @@ -2394,24 +2412,14 @@ int afe_spdif_port_start(u16 port_id, struct afe_spdif_port_config *spdif_port, afe_send_cal(port_id); afe_send_hw_delay(port_id, rate); - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = index; - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = q6audio_get_port_id(port_id); - config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - config.pdata.param_id = AFE_PARAM_ID_SPDIF_CONFIG; - config.pdata.param_size = sizeof(config.port); - config.port.spdif = spdif_port->cfg; - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_SPDIF_CONFIG; + param_hdr.param_size = sizeof(struct afe_spdif_port_config); + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) spdif_port); if (ret) { pr_err("%s: AFE enable for port 0x%x failed ret = %d\n", __func__, port_id, ret); @@ -2443,9 +2451,8 @@ int afe_send_slot_mapping_cfg( struct afe_param_id_slot_mapping_cfg *slot_mapping_cfg, u16 port_id) { - struct afe_slot_mapping_config_command config; + struct param_hdr_v3 param_hdr = {0}; int ret = 0; - int index = 0; if (!slot_mapping_cfg) { pr_err("%s: Error, no configuration data\n", __func__); @@ -2454,67 +2461,18 @@ int afe_send_slot_mapping_cfg( pr_debug("%s: port id: 0x%x\n", __func__, port_id); - index = q6audio_get_port_index(port_id); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - return -EINVAL; - } - ret = q6audio_validate_port(port_id); - if (ret < 0) { - pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret); - return -EINVAL; - } - - memset(&config, 0, sizeof(config)); - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = index; - - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = q6audio_get_port_id(port_id); - config.param.payload_size = sizeof(config) - - sizeof(struct apr_hdr) - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_TDM; - config.pdata.param_id = AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG; - config.pdata.param_size = sizeof(config.slot_mapping); - config.slot_mapping = *slot_mapping_cfg; + param_hdr.module_id = AFE_MODULE_TDM; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG; + param_hdr.param_size = sizeof(struct afe_param_id_slot_mapping_cfg); - atomic_set(&this_afe.state, 1); - atomic_set(&this_afe.status, 0); - ret = apr_send_pkt(this_afe.apr, (uint32_t *) &config); - if (ret < 0) { + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) slot_mapping_cfg); + if (ret < 0) pr_err("%s: AFE send slot mapping for port 0x%x failed ret = %d\n", __func__, port_id, ret); - ret = -EINVAL; - goto fail_cmd; - } - - 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; - goto fail_cmd; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); - goto fail_cmd; - } - -fail_cmd: return ret; } @@ -2522,9 +2480,8 @@ int afe_send_custom_tdm_header_cfg( struct afe_param_id_custom_tdm_header_cfg *custom_tdm_header_cfg, u16 port_id) { - struct afe_custom_tdm_header_config_command config; + struct param_hdr_v3 param_hdr = {0}; int ret = 0; - int index = 0; if (!custom_tdm_header_cfg) { pr_err("%s: Error, no configuration data\n", __func__); @@ -2533,78 +2490,30 @@ int afe_send_custom_tdm_header_cfg( pr_debug("%s: port id: 0x%x\n", __func__, port_id); - index = q6audio_get_port_index(port_id); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - return -EINVAL; - } - ret = q6audio_validate_port(port_id); - if (ret < 0) { - pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret); - return -EINVAL; - } + param_hdr.module_id = AFE_MODULE_TDM; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_CUSTOM_TDM_HEADER_CONFIG; + param_hdr.param_size = + sizeof(struct afe_param_id_custom_tdm_header_cfg); - memset(&config, 0, sizeof(config)); - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = index; - - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = q6audio_get_port_id(port_id); - config.param.payload_size = sizeof(config) - - sizeof(struct apr_hdr) - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_TDM; - config.pdata.param_id = AFE_PARAM_ID_CUSTOM_TDM_HEADER_CONFIG; - config.pdata.param_size = sizeof(config.custom_tdm_header); - config.custom_tdm_header = *custom_tdm_header_cfg; - - atomic_set(&this_afe.state, 1); - atomic_set(&this_afe.status, 0); - ret = apr_send_pkt(this_afe.apr, (uint32_t *) &config); - if (ret < 0) { + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) custom_tdm_header_cfg); + if (ret < 0) pr_err("%s: AFE send custom tdm header for port 0x%x failed ret = %d\n", __func__, port_id, ret); - ret = -EINVAL; - goto fail_cmd; - } - - 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; - goto fail_cmd; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); - goto fail_cmd; - } - -fail_cmd: return ret; } int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port, u32 rate, u16 num_groups) { - struct afe_audioif_config_command config; - int ret = 0; + struct param_hdr_v3 param_hdr = {0}; int index = 0; uint16_t port_index = 0; enum afe_mad_type mad_type = MAD_HW_NONE; + int ret = 0; if (!tdm_port) { pr_err("%s: Error, no configuration data\n", __func__); @@ -2669,26 +2578,15 @@ int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port, } } - memset(&config, 0, sizeof(config)); - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = index; - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = q6audio_get_port_id(port_id); - config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - config.pdata.param_id = AFE_PARAM_ID_TDM_CONFIG; - config.pdata.param_size = sizeof(config.port); - config.port.tdm = tdm_port->tdm; - - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_TDM_CONFIG; + param_hdr.param_size = sizeof(struct afe_param_id_tdm_cfg); + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &tdm_port->tdm); if (ret) { pr_err("%s: AFE enable for port 0x%x failed ret = %d\n", __func__, port_id, ret); @@ -2743,61 +2641,45 @@ void afe_set_routing_callback(routing_cb cb) int afe_port_send_usb_dev_param(u16 port_id, union afe_port_config *afe_config) { - struct afe_usb_audio_dev_param_command config; - int ret = 0, index = 0; + struct afe_param_id_usb_audio_dev_params usb_dev = {0}; + struct afe_param_id_usb_audio_dev_lpcm_fmt lpcm_fmt = {0}; + struct param_hdr_v3 param_hdr = {0}; + int ret = 0; if (!afe_config) { pr_err("%s: Error, no configuration data\n", __func__); ret = -EINVAL; goto exit; } - index = q6audio_get_port_index(port_id); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid! for port ID 0x%x\n", - __func__, index, port_id); - ret = -EINVAL; - goto exit; - } - memset(&config, 0, sizeof(config)); - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = index; - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = q6audio_get_port_id(port_id); - config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - config.pdata.param_id = AFE_PARAM_ID_USB_AUDIO_DEV_PARAMS; - config.pdata.param_size = sizeof(config.usb_dev); - config.usb_dev.cfg_minor_version = - AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG; - config.usb_dev.dev_token = afe_config->usb_audio.dev_token; - - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + + param_hdr.param_id = AFE_PARAM_ID_USB_AUDIO_DEV_PARAMS; + param_hdr.param_size = sizeof(usb_dev); + usb_dev.cfg_minor_version = AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG; + usb_dev.dev_token = afe_config->usb_audio.dev_token; + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &usb_dev); if (ret) { pr_err("%s: AFE device param cmd failed %d\n", __func__, ret); - ret = -EINVAL; goto exit; } - config.pdata.param_id = AFE_PARAM_ID_USB_AUDIO_DEV_LPCM_FMT; - config.pdata.param_size = sizeof(config.lpcm_fmt); - config.lpcm_fmt.cfg_minor_version = - AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG; - config.lpcm_fmt.endian = afe_config->usb_audio.endian; + param_hdr.param_id = AFE_PARAM_ID_USB_AUDIO_DEV_LPCM_FMT; + param_hdr.param_size = sizeof(lpcm_fmt); + lpcm_fmt.cfg_minor_version = AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG; + lpcm_fmt.endian = afe_config->usb_audio.endian; - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &lpcm_fmt); if (ret) { pr_err("%s: AFE device param cmd LPCM_FMT failed %d\n", __func__, ret); - ret = -EINVAL; goto exit; } @@ -2810,11 +2692,12 @@ static int q6afe_send_enc_config(u16 port_id, union afe_port_config afe_config, u16 afe_in_channels, u16 afe_in_bit_width) { - struct afe_audioif_config_command config; - int index; + u32 enc_fmt; + struct afe_enc_cfg_blk_param_t enc_blk_param = {0}; + struct avs_enc_packetizer_id_param_t enc_pkt_id_param = {0}; + struct afe_port_media_type_t media_type = {0}; + struct param_hdr_v3 param_hdr = {0}; int ret; - int payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param) - sizeof(config.port); pr_debug("%s:update DSP for enc format = %d\n", __func__, format); if (format != ASM_MEDIA_FMT_SBC && format != ASM_MEDIA_FMT_AAC_V2 && @@ -2822,94 +2705,76 @@ static int q6afe_send_enc_config(u16 port_id, pr_err("%s:Unsuppported format Ignore AFE config\n", __func__); return 0; } - memset(&config, 0, sizeof(config)); - index = q6audio_get_port_index(port_id); - if (index < 0) { - pr_err("%s: Invalid index number: %d\n", __func__, index); - return -EINVAL; - } - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = index; - - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = q6audio_get_port_id(port_id); - config.param.payload_size = payload_size + sizeof(config.port.enc_fmt); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_ID_ENCODER; - config.pdata.param_id = AFE_ENCODER_PARAM_ID_ENC_FMT_ID; - config.pdata.param_size = sizeof(config.port.enc_fmt); - config.port.enc_fmt.fmt_id = format; - pr_debug("%s:sending AFE_ENCODER_PARAM_ID_ENC_FMT_ID payload: %d\n", - __func__, config.param.payload_size); - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + param_hdr.module_id = AFE_MODULE_ID_ENCODER; + param_hdr.instance_id = INSTANCE_ID_0; + + param_hdr.param_id = AFE_ENCODER_PARAM_ID_ENC_FMT_ID; + param_hdr.param_size = sizeof(enc_fmt); + enc_fmt = format; + pr_debug("%s:sending AFE_ENCODER_PARAM_ID_ENC_FMT_ID payload\n", + __func__); + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &enc_fmt); if (ret) { pr_err("%s:unable to send AFE_ENCODER_PARAM_ID_ENC_FMT_ID", __func__); goto exit; } - config.param.payload_size = payload_size - + sizeof(config.port.enc_blk_param); - pr_debug("%s:send AFE_ENCODER_PARAM_ID_ENC_CFG_BLK to DSP payload:%d\n", - __func__, config.param.payload_size); - config.pdata.param_id = AFE_ENCODER_PARAM_ID_ENC_CFG_BLK; - config.pdata.param_size = sizeof(config.port.enc_blk_param); - config.port.enc_blk_param.enc_cfg_blk_size = - sizeof(config.port.enc_blk_param.enc_blk_config); - config.port.enc_blk_param.enc_blk_config = *cfg; - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + pr_debug("%s:send AFE_ENCODER_PARAM_ID_ENC_CFG_BLK to DSP payloadn", + __func__); + param_hdr.param_id = AFE_ENCODER_PARAM_ID_ENC_CFG_BLK; + param_hdr.param_size = sizeof(struct afe_enc_cfg_blk_param_t); + enc_blk_param.enc_cfg_blk_size = sizeof(union afe_enc_config_data); + enc_blk_param.enc_blk_config = *cfg; + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &enc_blk_param); if (ret) { pr_err("%s: AFE_ENCODER_PARAM_ID_ENC_CFG_BLK for port 0x%x failed %d\n", __func__, port_id, ret); goto exit; } - config.param.payload_size = - payload_size + sizeof(config.port.enc_pkt_id_param); - pr_debug("%s:sending AFE_ENCODER_PARAM_ID_PACKETIZER to DSP payload = %d", - __func__, config.param.payload_size); - config.pdata.param_id = AFE_ENCODER_PARAM_ID_PACKETIZER_ID; - config.pdata.param_size = sizeof(config.port.enc_pkt_id_param); - config.port.enc_pkt_id_param.enc_packetizer_id = - AFE_MODULE_ID_PACKETIZER_COP; - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + pr_debug("%s:sending AFE_ENCODER_PARAM_ID_PACKETIZER to DSP\n", + __func__); + param_hdr.param_id = AFE_ENCODER_PARAM_ID_PACKETIZER_ID; + param_hdr.param_size = sizeof(struct avs_enc_packetizer_id_param_t); + enc_pkt_id_param.enc_packetizer_id = AFE_MODULE_ID_PACKETIZER_COP; + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &enc_pkt_id_param); if (ret) { pr_err("%s: AFE_ENCODER_PARAM_ID_PACKETIZER for port 0x%x failed %d\n", __func__, port_id, ret); goto exit; } - config.param.payload_size = - payload_size + sizeof(config.port.media_type); - config.pdata.param_size = sizeof(config.port.media_type); - pr_debug("%s:Sending AFE_API_VERSION_PORT_MEDIA_TYPE to DSP", __func__); - config.pdata.module_id = AFE_MODULE_PORT; - config.pdata.param_id = AFE_PARAM_ID_PORT_MEDIA_TYPE; - config.port.media_type.minor_version = AFE_API_VERSION_PORT_MEDIA_TYPE; - config.port.media_type.sample_rate = afe_config.slim_sch.sample_rate; + param_hdr.module_id = AFE_MODULE_PORT; + param_hdr.param_id = AFE_PARAM_ID_PORT_MEDIA_TYPE; + param_hdr.param_size = sizeof(struct afe_port_media_type_t); + media_type.minor_version = AFE_API_VERSION_PORT_MEDIA_TYPE; + media_type.sample_rate = afe_config.slim_sch.sample_rate; if (afe_in_bit_width) - config.port.media_type.bit_width = afe_in_bit_width; + media_type.bit_width = afe_in_bit_width; else - config.port.media_type.bit_width = - afe_config.slim_sch.bit_width; + media_type.bit_width = afe_config.slim_sch.bit_width; if (afe_in_channels) - config.port.media_type.num_channels = afe_in_channels; + media_type.num_channels = afe_in_channels; else - config.port.media_type.num_channels = - afe_config.slim_sch.num_channels; - config.port.media_type.data_format = AFE_PORT_DATA_FORMAT_PCM; - config.port.media_type.reserved = 0; + media_type.num_channels = afe_config.slim_sch.num_channels; + media_type.data_format = AFE_PORT_DATA_FORMAT_PCM; + media_type.reserved = 0; - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &media_type); if (ret) { pr_err("%s: AFE_API_VERSION_PORT_MEDIA_TYPE for port 0x%x failed %d\n", __func__, port_id, ret); @@ -2924,13 +2789,16 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, u32 rate, u16 afe_in_channels, u16 afe_in_bit_width, union afe_enc_config_data *cfg, u32 enc_format) { - struct afe_audioif_config_command config; + union afe_port_config port_cfg; + struct param_hdr_v3 param_hdr = {0}; int ret = 0; int cfg_type; int index = 0; enum afe_mad_type mad_type; uint16_t port_index; + memset(&port_cfg, 0, sizeof(port_cfg)); + if (!afe_config) { pr_err("%s: Error, no configuration data\n", __func__); ret = -EINVAL; @@ -3051,13 +2919,6 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, } } - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = index; - switch (port_id) { case AFE_PORT_ID_PRIMARY_PCM_RX: case AFE_PORT_ID_PRIMARY_PCM_TX: @@ -3153,24 +3014,21 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config, ret = -EINVAL; goto fail_cmd; } - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = q6audio_get_port_id(port_id); - config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - config.pdata.param_id = cfg_type; - config.pdata.param_size = sizeof(config.port); - - config.port = *afe_config; + + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = cfg_type; + param_hdr.param_size = sizeof(union afe_port_config); + + port_cfg = *afe_config; if ((enc_format != ASM_MEDIA_FMT_NONE) && (cfg_type == AFE_PARAM_ID_SLIMBUS_CONFIG)) { - config.port.slim_sch.data_format = - AFE_SB_DATA_FORMAT_GENERIC_COMPRESSED; + port_cfg.slim_sch.data_format = + AFE_SB_DATA_FORMAT_GENERIC_COMPRESSED; } - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &port_cfg); if (ret) { pr_err("%s: AFE enable for port 0x%x failed %d\n", __func__, port_id, ret); @@ -3515,11 +3373,15 @@ int afe_open(u16 port_id, union afe_port_config *afe_config, int rate) { struct afe_port_cmd_device_start start; - struct afe_audioif_config_command config; + union afe_port_config port_cfg; + struct param_hdr_v3 param_hdr = {0}; int ret = 0; int cfg_type; int index = 0; + memset(&start, 0, sizeof(start)); + memset(&port_cfg, 0, sizeof(port_cfg)); + if (!afe_config) { pr_err("%s: Error, no configuration data\n", __func__); ret = -EINVAL; @@ -3574,12 +3436,6 @@ int afe_open(u16 port_id, } mutex_lock(&this_afe.afe_cmd_lock); - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = index; switch (port_id) { case PRIMARY_I2S_RX: case PRIMARY_I2S_TX: @@ -3641,24 +3497,16 @@ int afe_open(u16 port_id, ret = -EINVAL; goto fail_cmd; } - config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - config.param.port_id = q6audio_get_port_id(port_id); - config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - config.pdata.param_id = cfg_type; - config.pdata.param_size = sizeof(config.port); - - config.port = *afe_config; - pr_debug("%s: param PL size=%d iparam_size[%d][%zd %zd %zd %zd] param_id[0x%x]\n", - __func__, config.param.payload_size, config.pdata.param_size, - sizeof(config), sizeof(config.param), sizeof(config.port), - sizeof(struct apr_hdr), config.pdata.param_id); - - ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = cfg_type; + param_hdr.param_size = sizeof(union afe_port_config); + port_cfg = *afe_config; + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &port_cfg); if (ret) { pr_err("%s: AFE enable for port 0x%x opcode[0x%x]failed %d\n", __func__, port_id, cfg_type, ret); @@ -3689,57 +3537,28 @@ fail_cmd: int afe_loopback(u16 enable, u16 rx_port, u16 tx_port) { - struct afe_loopback_cfg_v1 lb_cmd; + struct afe_loopback_cfg_v1 lb_param = {0}; + struct param_hdr_v3 param_hdr = {0}; int ret = 0; - int index = 0; if (rx_port == MI2S_RX) rx_port = AFE_PORT_ID_PRIMARY_MI2S_RX; if (tx_port == MI2S_TX) tx_port = AFE_PORT_ID_PRIMARY_MI2S_TX; - ret = afe_q6_interface_prepare(); - if (ret != 0) { - pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); - return ret; - } + param_hdr.module_id = AFE_MODULE_LOOPBACK; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_LOOPBACK_CONFIG; + param_hdr.param_size = sizeof(struct afe_loopback_cfg_v1); - index = q6audio_get_port_index(rx_port); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - return -EINVAL; - } - ret = q6audio_validate_port(rx_port); - if (ret < 0) { - pr_err("%s: Invalid port 0x%x ret %d", __func__, rx_port, ret); - return -EINVAL; - } + lb_param.dst_port_id = rx_port; + lb_param.routing_mode = LB_MODE_DEFAULT; + lb_param.enable = (enable ? 1 : 0); + lb_param.loopback_cfg_minor_version = AFE_API_VERSION_LOOPBACK_CONFIG; - 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 = sizeof(lb_cmd); - 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; - - ret = afe_apr_send_pkt(&lb_cmd, &this_afe.wait[index]); + ret = q6afe_pack_and_set_param_in_band(tx_port, + q6audio_get_port_index(tx_port), + param_hdr, (u8 *) &lb_param); if (ret) pr_err("%s: AFE loopback failed %d\n", __func__, ret); return ret; @@ -3747,9 +3566,9 @@ int afe_loopback(u16 enable, u16 rx_port, u16 tx_port) int afe_loopback_gain(u16 port_id, u16 volume) { - struct afe_loopback_gain_per_path_param set_param; + struct afe_loopback_gain_per_path_param set_param = {0}; + struct param_hdr_v3 param_hdr = {0}; int ret = 0; - int index = 0; if (this_afe.apr == NULL) { this_afe.apr = apr_register("ADSP", "AFE", afe_callback, @@ -3770,18 +3589,6 @@ int afe_loopback_gain(u16 port_id, u16 volume) ret = -EINVAL; goto fail_cmd; } - index = q6audio_get_port_index(port_id); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - return -EINVAL; - } - ret = q6audio_validate_port(port_id); - if (ret < 0) { - pr_err("%s: Invalid port 0x%x ret %d", - __func__, port_id, ret); - return -EINVAL; - } /* RX ports numbers are even .TX ports numbers are odd. */ if (port_id % 2 == 0) { @@ -3793,36 +3600,19 @@ int afe_loopback_gain(u16 port_id, u16 volume) pr_debug("%s: port 0x%x volume %d\n", __func__, port_id, volume); - set_param.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - set_param.hdr.pkt_size = sizeof(set_param); - set_param.hdr.src_port = 0; - set_param.hdr.dest_port = 0; - set_param.hdr.token = index; - set_param.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - - set_param.param.port_id = port_id; - set_param.param.payload_size = - (sizeof(struct afe_loopback_gain_per_path_param) - - sizeof(struct apr_hdr) - sizeof(struct afe_port_cmd_set_param_v2)); - set_param.param.payload_address_lsw = 0; - set_param.param.payload_address_msw = 0; - set_param.param.mem_map_handle = 0; - - set_param.pdata.module_id = AFE_MODULE_LOOPBACK; - set_param.pdata.param_id = AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH; - set_param.pdata.param_size = - (set_param.param.payload_size - - sizeof(struct afe_port_param_data_v2)); + param_hdr.module_id = AFE_MODULE_LOOPBACK; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH; + param_hdr.param_size = sizeof(struct afe_loopback_gain_per_path_param); set_param.rx_port_id = port_id; set_param.gain = volume; - ret = afe_apr_send_pkt(&set_param, &this_afe.wait[index]); - if (ret) { + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &set_param); + if (ret) pr_err("%s: AFE param set failed for port 0x%x ret %d\n", __func__, port_id, ret); - goto fail_cmd; - } fail_cmd: return ret; @@ -3950,9 +3740,9 @@ int afe_pseudo_port_stop_nowait(u16 port_id) int afe_port_group_set_param(u16 group_id, union afe_port_group_config *afe_group_config) { - int ret; - struct afe_port_group_create config; + struct param_hdr_v3 param_hdr = {0}; int cfg_type; + int ret; if (!afe_group_config) { pr_err("%s: Error, no configuration data\n", __func__); @@ -3983,27 +3773,13 @@ int afe_port_group_set_param(u16 group_id, return -EINVAL; } - memset(&config, 0, sizeof(config)); - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), - APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = IDX_GLOBAL_CFG; - config.hdr.opcode = AFE_SVC_CMD_SET_PARAM; - - config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_GROUP_DEVICE; - config.pdata.param_id = cfg_type; - config.pdata.param_size = sizeof(config.data); - config.data = *afe_group_config; - - ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]); + param_hdr.module_id = AFE_MODULE_GROUP_DEVICE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = cfg_type; + param_hdr.param_size = sizeof(union afe_port_group_config); + + ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr, + (u8 *) afe_group_config); if (ret) pr_err("%s: AFE_PARAM_ID_GROUP_DEVICE_CFG failed %d\n", __func__, ret); @@ -4015,8 +3791,9 @@ int afe_port_group_enable(u16 group_id, union afe_port_group_config *afe_group_config, u16 enable) { + struct afe_group_device_enable group_enable = {0}; + struct param_hdr_v3 param_hdr = {0}; int ret; - struct afe_port_group_create config; pr_debug("%s: group id: 0x%x enable: %d\n", __func__, group_id, enable); @@ -4035,28 +3812,15 @@ int afe_port_group_enable(u16 group_id, } } - memset(&config, 0, sizeof(config)); - config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), - APR_PKT_VER); - config.hdr.pkt_size = sizeof(config); - config.hdr.src_port = 0; - config.hdr.dest_port = 0; - config.hdr.token = IDX_GLOBAL_CFG; - config.hdr.opcode = AFE_SVC_CMD_SET_PARAM; - - config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - - sizeof(config.param); - config.param.payload_address_lsw = 0x00; - config.param.payload_address_msw = 0x00; - config.param.mem_map_handle = 0x00; - config.pdata.module_id = AFE_MODULE_GROUP_DEVICE; - config.pdata.param_id = AFE_PARAM_ID_GROUP_DEVICE_ENABLE; - config.pdata.param_size = sizeof(config.data); - config.data.group_enable.group_id = group_id; - config.data.group_enable.enable = enable; - - ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]); + param_hdr.module_id = AFE_MODULE_GROUP_DEVICE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_GROUP_DEVICE_ENABLE; + param_hdr.param_size = sizeof(struct afe_group_device_enable); + group_enable.group_id = group_id; + group_enable.enable = enable; + + ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr, + (u8 *) &group_enable); if (ret) pr_err("%s: AFE_PARAM_ID_GROUP_DEVICE_ENABLE failed %d\n", __func__, ret); @@ -5006,9 +4770,7 @@ fail_cmd: static int afe_sidetone_iir(u16 tx_port_id) { - struct afe_loopback_iir_cfg_v2 iir_sidetone; int ret; - int index = 0; uint16_t size = 0; int cal_index = AFE_SIDETONE_IIR_CAL; int iir_pregain = 0; @@ -5016,20 +4778,13 @@ static int afe_sidetone_iir(u16 tx_port_id) int iir_enable; struct cal_block_data *cal_block; int mid; - - memset(&iir_sidetone, 0, sizeof(iir_sidetone)); - index = q6audio_get_port_index(tx_port_id); - iir_sidetone.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - iir_sidetone.hdr.pkt_size = sizeof(iir_sidetone); - iir_sidetone.hdr.src_port = 0; - iir_sidetone.hdr.dest_port = 0; - iir_sidetone.hdr.token = index; - iir_sidetone.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - iir_sidetone.param.port_id = tx_port_id; - iir_sidetone.param.payload_address_lsw = 0x00; - iir_sidetone.param.payload_address_msw = 0x00; - iir_sidetone.param.mem_map_handle = 0x00; + struct afe_mod_enable_param enable = {0}; + struct afe_sidetone_iir_filter_config_params filter_data = {0}; + struct param_hdr_v3 param_hdr = {0}; + u8 *packed_param_data = NULL; + u32 packed_param_size = 0; + u32 single_param_size = 0; + struct audio_cal_info_sidetone_iir *st_iir_cal_info = NULL; if (this_afe.cal_data[cal_index] == NULL) { pr_err("%s: cal data is NULL\n", __func__); @@ -5045,14 +4800,13 @@ static int afe_sidetone_iir(u16 tx_port_id) goto done; } - iir_pregain = ((struct audio_cal_info_sidetone_iir *) - cal_block->cal_info)->pregain; - iir_enable = ((struct audio_cal_info_sidetone_iir *) - cal_block->cal_info)->iir_enable; - iir_num_biquad_stages = ((struct audio_cal_info_sidetone_iir *) - cal_block->cal_info)->num_biquad_stages; - mid = ((struct audio_cal_info_sidetone_iir *) - cal_block->cal_info)->mid; + /* Cache data from cal block while inside lock to reduce locked time */ + st_iir_cal_info = + (struct audio_cal_info_sidetone_iir *) cal_block->cal_info; + iir_pregain = st_iir_cal_info->pregain; + iir_enable = st_iir_cal_info->iir_enable; + iir_num_biquad_stages = st_iir_cal_info->num_biquad_stages; + mid = st_iir_cal_info->mid; /* * calculate the actual size of payload based on no of stages @@ -5068,75 +4822,85 @@ static int afe_sidetone_iir(u16 tx_port_id) pr_debug("%s: adding 2 to size:%d\n", __func__, size); size = size + 2; } - memcpy(&iir_sidetone.st_iir_filter_config_data.iir_config, - &((struct audio_cal_info_sidetone_iir *) - cal_block->cal_info)->iir_config, - sizeof(iir_sidetone.st_iir_filter_config_data.iir_config)); + memcpy(&filter_data.iir_config, &st_iir_cal_info->iir_config, size); mutex_unlock(&this_afe.cal_data[cal_index]->lock); - /* - * Calculate the payload size for setparams command - */ - iir_sidetone.param.payload_size = (sizeof(iir_sidetone) - - sizeof(struct apr_hdr) - - sizeof(struct afe_port_cmd_set_param_v2) - - (MAX_SIDETONE_IIR_DATA_SIZE - size)); - - pr_debug("%s: payload size :%d\n", __func__, - iir_sidetone.param.payload_size); + packed_param_size = + sizeof(param_hdr) * 2 + sizeof(enable) + sizeof(filter_data); + packed_param_data = kzalloc(packed_param_size, GFP_KERNEL); + if (!packed_param_data) + return -ENOMEM; + packed_param_size = 0; /* * Set IIR enable params */ - iir_sidetone.st_iir_enable_pdata.module_id = mid; - iir_sidetone.st_iir_enable_pdata.param_id = - AFE_PARAM_ID_ENABLE; - iir_sidetone.st_iir_enable_pdata.param_size = - sizeof(iir_sidetone.st_iir_mode_enable_data); - iir_sidetone.st_iir_mode_enable_data.enable = iir_enable; + param_hdr.module_id = mid; + param_hdr.param_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_ENABLE; + param_hdr.param_size = sizeof(enable); + enable.enable = iir_enable; + ret = q6common_pack_pp_params(packed_param_data, ¶m_hdr, + (u8 *) &enable, &single_param_size); + if (ret) { + pr_err("%s: Failed to pack param data, error %d\n", __func__, + ret); + goto done; + } + packed_param_size += single_param_size; /* * Set IIR filter config params */ - iir_sidetone.st_iir_filter_config_pdata.module_id = mid; - iir_sidetone.st_iir_filter_config_pdata.param_id = - AFE_PARAM_ID_SIDETONE_IIR_FILTER_CONFIG; - iir_sidetone.st_iir_filter_config_pdata.param_size = - sizeof(iir_sidetone.st_iir_filter_config_data.num_biquad_stages) - + - sizeof(iir_sidetone.st_iir_filter_config_data.pregain) + size; - iir_sidetone.st_iir_filter_config_pdata.reserved = 0; - iir_sidetone.st_iir_filter_config_data.num_biquad_stages = - iir_num_biquad_stages; - iir_sidetone.st_iir_filter_config_data.pregain = iir_pregain; + param_hdr.module_id = mid; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_SIDETONE_IIR_FILTER_CONFIG; + param_hdr.param_size = sizeof(filter_data.num_biquad_stages) + + sizeof(filter_data.pregain) + size; + filter_data.num_biquad_stages = iir_num_biquad_stages; + filter_data.pregain = iir_pregain; + ret = q6common_pack_pp_params(packed_param_data + packed_param_size, + ¶m_hdr, (u8 *) &filter_data, + &single_param_size); + if (ret) { + pr_err("%s: Failed to pack param data, error %d\n", __func__, + ret); + goto done; + } + packed_param_size += single_param_size; + pr_debug("%s: tx(0x%x)mid(0x%x)iir_en(%d)stg(%d)gain(0x%x)size(%d)\n", - __func__, tx_port_id, mid, - iir_sidetone.st_iir_mode_enable_data.enable, - iir_sidetone.st_iir_filter_config_data.num_biquad_stages, - iir_sidetone.st_iir_filter_config_data.pregain, - iir_sidetone.st_iir_filter_config_pdata.param_size); - ret = afe_apr_send_pkt(&iir_sidetone, &this_afe.wait[index]); + __func__, tx_port_id, mid, enable.enable, + filter_data.num_biquad_stages, filter_data.pregain, + param_hdr.param_size); + + ret = q6afe_set_params(tx_port_id, q6audio_get_port_index(tx_port_id), + NULL, packed_param_data, packed_param_size); if (ret) pr_err("%s: AFE sidetone failed for tx_port(0x%x)\n", __func__, tx_port_id); done: + kfree(packed_param_data); return ret; - } static int afe_sidetone(u16 tx_port_id, u16 rx_port_id, bool enable) { - struct afe_st_loopback_cfg_v1 cmd_sidetone; int ret; - int index; int cal_index = AFE_SIDETONE_CAL; int sidetone_gain; int sidetone_enable; struct cal_block_data *cal_block; int mid = 0; + struct afe_loopback_sidetone_gain gain_data = {0}; + struct loopback_cfg_data cfg_data = {0}; + struct param_hdr_v3 param_hdr = {0}; + u8 *packed_param_data = NULL; + u32 packed_param_size = 0; + u32 single_param_size = 0; + struct audio_cal_info_sidetone *st_cal_info = NULL; - memset(&cmd_sidetone, 0, sizeof(cmd_sidetone)); if (this_afe.cal_data[cal_index] == NULL) { pr_err("%s: cal data is NULL\n", __func__); ret = -EINVAL; @@ -5150,60 +4914,61 @@ static int afe_sidetone(u16 tx_port_id, u16 rx_port_id, bool enable) ret = -EINVAL; goto done; } - sidetone_gain = ((struct audio_cal_info_sidetone *) - cal_block->cal_info)->gain; - sidetone_enable = ((struct audio_cal_info_sidetone *) - cal_block->cal_info)->enable; - mid = ((struct audio_cal_info_sidetone *) - cal_block->cal_info)->mid; - mutex_unlock(&this_afe.cal_data[cal_index]->lock); - index = q6audio_get_port_index(tx_port_id); - cmd_sidetone.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - cmd_sidetone.hdr.pkt_size = sizeof(cmd_sidetone); - cmd_sidetone.hdr.src_port = 0; - cmd_sidetone.hdr.dest_port = 0; - cmd_sidetone.hdr.token = index; - cmd_sidetone.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - cmd_sidetone.param.port_id = tx_port_id; - cmd_sidetone.param.payload_size = (sizeof(cmd_sidetone) - - sizeof(struct apr_hdr) - - sizeof(struct afe_port_cmd_set_param_v2)); - cmd_sidetone.param.payload_address_lsw = 0x00; - cmd_sidetone.param.payload_address_msw = 0x00; - cmd_sidetone.param.mem_map_handle = 0x00; - cmd_sidetone.gain_pdata.module_id = AFE_MODULE_LOOPBACK; - cmd_sidetone.gain_pdata.param_id = AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH; - /* - * size of actual payload only - */ - cmd_sidetone.gain_pdata.param_size = sizeof( - struct afe_loopback_sidetone_gain); - cmd_sidetone.gain_data.rx_port_id = rx_port_id; - cmd_sidetone.gain_data.gain = sidetone_gain; + /* Cache data from cal block while inside lock to reduce locked time */ + st_cal_info = (struct audio_cal_info_sidetone *) cal_block->cal_info; + sidetone_gain = st_cal_info->gain; + sidetone_enable = st_cal_info->enable; + mid = st_cal_info->mid; + mutex_unlock(&this_afe.cal_data[cal_index]->lock); - cmd_sidetone.cfg_pdata.module_id = AFE_MODULE_LOOPBACK; - cmd_sidetone.cfg_pdata.param_id = AFE_PARAM_ID_LOOPBACK_CONFIG; - /* - * size of actual payload only - */ - cmd_sidetone.cfg_pdata.param_size = sizeof(struct loopback_cfg_data); - cmd_sidetone.cfg_data.loopback_cfg_minor_version = - AFE_API_VERSION_LOOPBACK_CONFIG; - cmd_sidetone.cfg_data.dst_port_id = rx_port_id; - cmd_sidetone.cfg_data.routing_mode = LB_MODE_SIDETONE; - cmd_sidetone.cfg_data.enable = enable; + /* Set gain data. */ + param_hdr.module_id = AFE_MODULE_LOOPBACK; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH; + param_hdr.param_size = sizeof(struct afe_loopback_sidetone_gain); + gain_data.rx_port_id = rx_port_id; + gain_data.gain = sidetone_gain; + ret = q6common_pack_pp_params(packed_param_data, ¶m_hdr, + (u8 *) &gain_data, &single_param_size); + if (ret) { + pr_err("%s: Failed to pack param data, error %d\n", __func__, + ret); + goto done; + } + packed_param_size += single_param_size; + + /* Set configuration data. */ + param_hdr.module_id = AFE_MODULE_LOOPBACK; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_LOOPBACK_CONFIG; + param_hdr.param_size = sizeof(struct loopback_cfg_data); + cfg_data.loopback_cfg_minor_version = AFE_API_VERSION_LOOPBACK_CONFIG; + cfg_data.dst_port_id = rx_port_id; + cfg_data.routing_mode = LB_MODE_SIDETONE; + cfg_data.enable = enable; + ret = q6common_pack_pp_params(packed_param_data + packed_param_size, + ¶m_hdr, (u8 *) &cfg_data, + &single_param_size); + if (ret) { + pr_err("%s: Failed to pack param data, error %d\n", __func__, + ret); + goto done; + } + packed_param_size += single_param_size; pr_debug("%s rx(0x%x) tx(0x%x) enable(%d) mid(0x%x) gain(%d) sidetone_enable(%d)\n", __func__, rx_port_id, tx_port_id, enable, mid, sidetone_gain, sidetone_enable); - ret = afe_apr_send_pkt(&cmd_sidetone, &this_afe.wait[index]); + ret = q6afe_set_params(tx_port_id, q6audio_get_port_index(tx_port_id), + NULL, packed_param_data, packed_param_size); if (ret) pr_err("%s: AFE sidetone send failed for tx_port:%d rx_port:%d ret:%d\n", __func__, tx_port_id, rx_port_id, ret); + done: + kfree(packed_param_data); return ret; } @@ -5588,93 +5353,44 @@ fail_cmd: int afe_set_digital_codec_core_clock(u16 port_id, struct afe_digital_clk_cfg *cfg) { - struct afe_lpass_digital_clk_config_command clk_cfg; - int index = 0; + struct afe_digital_clk_cfg clk_cfg = {0}; + struct param_hdr_v3 param_hdr = {0}; int ret = 0; if (!cfg) { pr_err("%s: clock cfg is NULL\n", __func__); - ret = -EINVAL; - return ret; - } - - ret = afe_q6_interface_prepare(); - if (ret != 0) { - pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); - return ret; + return -EINVAL; } - clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - clk_cfg.hdr.pkt_size = sizeof(clk_cfg); - clk_cfg.hdr.src_port = 0; - clk_cfg.hdr.dest_port = 0; - clk_cfg.hdr.token = index; - - clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; /*default rx port is taken to enable the codec digital clock*/ - clk_cfg.param.port_id = q6audio_get_port_id(port_id); - clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr) - - sizeof(clk_cfg.param); - clk_cfg.param.payload_address_lsw = 0x00; - clk_cfg.param.payload_address_msw = 0x00; - clk_cfg.param.mem_map_handle = 0x00; - clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - clk_cfg.pdata.param_id = AFE_PARAM_ID_INTERNAL_DIGIATL_CDC_CLK_CONFIG; - clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg); - clk_cfg.clk_cfg = *cfg; + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_INTERNAL_DIGIATL_CDC_CLK_CONFIG; + param_hdr.param_size = sizeof(struct afe_digital_clk_cfg); + clk_cfg = *cfg; pr_debug("%s: Minor version =0x%x clk val = %d\n" "clk root = 0x%x resrv = 0x%x\n", - __func__, cfg->i2s_cfg_minor_version, - cfg->clk_val, cfg->clk_root, cfg->reserved); - - atomic_set(&this_afe.state, 1); - atomic_set(&this_afe.status, 0); - ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg); - if (ret < 0) { - pr_err("%s: AFE enable for port 0x%x ret %d\n", - __func__, port_id, ret); - ret = -EINVAL; - goto fail_cmd; - } - - 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; - goto fail_cmd; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); - goto fail_cmd; - } + __func__, cfg->i2s_cfg_minor_version, cfg->clk_val, + cfg->clk_root, cfg->reserved); -fail_cmd: + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &clk_cfg); + if (ret < 0) + pr_err("%s: AFE enable for port 0x%x ret %d\n", __func__, + port_id, ret); return ret; } int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg) { - struct afe_lpass_clk_config_command clk_cfg; - int index = 0; + struct afe_clk_cfg clk_cfg = {0}; + struct param_hdr_v3 param_hdr = {0}; int ret = 0; if (!cfg) { pr_err("%s: clock cfg is NULL\n", __func__); - ret = -EINVAL; - return ret; - } - index = q6audio_get_port_index(port_id); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); return -EINVAL; } ret = q6audio_is_digital_pcm_interface(port_id); @@ -5684,31 +5400,12 @@ int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg) return -EINVAL; } - ret = afe_q6_interface_prepare(); - if (ret != 0) { - pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); - return ret; - } - mutex_lock(&this_afe.afe_cmd_lock); - clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - clk_cfg.hdr.pkt_size = sizeof(clk_cfg); - clk_cfg.hdr.src_port = 0; - clk_cfg.hdr.dest_port = 0; - clk_cfg.hdr.token = index; - - clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - clk_cfg.param.port_id = q6audio_get_port_id(port_id); - clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr) - - sizeof(clk_cfg.param); - clk_cfg.param.payload_address_lsw = 0x00; - clk_cfg.param.payload_address_msw = 0x00; - clk_cfg.param.mem_map_handle = 0x00; - clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - clk_cfg.pdata.param_id = AFE_PARAM_ID_LPAIF_CLK_CONFIG; - clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg); - clk_cfg.clk_cfg = *cfg; + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_LPAIF_CLK_CONFIG; + param_hdr.param_size = sizeof(clk_cfg); + clk_cfg = *cfg; pr_debug("%s: Minor version =0x%x clk val1 = %d\n" "clk val2 = %d, clk src = 0x%x\n" @@ -5719,41 +5416,20 @@ int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg) cfg->clk_root, cfg->clk_set_mode, cfg->reserved, q6audio_get_port_id(port_id)); - atomic_set(&this_afe.state, 1); - atomic_set(&this_afe.status, 0); - ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg); - if (ret < 0) { + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &clk_cfg); + if (ret < 0) pr_err("%s: AFE enable for port 0x%x ret %d\n", __func__, port_id, ret); - ret = -EINVAL; - goto fail_cmd; - } - - 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; - goto fail_cmd; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); - goto fail_cmd; - } -fail_cmd: mutex_unlock(&this_afe.afe_cmd_lock); return ret; } int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg) { - struct afe_lpass_clk_config_command_v2 clk_cfg; + struct param_hdr_v3 param_hdr = {0}; int ret = 0; if (!cfg) { @@ -5774,24 +5450,10 @@ int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg) } mutex_lock(&this_afe.afe_cmd_lock); - clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - clk_cfg.hdr.pkt_size = sizeof(clk_cfg); - clk_cfg.hdr.src_port = 0; - clk_cfg.hdr.dest_port = 0; - clk_cfg.hdr.token = index; - - clk_cfg.hdr.opcode = AFE_SVC_CMD_SET_PARAM; - clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr) - - sizeof(clk_cfg.param); - clk_cfg.param.payload_address_lsw = 0x00; - clk_cfg.param.payload_address_msw = 0x00; - clk_cfg.param.mem_map_handle = 0x00; - clk_cfg.pdata.module_id = AFE_MODULE_CLOCK_SET; - clk_cfg.pdata.param_id = AFE_PARAM_ID_CLOCK_SET; - clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg); - clk_cfg.clk_cfg = *cfg; - + param_hdr.module_id = AFE_MODULE_CLOCK_SET; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_CLOCK_SET; + param_hdr.param_size = sizeof(struct afe_clk_set); pr_debug("%s: Minor version =0x%x clk id = %d\n" "clk freq (Hz) = %d, clk attri = 0x%x\n" @@ -5800,34 +5462,12 @@ int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg) cfg->clk_id, cfg->clk_freq_in_hz, cfg->clk_attri, cfg->clk_root, cfg->enable); - atomic_set(&this_afe.state, 1); - atomic_set(&this_afe.status, 0); - ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg); - if (ret < 0) { + ret = q6afe_svc_pack_and_set_param_in_band(index, param_hdr, + (u8 *) cfg); + if (ret < 0) pr_err("%s: AFE clk cfg failed with ret %d\n", __func__, ret); - ret = -EINVAL; - goto fail_cmd; - } - - 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; - goto fail_cmd; - } else { - /* set ret to 0 as no timeout happened */ - ret = 0; - } - if (atomic_read(&this_afe.status) != 0) { - pr_err("%s: config cmd failed\n", __func__); - ret = -EINVAL; - goto fail_cmd; - } -fail_cmd: mutex_unlock(&this_afe.afe_cmd_lock); return ret; } @@ -5861,19 +5501,12 @@ int afe_set_lpass_clock_v2(u16 port_id, struct afe_clk_set *cfg) int afe_set_lpass_internal_digital_codec_clock(u16 port_id, struct afe_digital_clk_cfg *cfg) { - struct afe_lpass_digital_clk_config_command clk_cfg; - int index = 0; + struct afe_digital_clk_cfg clk_cfg = {0}; + struct param_hdr_v3 param_hdr = {0}; int ret = 0; if (!cfg) { pr_err("%s: clock cfg is NULL\n", __func__); - ret = -EINVAL; - return ret; - } - index = q6audio_get_port_index(port_id); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); return -EINVAL; } ret = q6audio_is_digital_pcm_interface(port_id); @@ -5883,30 +5516,11 @@ int afe_set_lpass_internal_digital_codec_clock(u16 port_id, return -EINVAL; } - ret = afe_q6_interface_prepare(); - if (ret != 0) { - pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); - return ret; - } - - clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - clk_cfg.hdr.pkt_size = sizeof(clk_cfg); - clk_cfg.hdr.src_port = 0; - clk_cfg.hdr.dest_port = 0; - clk_cfg.hdr.token = index; - - clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - clk_cfg.param.port_id = q6audio_get_port_id(port_id); - clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr) - - sizeof(clk_cfg.param); - clk_cfg.param.payload_address_lsw = 0x00; - clk_cfg.param.payload_address_msw = 0x00; - clk_cfg.param.mem_map_handle = 0x00; - clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - clk_cfg.pdata.param_id = AFE_PARAM_ID_INTERNAL_DIGIATL_CDC_CLK_CONFIG; - clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg); - clk_cfg.clk_cfg = *cfg; + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_INTERNAL_DIGIATL_CDC_CLK_CONFIG; + param_hdr.param_size = sizeof(clk_cfg); + clk_cfg = *cfg; pr_debug("%s: Minor version =0x%x clk val = %d\n" "clk root = 0x%x resrv = 0x%x port id = 0x%x\n", @@ -5914,49 +5528,22 @@ int afe_set_lpass_internal_digital_codec_clock(u16 port_id, cfg->clk_val, cfg->clk_root, cfg->reserved, q6audio_get_port_id(port_id)); - atomic_set(&this_afe.state, 1); - atomic_set(&this_afe.status, 0); - ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg); - if (ret < 0) { + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &clk_cfg); + if (ret < 0) pr_err("%s: AFE enable for port 0x0x%x ret %d\n", __func__, port_id, ret); - ret = -EINVAL; - goto fail_cmd; - } - - 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; - goto fail_cmd; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); - goto fail_cmd; - } -fail_cmd: return ret; } int afe_enable_lpass_core_shared_clock(u16 port_id, u32 enable) { - struct afe_lpass_core_shared_clk_config_command clk_cfg; - int index = 0; + struct afe_param_id_lpass_core_shared_clk_cfg clk_cfg = {0}; + struct param_hdr_v3 param_hdr = {0}; int ret = 0; - index = q6audio_get_port_index(port_id); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - return -EINVAL; - } ret = q6audio_is_digital_pcm_interface(port_id); if (ret < 0) { pr_err("%s: q6audio_is_digital_pcm_interface fail %d\n", @@ -5964,65 +5551,25 @@ int afe_enable_lpass_core_shared_clock(u16 port_id, u32 enable) return -EINVAL; } - ret = afe_q6_interface_prepare(); - if (ret != 0) { - pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); - return ret; - } - mutex_lock(&this_afe.afe_cmd_lock); - clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - clk_cfg.hdr.pkt_size = sizeof(clk_cfg); - clk_cfg.hdr.src_port = 0; - clk_cfg.hdr.dest_port = 0; - clk_cfg.hdr.token = index; - - clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; - clk_cfg.param.port_id = q6audio_get_port_id(port_id); - clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr) - - sizeof(clk_cfg.param); - clk_cfg.param.payload_address_lsw = 0x00; - clk_cfg.param.payload_address_msw = 0x00; - clk_cfg.param.mem_map_handle = 0x00; - clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - clk_cfg.pdata.param_id = AFE_PARAM_ID_LPASS_CORE_SHARED_CLOCK_CONFIG; - clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg); - clk_cfg.clk_cfg.lpass_core_shared_clk_cfg_minor_version = - AFE_API_VERSION_LPASS_CORE_SHARED_CLK_CONFIG; - clk_cfg.clk_cfg.enable = enable; + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_LPASS_CORE_SHARED_CLOCK_CONFIG; + param_hdr.param_size = sizeof(clk_cfg); + clk_cfg.lpass_core_shared_clk_cfg_minor_version = + AFE_API_VERSION_LPASS_CORE_SHARED_CLK_CONFIG; + clk_cfg.enable = enable; pr_debug("%s: port id = %d, enable = %d\n", __func__, q6audio_get_port_id(port_id), enable); - atomic_set(&this_afe.state, 1); - atomic_set(&this_afe.status, 0); - ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg); - if (ret < 0) { + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, (u8 *) &clk_cfg); + if (ret < 0) pr_err("%s: AFE enable for port 0x%x ret %d\n", __func__, port_id, ret); - ret = -EINVAL; - goto fail_cmd; - } - - 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; - goto fail_cmd; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); - goto fail_cmd; - } -fail_cmd: mutex_unlock(&this_afe.afe_cmd_lock); return ret; } @@ -6052,8 +5599,9 @@ int q6afe_check_osr_clk_freq(u32 freq) int afe_get_sp_th_vi_ftm_data(struct afe_sp_th_vi_get_param *th_vi) { + struct param_hdr_v3 param_hdr = {0}; + int port = SLIMBUS_4_TX; int ret = -EINVAL; - int index = 0, port = SLIMBUS_4_TX; if (!th_vi) { pr_err("%s: Invalid params\n", __func__); @@ -6062,59 +5610,18 @@ int afe_get_sp_th_vi_ftm_data(struct afe_sp_th_vi_get_param *th_vi) if (this_afe.vi_tx_port != -1) port = this_afe.vi_tx_port; - ret = q6audio_validate_port(port); - if (ret < 0) { - pr_err("%s: invalid port 0x%x ret %d\n", __func__, port, ret); - goto done; - } - index = q6audio_get_port_index(port); - if (index < 0) { - pr_err("%s: invalid port 0x%x, index %d\n", - __func__, port, index); - ret = -EINVAL; - goto done; - } - th_vi->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - th_vi->hdr.pkt_size = sizeof(*th_vi); - th_vi->hdr.src_port = 0; - th_vi->hdr.dest_port = 0; - th_vi->hdr.token = index; - th_vi->hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2; - th_vi->get_param.mem_map_handle = 0; - th_vi->get_param.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI; - th_vi->get_param.param_id = AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS; - th_vi->get_param.payload_address_lsw = 0; - th_vi->get_param.payload_address_msw = 0; - th_vi->get_param.payload_size = sizeof(*th_vi) - - sizeof(th_vi->get_param) - sizeof(th_vi->hdr); - th_vi->get_param.port_id = q6audio_get_port_id(port); - th_vi->pdata.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI; - th_vi->pdata.param_id = AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS; - th_vi->pdata.param_size = sizeof(th_vi->param); - atomic_set(&this_afe.status, 0); - atomic_set(&this_afe.state, 1); - ret = apr_send_pkt(this_afe.apr, (uint32_t *)th_vi); - if (ret < 0) { - pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n", - __func__, port, th_vi->get_param.param_id, ret); - goto done; - } - 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; - goto done; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code(atomic_read(&this_afe.status)); + param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS; + param_hdr.param_size = sizeof(struct afe_sp_th_vi_ftm_params); + + ret = q6afe_get_params(port, NULL, ¶m_hdr); + if (ret) { + pr_err("%s: Failed to get TH VI FTM data\n", __func__); goto done; } + + th_vi->pdata = param_hdr; memcpy(&th_vi->param , &this_afe.th_vi_resp.param, sizeof(this_afe.th_vi_resp.param)); pr_debug("%s: DC resistance %d %d temp %d %d status %d %d\n", @@ -6131,8 +5638,9 @@ done: int afe_get_sp_ex_vi_ftm_data(struct afe_sp_ex_vi_get_param *ex_vi) { + struct param_hdr_v3 param_hdr = {0}; + int port = SLIMBUS_4_TX; int ret = -EINVAL; - int index = 0, port = SLIMBUS_4_TX; if (!ex_vi) { pr_err("%s: Invalid params\n", __func__); @@ -6141,61 +5649,19 @@ int afe_get_sp_ex_vi_ftm_data(struct afe_sp_ex_vi_get_param *ex_vi) if (this_afe.vi_tx_port != -1) port = this_afe.vi_tx_port; - ret = q6audio_validate_port(port); - if (ret < 0) { - pr_err("%s: invalid port 0x%x ret %d\n", __func__, port, ret); - goto done; - } + param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS; + param_hdr.param_size = sizeof(struct afe_sp_ex_vi_ftm_params); - index = q6audio_get_port_index(port); - if (index < 0) { - pr_err("%s: invalid index %d port 0x%x\n", __func__, - index, port); - ret = -EINVAL; - goto done; - } - - ex_vi->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - ex_vi->hdr.pkt_size = sizeof(*ex_vi); - ex_vi->hdr.src_port = 0; - ex_vi->hdr.dest_port = 0; - ex_vi->hdr.token = index; - ex_vi->hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2; - ex_vi->get_param.mem_map_handle = 0; - ex_vi->get_param.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI; - ex_vi->get_param.param_id = AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS; - ex_vi->get_param.payload_address_lsw = 0; - ex_vi->get_param.payload_address_msw = 0; - ex_vi->get_param.payload_size = sizeof(*ex_vi) - - sizeof(ex_vi->get_param) - sizeof(ex_vi->hdr); - ex_vi->get_param.port_id = q6audio_get_port_id(port); - ex_vi->pdata.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI; - ex_vi->pdata.param_id = AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS; - ex_vi->pdata.param_size = sizeof(ex_vi->param); - atomic_set(&this_afe.status, 0); - atomic_set(&this_afe.state, 1); - ret = apr_send_pkt(this_afe.apr, (uint32_t *)ex_vi); + ret = q6afe_get_params(port, NULL, ¶m_hdr); if (ret < 0) { pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n", - __func__, port, ex_vi->get_param.param_id, ret); - goto done; - } - 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; - goto done; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code(atomic_read(&this_afe.status)); + __func__, port, param_hdr.param_id, ret); goto done; } + + ex_vi->pdata = param_hdr; memcpy(&ex_vi->param , &this_afe.ex_vi_resp.param, sizeof(this_afe.ex_vi_resp.param)); pr_debug("%s: freq %d %d resistance %d %d qfactor %d %d state %d %d\n", @@ -6215,80 +5681,28 @@ done: int afe_get_av_dev_drift(struct afe_param_id_dev_timing_stats *timing_stats, u16 port) { + struct param_hdr_v3 param_hdr = {0}; int ret = -EINVAL; - int index = 0; - struct afe_av_dev_drift_get_param av_dev_drift; if (!timing_stats) { pr_err("%s: Invalid params\n", __func__); goto exit; } - ret = q6audio_validate_port(port); - if (ret < 0) { - pr_err("%s: invalid port 0x%x ret %d\n", __func__, port, ret); - ret = -EINVAL; - goto exit; - } + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_DEV_TIMING_STATS; + param_hdr.param_size = sizeof(struct afe_param_id_dev_timing_stats); - index = q6audio_get_port_index(port); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: Invalid AFE port index[%d]\n", - __func__, index); - ret = -EINVAL; - goto exit; - } - - memset(&av_dev_drift, 0, sizeof(struct afe_av_dev_drift_get_param)); - - av_dev_drift.hdr.hdr_field = - APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - av_dev_drift.hdr.pkt_size = sizeof(av_dev_drift); - av_dev_drift.hdr.src_port = 0; - av_dev_drift.hdr.dest_port = 0; - av_dev_drift.hdr.token = index; - av_dev_drift.hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2; - av_dev_drift.get_param.mem_map_handle = 0; - av_dev_drift.get_param.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - av_dev_drift.get_param.param_id = AFE_PARAM_ID_DEV_TIMING_STATS; - av_dev_drift.get_param.payload_address_lsw = 0; - av_dev_drift.get_param.payload_address_msw = 0; - av_dev_drift.get_param.payload_size = sizeof(av_dev_drift) - - sizeof(av_dev_drift.get_param) - sizeof(av_dev_drift.hdr); - av_dev_drift.get_param.port_id = q6audio_get_port_id(port); - av_dev_drift.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; - av_dev_drift.pdata.param_id = AFE_PARAM_ID_DEV_TIMING_STATS; - av_dev_drift.pdata.param_size = sizeof(av_dev_drift.timing_stats); - atomic_set(&this_afe.status, 0); - atomic_set(&this_afe.state, 1); - ret = apr_send_pkt(this_afe.apr, (uint32_t *)&av_dev_drift); + ret = q6afe_get_params(port, NULL, ¶m_hdr); if (ret < 0) { pr_err("%s: get param port 0x%x param id[0x%x] failed %d\n", - __func__, port, av_dev_drift.get_param.param_id, ret); - goto exit; - } - - 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; - goto exit; - } - - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); + __func__, port, param_hdr.param_id, ret); goto exit; } memcpy(timing_stats, &this_afe.av_dev_drift_resp.timing_stats, - sizeof(this_afe.av_dev_drift_resp.timing_stats)); + param_hdr.param_size); ret = 0; exit: return ret; @@ -6296,8 +5710,9 @@ exit: int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib_resp) { + struct param_hdr_v3 param_hdr = {0}; + int port = SLIMBUS_4_TX; int ret = -EINVAL; - int index = 0, port = SLIMBUS_4_TX; if (!calib_resp) { pr_err("%s: Invalid params\n", __func__); @@ -6306,60 +5721,15 @@ int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib_resp) if (this_afe.vi_tx_port != -1) port = this_afe.vi_tx_port; - ret = q6audio_validate_port(port); - if (ret < 0) { - pr_err("%s: invalid port 0x%x ret %d\n", __func__, port, ret); - ret = -EINVAL; - goto fail_cmd; - } - index = q6audio_get_port_index(port); - if (index < 0 || index >= AFE_MAX_PORTS) { - pr_err("%s: AFE port index[%d] invalid!\n", - __func__, index); - ret = -EINVAL; - goto fail_cmd; - } - calib_resp->hdr.hdr_field = - APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); - calib_resp->hdr.pkt_size = sizeof(*calib_resp); - calib_resp->hdr.src_port = 0; - calib_resp->hdr.dest_port = 0; - calib_resp->hdr.token = index; - calib_resp->hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2; - calib_resp->get_param.mem_map_handle = 0; - calib_resp->get_param.module_id = AFE_MODULE_FB_SPKR_PROT_VI_PROC_V2; - calib_resp->get_param.param_id = AFE_PARAM_ID_CALIB_RES_CFG_V2; - calib_resp->get_param.payload_address_lsw = 0; - calib_resp->get_param.payload_address_msw = 0; - calib_resp->get_param.payload_size = sizeof(*calib_resp) - - sizeof(calib_resp->get_param) - sizeof(calib_resp->hdr); - calib_resp->get_param.port_id = q6audio_get_port_id(port); - calib_resp->pdata.module_id = AFE_MODULE_FB_SPKR_PROT_VI_PROC_V2; - calib_resp->pdata.param_id = AFE_PARAM_ID_CALIB_RES_CFG_V2; - calib_resp->pdata.param_size = sizeof(calib_resp->res_cfg); - atomic_set(&this_afe.status, 0); - atomic_set(&this_afe.state, 1); - ret = apr_send_pkt(this_afe.apr, (uint32_t *)calib_resp); + param_hdr.module_id = AFE_MODULE_FB_SPKR_PROT_VI_PROC_V2; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_CALIB_RES_CFG_V2; + param_hdr.param_size = sizeof(struct afe_spkr_prot_get_vi_calib); + + ret = q6afe_get_params(port, NULL, ¶m_hdr); if (ret < 0) { pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n", - __func__, port, calib_resp->get_param.param_id, ret); - goto fail_cmd; - } - 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; - goto fail_cmd; - } - if (atomic_read(&this_afe.status) > 0) { - pr_err("%s: config cmd failed [%s]\n", - __func__, adsp_err_get_err_str( - atomic_read(&this_afe.status))); - ret = adsp_err_get_lnx_err_code( - atomic_read(&this_afe.status)); + __func__, port, param_hdr.param_id, ret); goto fail_cmd; } memcpy(&calib_resp->res_cfg , &this_afe.calib_data.res_cfg, diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c index c3d86e6cced2..5f0a61fb9081 100644 --- a/sound/soc/msm/qdsp6v2/q6asm.c +++ b/sound/soc/msm/qdsp6v2/q6asm.c @@ -41,6 +41,7 @@ #include <sound/audio_cal_utils.h> #include <sound/adsp_err.h> #include <sound/compress_params.h> +#include <sound/q6common.h> #define TRUE 0x01 #define FALSE 0x00 @@ -1796,6 +1797,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) if (data->opcode == APR_BASIC_RSP_RESULT) { switch (payload[0]) { case ASM_STREAM_CMD_SET_PP_PARAMS_V2: + case ASM_STREAM_CMD_SET_PP_PARAMS_V3: if (rtac_make_asm_callback(ac->session, payload, data->payload_size)) break; @@ -1842,9 +1844,12 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) pr_err("%s: cmd = 0x%x returned error = 0x%x\n", __func__, payload[0], payload[1]); if (wakeup_flag) { - if ((is_adsp_reg_event(payload[0]) >= 0) - || (payload[0] == - ASM_STREAM_CMD_SET_PP_PARAMS_V2)) + if ((is_adsp_reg_event(payload[0]) >= + 0) || + (payload[0] == + ASM_STREAM_CMD_SET_PP_PARAMS_V2) || + (payload[0] == + ASM_STREAM_CMD_SET_PP_PARAMS_V3)) atomic_set(&ac->cmd_state_pp, payload[1]); else @@ -1855,7 +1860,8 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) return 0; } if ((is_adsp_reg_event(payload[0]) >= 0) || - (payload[0] == ASM_STREAM_CMD_SET_PP_PARAMS_V2)) { + (payload[0] == ASM_STREAM_CMD_SET_PP_PARAMS_V2) || + (payload[0] == ASM_STREAM_CMD_SET_PP_PARAMS_V3)) { if (atomic_read(&ac->cmd_state_pp) && wakeup_flag) { atomic_set(&ac->cmd_state_pp, 0); @@ -1898,10 +1904,10 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) break; } case ASM_STREAM_CMD_GET_PP_PARAMS_V2: - pr_debug("%s: ASM_STREAM_CMD_GET_PP_PARAMS_V2 session %d opcode 0x%x token 0x%x src %d dest %d\n", - __func__, ac->session, - data->opcode, data->token, - data->src_port, data->dest_port); + case ASM_STREAM_CMD_GET_PP_PARAMS_V3: + pr_debug("%s: ASM_STREAM_CMD_GET_PP_PARAMS session %d opcode 0x%x token 0x%x src %d dest %d\n", + __func__, ac->session, data->opcode, + data->token, data->src_port, data->dest_port); /* Should only come here if there is an APR */ /* error or malformed APR packet. Otherwise */ /* response will be returned as */ @@ -1971,13 +1977,13 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv) break; } case ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2: - pr_debug("%s: ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2 session %d opcode 0x%x token 0x%x src %d dest %d\n", - __func__, ac->session, data->opcode, - data->token, - data->src_port, data->dest_port); + case ASM_STREAM_CMDRSP_GET_PP_PARAMS_V3: + pr_debug("%s: ASM_STREAM_CMDRSP_GET_PP_PARAMS session %d opcode 0x%x token 0x%x src %d dest %d\n", + __func__, ac->session, data->opcode, data->token, + data->src_port, data->dest_port); if (payload[0] != 0) { - pr_err("%s: ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2 returned error = 0x%x\n", - __func__, payload[0]); + pr_err("%s: ASM_STREAM_CMDRSP_GET_PP_PARAMS returned error = 0x%x\n", + __func__, payload[0]); } else if (generic_get_data) { generic_get_data->valid = 1; if (generic_get_data->is_inband) { @@ -2466,6 +2472,136 @@ static void q6asm_add_mmaphdr(struct audio_client *ac, struct apr_hdr *hdr, return; } +int q6asm_set_pp_params(struct audio_client *ac, + struct mem_mapping_hdr *mem_hdr, u8 *param_data, + u32 param_size) +{ + struct asm_stream_cmd_set_pp_params *asm_set_param = NULL; + int pkt_size = 0; + int ret = 0; + + if (ac == NULL) { + pr_err("%s: Audio Client is NULL\n", __func__); + return -EINVAL; + } else if (ac->apr == NULL) { + pr_err("%s: APR pointer is NULL\n", __func__); + return -EINVAL; + } + + pkt_size = sizeof(struct asm_stream_cmd_set_pp_params); + /* Add param size to packet size when sending in-band only */ + if (param_data != NULL) + pkt_size += param_size; + asm_set_param = kzalloc(pkt_size, GFP_KERNEL); + if (!asm_set_param) + return -ENOMEM; + + q6asm_add_hdr_async(ac, &asm_set_param->apr_hdr, pkt_size, TRUE); + + /* With pre-packed data, only the opcode differes from V2 and V3. */ + if (q6common_is_instance_id_supported()) + asm_set_param->apr_hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V3; + else + asm_set_param->apr_hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; + + asm_set_param->payload_size = param_size; + + if (mem_hdr != NULL) { + /* Out of band case */ + asm_set_param->mem_hdr = *mem_hdr; + } else if (param_data != NULL) { + /* In band case. Parameter data must be pre-packed with its + * header before calling this function. Use + * q6common_pack_pp_params to pack parameter data and header + * correctly. + */ + memcpy(&asm_set_param->param_data, param_data, param_size); + } else { + pr_err("%s: Received NULL pointers for both mem header and param data\n", + __func__); + ret = -EINVAL; + goto done; + } + + atomic_set(&ac->cmd_state_pp, -1); + ret = apr_send_pkt(ac->apr, (uint32_t *) asm_set_param); + if (ret < 0) { + pr_err("%s: apr send failed rc %d\n", __func__, ret); + ret = -EINVAL; + goto done; + } + + ret = wait_event_timeout(ac->cmd_wait, + atomic_read(&ac->cmd_state_pp) >= 0, 5 * HZ); + if (!ret) { + pr_err("%s: timeout sending apr pkt\n", __func__); + ret = -ETIMEDOUT; + goto done; + } + + if (atomic_read(&ac->cmd_state_pp) > 0) { + pr_err("%s: DSP returned error[%s]\n", __func__, + adsp_err_get_err_str(atomic_read(&ac->cmd_state_pp))); + ret = adsp_err_get_lnx_err_code(atomic_read(&ac->cmd_state_pp)); + goto done; + } + ret = 0; +done: + kfree(asm_set_param); + return ret; +} +EXPORT_SYMBOL(q6asm_set_pp_params); + +int q6asm_pack_and_set_pp_param_in_band(struct audio_client *ac, + struct param_hdr_v3 param_hdr, + u8 *param_data) +{ + u8 *packed_data = NULL; + u32 packed_size = sizeof(union param_hdrs) + param_hdr.param_size; + int ret = 0; + + packed_data = kzalloc(packed_size, GFP_KERNEL); + if (packed_data == NULL) + return -ENOMEM; + + ret = q6common_pack_pp_params(packed_data, ¶m_hdr, param_data, + &packed_size); + if (ret) { + pr_err("%s: Failed to pack params, error %d\n", __func__, ret); + goto done; + } + + ret = q6asm_set_pp_params(ac, NULL, packed_data, packed_size); +done: + kfree(packed_data); + return ret; +} +EXPORT_SYMBOL(q6asm_pack_and_set_pp_param_in_band); + +int q6asm_set_soft_volume_module_instance_ids(int instance, + struct param_hdr_v3 *param_hdr) +{ + if (param_hdr == NULL) { + pr_err("%s: Param header is NULL\n", __func__); + return -EINVAL; + } + + switch (instance) { + case SOFT_VOLUME_INSTANCE_2: + param_hdr->module_id = ASM_MODULE_ID_VOL_CTRL2; + param_hdr->instance_id = INSTANCE_ID_0; + return 0; + case SOFT_VOLUME_INSTANCE_1: + param_hdr->module_id = ASM_MODULE_ID_VOL_CTRL; + param_hdr->instance_id = INSTANCE_ID_0; + return 0; + default: + pr_err("%s: Invalid instance %d\n", __func__, instance); + return -EINVAL; + } +} +EXPORT_SYMBOL(q6asm_set_soft_volume_module_instance_ids); + static int __q6asm_open_read(struct audio_client *ac, uint32_t format, uint16_t bits_per_sample, uint32_t pcm_format_block_ver, @@ -6741,67 +6877,27 @@ fail_cmd: int q6asm_set_lrgain(struct audio_client *ac, int left_gain, int right_gain) { struct asm_volume_ctrl_multichannel_gain multi_ch_gain; - int sz = 0; + struct param_hdr_v3 param_info = {0}; int rc = 0; - if (ac == NULL) { - pr_err("%s: APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } - if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } - memset(&multi_ch_gain, 0, sizeof(multi_ch_gain)); - sz = sizeof(struct asm_volume_ctrl_multichannel_gain); - q6asm_add_hdr_async(ac, &multi_ch_gain.hdr, sz, TRUE); - atomic_set(&ac->cmd_state_pp, -1); - multi_ch_gain.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - multi_ch_gain.param.data_payload_addr_lsw = 0; - multi_ch_gain.param.data_payload_addr_msw = 0; - multi_ch_gain.param.mem_map_handle = 0; - multi_ch_gain.param.data_payload_size = sizeof(multi_ch_gain) - - sizeof(multi_ch_gain.hdr) - sizeof(multi_ch_gain.param); - multi_ch_gain.data.module_id = ASM_MODULE_ID_VOL_CTRL; - multi_ch_gain.data.param_id = ASM_PARAM_ID_MULTICHANNEL_GAIN; - multi_ch_gain.data.param_size = multi_ch_gain.param.data_payload_size - - sizeof(multi_ch_gain.data); - multi_ch_gain.data.reserved = 0; + + param_info.module_id = ASM_MODULE_ID_VOL_CTRL; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = ASM_PARAM_ID_MULTICHANNEL_GAIN; + param_info.param_size = sizeof(multi_ch_gain); + multi_ch_gain.gain_data[0].channeltype = PCM_CHANNEL_FL; multi_ch_gain.gain_data[0].gain = left_gain << 15; multi_ch_gain.gain_data[1].channeltype = PCM_CHANNEL_FR; multi_ch_gain.gain_data[1].gain = right_gain << 15; multi_ch_gain.num_channels = 2; - rc = apr_send_pkt(ac->apr, (uint32_t *) &multi_ch_gain); - if (rc < 0) { + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info, + (u8 *) &multi_ch_gain); + if (rc < 0) pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", - __func__, multi_ch_gain.data.param_id, rc); - rc = -EINVAL; - goto fail_cmd; - } + __func__, param_info.param_id, rc); - rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ); - if (!rc) { - pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, - multi_ch_gain.data.param_id); - rc = -ETIMEDOUT; - goto fail_cmd; - } - if (atomic_read(&ac->cmd_state_pp) > 0) { - pr_err("%s: DSP returned error[%s] , set-params paramid[0x%x]\n", - __func__, adsp_err_get_err_str( - atomic_read(&ac->cmd_state_pp)), - multi_ch_gain.data.param_id); - rc = adsp_err_get_lnx_err_code( - atomic_read(&ac->cmd_state_pp)); - goto fail_cmd; - } - rc = 0; -fail_cmd: return rc; } @@ -6817,20 +6913,14 @@ int q6asm_set_multich_gain(struct audio_client *ac, uint32_t channels, uint32_t *gains, uint8_t *ch_map, bool use_default) { struct asm_volume_ctrl_multichannel_gain multich_gain; - int sz = 0; + struct param_hdr_v3 param_info = {0}; int rc = 0; int i; u8 default_chmap[VOLUME_CONTROL_MAX_CHANNELS]; if (ac == NULL) { - pr_err("%s: ac is NULL\n", __func__); - rc = -EINVAL; - goto done; - } - if (ac->apr == NULL) { - dev_err(ac->dev, "%s: AC APR handle NULL\n", __func__); - rc = -EINVAL; - goto done; + pr_err("%s: Audio client is NULL\n", __func__); + return -EINVAL; } if (gains == NULL) { dev_err(ac->dev, "%s: gain_list is NULL\n", __func__); @@ -6850,20 +6940,10 @@ int q6asm_set_multich_gain(struct audio_client *ac, uint32_t channels, } memset(&multich_gain, 0, sizeof(multich_gain)); - sz = sizeof(struct asm_volume_ctrl_multichannel_gain); - q6asm_add_hdr_async(ac, &multich_gain.hdr, sz, TRUE); - atomic_set(&ac->cmd_state_pp, -1); - multich_gain.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - multich_gain.param.data_payload_addr_lsw = 0; - multich_gain.param.data_payload_addr_msw = 0; - multich_gain.param.mem_map_handle = 0; - multich_gain.param.data_payload_size = sizeof(multich_gain) - - sizeof(multich_gain.hdr) - sizeof(multich_gain.param); - multich_gain.data.module_id = ASM_MODULE_ID_VOL_CTRL; - multich_gain.data.param_id = ASM_PARAM_ID_MULTICHANNEL_GAIN; - multich_gain.data.param_size = multich_gain.param.data_payload_size - - sizeof(multich_gain.data); - multich_gain.data.reserved = 0; + param_info.module_id = ASM_MODULE_ID_VOL_CTRL; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = ASM_PARAM_ID_MULTICHANNEL_GAIN; + param_info.param_size = sizeof(multich_gain); if (use_default) { rc = q6asm_map_channels(default_chmap, channels, false); @@ -6882,166 +6962,56 @@ int q6asm_set_multich_gain(struct audio_client *ac, uint32_t channels, } multich_gain.num_channels = channels; - rc = apr_send_pkt(ac->apr, (uint32_t *) &multich_gain); - if (rc < 0) { + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info, + (u8 *) &multich_gain); + if (rc) pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", - __func__, multich_gain.data.param_id, rc); - goto done; - } - - rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ); - if (!rc) { - pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, - multich_gain.data.param_id); - rc = -EINVAL; - goto done; - } - if (atomic_read(&ac->cmd_state_pp) > 0) { - pr_err("%s: DSP returned error[%d] , set-params paramid[0x%x]\n", - __func__, atomic_read(&ac->cmd_state_pp), - multich_gain.data.param_id); - rc = -EINVAL; - goto done; - } - rc = 0; + __func__, param_info.param_id, rc); done: return rc; } int q6asm_set_mute(struct audio_client *ac, int muteflag) { - struct asm_volume_ctrl_mute_config mute; - int sz = 0; + struct asm_volume_ctrl_mute_config mute = {0}; + struct param_hdr_v3 param_info = {0}; int rc = 0; - if (ac == NULL) { - pr_err("%s: APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } - if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } - - sz = sizeof(struct asm_volume_ctrl_mute_config); - q6asm_add_hdr_async(ac, &mute.hdr, sz, TRUE); - atomic_set(&ac->cmd_state_pp, -1); - mute.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - mute.param.data_payload_addr_lsw = 0; - mute.param.data_payload_addr_msw = 0; - mute.param.mem_map_handle = 0; - mute.param.data_payload_size = sizeof(mute) - - sizeof(mute.hdr) - sizeof(mute.param); - mute.data.module_id = ASM_MODULE_ID_VOL_CTRL; - mute.data.param_id = ASM_PARAM_ID_VOL_CTRL_MUTE_CONFIG; - mute.data.param_size = mute.param.data_payload_size - sizeof(mute.data); - mute.data.reserved = 0; + param_info.module_id = ASM_MODULE_ID_VOL_CTRL; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = ASM_PARAM_ID_VOL_CTRL_MUTE_CONFIG; + param_info.param_size = sizeof(mute); mute.mute_flag = muteflag; - rc = apr_send_pkt(ac->apr, (uint32_t *) &mute); - if (rc < 0) { + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info, (u8 *) &mute); + if (rc) pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", - __func__, mute.data.param_id, rc); - rc = -EINVAL; - goto fail_cmd; - } - - rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ); - if (!rc) { - pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, - mute.data.param_id); - rc = -ETIMEDOUT; - goto fail_cmd; - } - if (atomic_read(&ac->cmd_state_pp) > 0) { - pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n", - __func__, adsp_err_get_err_str( - atomic_read(&ac->cmd_state_pp)), - mute.data.param_id); - rc = adsp_err_get_lnx_err_code( - atomic_read(&ac->cmd_state_pp)); - goto fail_cmd; - } - rc = 0; -fail_cmd: + __func__, param_info.param_id, rc); return rc; } static int __q6asm_set_volume(struct audio_client *ac, int volume, int instance) { - struct asm_volume_ctrl_master_gain vol; - int sz = 0; - int rc = 0; - int module_id; - - if (ac == NULL) { - pr_err("%s: APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } - if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } + struct asm_volume_ctrl_master_gain vol = {0}; + struct param_hdr_v3 param_info = {0}; + int rc = 0; - switch (instance) { - case SOFT_VOLUME_INSTANCE_2: - module_id = ASM_MODULE_ID_VOL_CTRL2; - break; - case SOFT_VOLUME_INSTANCE_1: - default: - module_id = ASM_MODULE_ID_VOL_CTRL; - break; + rc = q6asm_set_soft_volume_module_instance_ids(instance, ¶m_info); + if (rc) { + pr_err("%s: Failed to pack soft volume module and instance IDs, error %d\n", + __func__, rc); + return rc; } - sz = sizeof(struct asm_volume_ctrl_master_gain); - q6asm_add_hdr_async(ac, &vol.hdr, sz, TRUE); - atomic_set(&ac->cmd_state_pp, -1); - vol.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - vol.param.data_payload_addr_lsw = 0; - vol.param.data_payload_addr_msw = 0; - vol.param.mem_map_handle = 0; - vol.param.data_payload_size = sizeof(vol) - - sizeof(vol.hdr) - sizeof(vol.param); - vol.data.module_id = module_id; - vol.data.param_id = ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN; - vol.data.param_size = vol.param.data_payload_size - sizeof(vol.data); - vol.data.reserved = 0; + param_info.param_id = ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN; + param_info.param_size = sizeof(vol); vol.master_gain = volume; - rc = apr_send_pkt(ac->apr, (uint32_t *) &vol); - if (rc < 0) { + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info, (u8 *) &vol); + if (rc) pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", - __func__, vol.data.param_id, rc); - rc = -EINVAL; - goto fail_cmd; - } + __func__, param_info.param_id, rc); - rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ); - if (!rc) { - pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, - vol.data.param_id); - rc = -ETIMEDOUT; - goto fail_cmd; - } - if (atomic_read(&ac->cmd_state_pp) > 0) { - pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n", - __func__, adsp_err_get_err_str( - atomic_read(&ac->cmd_state_pp)), - vol.data.param_id); - rc = adsp_err_get_lnx_err_code( - atomic_read(&ac->cmd_state_pp)); - goto fail_cmd; - } - - rc = 0; -fail_cmd: return rc; } @@ -7240,68 +7210,26 @@ done: int q6asm_set_softpause(struct audio_client *ac, struct asm_softpause_params *pause_param) { - struct asm_soft_pause_params softpause; - int sz = 0; + struct asm_soft_pause_params softpause = {0}; + struct param_hdr_v3 param_info = {0}; int rc = 0; - if (ac == NULL) { - pr_err("%s: APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } - if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } + param_info.module_id = ASM_MODULE_ID_VOL_CTRL; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = ASM_PARAM_ID_SOFT_PAUSE_PARAMETERS; + param_info.param_size = sizeof(softpause); - sz = sizeof(struct asm_soft_pause_params); - q6asm_add_hdr_async(ac, &softpause.hdr, sz, TRUE); - atomic_set(&ac->cmd_state_pp, -1); - softpause.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - - softpause.param.data_payload_addr_lsw = 0; - softpause.param.data_payload_addr_msw = 0; - softpause.param.mem_map_handle = 0; - softpause.param.data_payload_size = sizeof(softpause) - - sizeof(softpause.hdr) - sizeof(softpause.param); - softpause.data.module_id = ASM_MODULE_ID_VOL_CTRL; - softpause.data.param_id = ASM_PARAM_ID_SOFT_PAUSE_PARAMETERS; - softpause.data.param_size = softpause.param.data_payload_size - - sizeof(softpause.data); - softpause.data.reserved = 0; softpause.enable_flag = pause_param->enable; softpause.period = pause_param->period; softpause.step = pause_param->step; softpause.ramping_curve = pause_param->rampingcurve; - rc = apr_send_pkt(ac->apr, (uint32_t *) &softpause); - if (rc < 0) { + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info, + (u8 *) &softpause); + if (rc) pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", - __func__, softpause.data.param_id, rc); - rc = -EINVAL; - goto fail_cmd; - } + __func__, param_info.param_id, rc); - rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ); - if (!rc) { - pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, - softpause.data.param_id); - rc = -ETIMEDOUT; - goto fail_cmd; - } - if (atomic_read(&ac->cmd_state_pp) > 0) { - pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n", - __func__, adsp_err_get_err_str( - atomic_read(&ac->cmd_state_pp)), - softpause.data.param_id); - rc = adsp_err_get_lnx_err_code( - atomic_read(&ac->cmd_state_pp)); - goto fail_cmd; - } - rc = 0; -fail_cmd: return rc; } @@ -7309,77 +7237,30 @@ static int __q6asm_set_softvolume(struct audio_client *ac, struct asm_softvolume_params *softvol_param, int instance) { - struct asm_soft_step_volume_params softvol; - int sz = 0; - int rc = 0; - int module_id; + struct asm_soft_step_volume_params softvol = {0}; + struct param_hdr_v3 param_info = {0}; + int rc = 0; - if (ac == NULL) { - pr_err("%s: APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } - if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; + rc = q6asm_set_soft_volume_module_instance_ids(instance, ¶m_info); + if (rc) { + pr_err("%s: Failed to pack soft volume module and instance IDs, error %d\n", + __func__, rc); + return rc; } - switch (instance) { - case SOFT_VOLUME_INSTANCE_2: - module_id = ASM_MODULE_ID_VOL_CTRL2; - break; - case SOFT_VOLUME_INSTANCE_1: - default: - module_id = ASM_MODULE_ID_VOL_CTRL; - break; - } + param_info.param_id = ASM_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS; + param_info.param_size = sizeof(softvol); - sz = sizeof(struct asm_soft_step_volume_params); - q6asm_add_hdr_async(ac, &softvol.hdr, sz, TRUE); - atomic_set(&ac->cmd_state_pp, -1); - softvol.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - softvol.param.data_payload_addr_lsw = 0; - softvol.param.data_payload_addr_msw = 0; - softvol.param.mem_map_handle = 0; - softvol.param.data_payload_size = sizeof(softvol) - - sizeof(softvol.hdr) - sizeof(softvol.param); - softvol.data.module_id = module_id; - softvol.data.param_id = ASM_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS; - softvol.data.param_size = softvol.param.data_payload_size - - sizeof(softvol.data); - softvol.data.reserved = 0; softvol.period = softvol_param->period; softvol.step = softvol_param->step; softvol.ramping_curve = softvol_param->rampingcurve; - rc = apr_send_pkt(ac->apr, (uint32_t *) &softvol); - if (rc < 0) { + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info, + (u8 *) &softvol); + if (rc) pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", - __func__, softvol.data.param_id, rc); - rc = -EINVAL; - goto fail_cmd; - } + __func__, param_info.param_id, rc); - rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ); - if (!rc) { - pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, - softvol.data.param_id); - rc = -ETIMEDOUT; - goto fail_cmd; - } - if (atomic_read(&ac->cmd_state_pp) > 0) { - pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n", - __func__, adsp_err_get_err_str( - atomic_read(&ac->cmd_state_pp)), - softvol.data.param_id); - rc = adsp_err_get_lnx_err_code( - atomic_read(&ac->cmd_state_pp)); - goto fail_cmd; - } - rc = 0; -fail_cmd: return rc; } @@ -7400,334 +7281,156 @@ int q6asm_set_softvolume_v2(struct audio_client *ac, int q6asm_set_vol_ctrl_gain_pair(struct audio_client *ac, struct asm_stream_pan_ctrl_params *pan_param) { - int sz = 0; - int rc = 0; + struct audproc_volume_ctrl_multichannel_gain gain_data; + struct param_hdr_v3 param_hdr = {0}; + int num_out_ch = 0; int i = 0; - int32_t ch = 0; - struct apr_hdr hdr; - struct audproc_volume_ctrl_channel_type_gain_pair - gain_data[ASM_MAX_CHANNELS]; - struct asm_stream_cmd_set_pp_params_v2 payload_params; - struct asm_stream_param_data_v2 data; - uint16_t *asm_params = NULL; - - if (ac == NULL) { - pr_err("%s: ac is NULL\n", __func__); - rc = -EINVAL; - goto fail; - } - if (ac->apr == NULL) { - dev_err(ac->dev, "%s: ac apr handle NULL\n", __func__); - rc = -EINVAL; - goto fail; - } + int rc = 0; - sz = sizeof(struct apr_hdr) + - sizeof(struct asm_stream_cmd_set_pp_params_v2) + - sizeof(struct asm_stream_param_data_v2) + - sizeof(uint32_t) + - (sizeof(struct audproc_volume_ctrl_channel_type_gain_pair) * - ASM_MAX_CHANNELS); - asm_params = kzalloc(sz, GFP_KERNEL); - if (!asm_params) { - rc = -ENOMEM; - goto fail; + if (pan_param == NULL) { + pr_err("%s: Pan parameter is NULL\n", __func__); + return -EINVAL; } - q6asm_add_hdr_async(ac, &hdr, sz, TRUE); - atomic_set(&ac->cmd_state_pp, -1); + memset(&gain_data, 0, sizeof(gain_data)); - hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - memcpy(((u8 *)asm_params), &hdr, sizeof(struct apr_hdr)); - - payload_params.data_payload_addr_lsw = 0; - payload_params.data_payload_addr_msw = 0; - payload_params.mem_map_handle = 0; - payload_params.data_payload_size = - sizeof(struct asm_stream_param_data_v2) + - sizeof(uint32_t) + - (sizeof(struct audproc_volume_ctrl_channel_type_gain_pair) * - ASM_MAX_CHANNELS); - memcpy(((u8 *)asm_params + sizeof(struct apr_hdr)), - &payload_params, - sizeof(struct asm_stream_cmd_set_pp_params_v2)); - - data.module_id = AUDPROC_MODULE_ID_VOL_CTRL; - data.param_id = AUDPROC_PARAM_ID_MULTICHANNEL_GAIN; - data.param_size = sizeof(uint32_t) + - (sizeof(struct audproc_volume_ctrl_channel_type_gain_pair) * - ASM_MAX_CHANNELS); - data.reserved = 0; - memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) + - sizeof(struct asm_stream_cmd_set_pp_params_v2)), - &data, sizeof(struct asm_stream_param_data_v2)); - - ch = pan_param->num_output_channels; - memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) + - sizeof(struct asm_stream_cmd_set_pp_params_v2) + - sizeof(struct asm_stream_param_data_v2)), - &ch, - sizeof(uint32_t)); - - memset(gain_data, 0, - ASM_MAX_CHANNELS * - sizeof(struct audproc_volume_ctrl_channel_type_gain_pair)); - for (i = 0; i < pan_param->num_output_channels; i++) { - gain_data[i].channel_type = - pan_param->output_channel_map[i]; - gain_data[i].gain = pan_param->gain[i]; - } - memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) + - sizeof(struct asm_stream_cmd_set_pp_params_v2) + - sizeof(struct asm_stream_param_data_v2) + - sizeof(uint32_t)), - gain_data, - ASM_MAX_CHANNELS * - sizeof(struct audproc_volume_ctrl_channel_type_gain_pair)); + param_hdr.module_id = AUDPROC_MODULE_ID_VOL_CTRL; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_MULTICHANNEL_GAIN; + param_hdr.param_size = sizeof(gain_data); - rc = apr_send_pkt(ac->apr, (uint32_t *) asm_params); - if (rc < 0) { - pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", - __func__, data.param_id, rc); - goto done; + num_out_ch = pan_param->num_output_channels; + if (num_out_ch > ASM_MAX_CHANNELS) { + pr_err("%s: Invalid number of output channels %d\n", __func__, + num_out_ch); + return -EINVAL; } + gain_data.num_channels = num_out_ch; - rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state_pp) >= 0), 5 * HZ); - if (!rc) { - pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, - data.param_id); - rc = -EINVAL; - goto done; - } - if (atomic_read(&ac->cmd_state_pp) > 0) { - pr_err("%s: DSP returned error[%d], set-params paramid[0x%x]\n", - __func__, atomic_read(&ac->cmd_state_pp), - data.param_id); - rc = -EINVAL; - goto done; + for (i = 0; i < num_out_ch; i++) { + gain_data.gain_data[i].channel_type = + pan_param->output_channel_map[i]; + gain_data.gain_data[i].gain = pan_param->gain[i]; } - rc = 0; -done: - kfree(asm_params); -fail: + + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_hdr, + (uint8_t *) &gain_data); + if (rc < 0) + pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", + __func__, param_hdr.param_id, rc); return rc; } int q6asm_set_mfc_panning_params(struct audio_client *ac, struct asm_stream_pan_ctrl_params *pan_param) { - int sz, rc, i; - struct audproc_mfc_output_media_fmt mfc_cfg; - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 payload_params; - struct asm_stream_param_data_v2 data; - struct audproc_chmixer_param_coeff pan_cfg; - uint16_t variable_payload = 0; - char *asm_params = NULL; - uint16_t ii; - uint16_t *dst_gain_ptr = NULL; - sz = rc = i = 0; - if (ac == NULL) { - pr_err("%s: ac handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd1; - } - if (ac->apr == NULL) { - pr_err("%s: ac apr handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd1; - } + struct audproc_mfc_param_media_fmt mfc_cfg = {0}; + struct audproc_chmixer_param_coeff *chmixer_cfg; + struct param_hdr_v3 param_hdr = {0}; + u16 *dst_gain_ptr = NULL; + int num_out_ch; + int num_in_ch; + int chmixer_cfg_size = 0; + int packed_data_size = 0; + int out_ch_map_size; + int in_ch_map_size; + int gain_size; + int i = 0; + int rc = 0; + + if (!pan_param) + return -EINVAL; + + num_out_ch = pan_param->num_output_channels; + num_in_ch = pan_param->num_input_channels; + + param_hdr.module_id = AUDPROC_MODULE_ID_MFC; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT; + param_hdr.param_size = sizeof(mfc_cfg); - sz = sizeof(struct audproc_mfc_output_media_fmt); - q6asm_add_hdr_async(ac, &mfc_cfg.params.hdr, sz, TRUE); - atomic_set(&ac->cmd_state_pp, -1); - mfc_cfg.params.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - mfc_cfg.params.payload_addr_lsw = 0; - mfc_cfg.params.payload_addr_msw = 0; - mfc_cfg.params.mem_map_handle = 0; - mfc_cfg.params.payload_size = sizeof(mfc_cfg) - sizeof(mfc_cfg.params); - mfc_cfg.data.module_id = AUDPROC_MODULE_ID_MFC; - mfc_cfg.data.param_id = AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT; - mfc_cfg.data.param_size = mfc_cfg.params.payload_size - - sizeof(mfc_cfg.data); - mfc_cfg.data.reserved = 0; mfc_cfg.sampling_rate = 0; mfc_cfg.bits_per_sample = 0; - mfc_cfg.num_channels = pan_param->num_output_channels; - for (i = 0; i < mfc_cfg.num_channels; i++) + mfc_cfg.num_channels = num_out_ch; + for (i = 0; i < num_out_ch; i++) mfc_cfg.channel_type[i] = pan_param->output_channel_map[i]; - rc = apr_send_pkt(ac->apr, (uint32_t *) &mfc_cfg); + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_hdr, + (uint8_t *) &mfc_cfg); if (rc < 0) { pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", - __func__, mfc_cfg.data.param_id, rc); - rc = -EINVAL; - goto fail_cmd1; + __func__, param_hdr.param_id, rc); + return rc; } - rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ); - if (!rc) { - pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, - mfc_cfg.data.param_id); - rc = -ETIMEDOUT; - goto fail_cmd1; - } - if (atomic_read(&ac->cmd_state_pp) > 0) { - pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n", - __func__, adsp_err_get_err_str( - atomic_read(&ac->cmd_state_pp)), - mfc_cfg.data.param_id); - rc = adsp_err_get_lnx_err_code( - atomic_read(&ac->cmd_state_pp)); - goto fail_cmd1; - } + out_ch_map_size = num_out_ch * sizeof(uint16_t); + in_ch_map_size = num_in_ch * sizeof(uint16_t); + gain_size = num_out_ch * num_in_ch * sizeof(uint16_t); - variable_payload = pan_param->num_output_channels * sizeof(uint16_t)+ - pan_param->num_input_channels * sizeof(uint16_t) + - pan_param->num_output_channels * - pan_param->num_input_channels * sizeof(uint16_t); - i = (variable_payload % sizeof(uint32_t)); - variable_payload += (i == 0) ? 0 : sizeof(uint32_t) - i; - sz = sizeof(struct apr_hdr) + - sizeof(struct asm_stream_cmd_set_pp_params_v2) + - sizeof(struct asm_stream_param_data_v2) + - sizeof(struct audproc_chmixer_param_coeff) + - variable_payload; + chmixer_cfg_size = sizeof(struct audproc_chmixer_param_coeff) + + out_ch_map_size + in_ch_map_size + gain_size; + chmixer_cfg = kzalloc(chmixer_cfg_size, GFP_KERNEL); + if (!chmixer_cfg) + return -ENOMEM; - asm_params = kzalloc(sz, GFP_KERNEL); - if (!asm_params) { - rc = -ENOMEM; - goto fail_cmd1; - } + param_hdr.module_id = AUDPROC_MODULE_ID_MFC; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AUDPROC_CHMIXER_PARAM_ID_COEFF; + param_hdr.param_size = chmixer_cfg_size; - q6asm_add_hdr_async(ac, &hdr, sz, TRUE); - atomic_set(&ac->cmd_state_pp, -1); - hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - memcpy(((u8 *)asm_params), &hdr, sizeof(struct apr_hdr)); - - payload_params.data_payload_addr_lsw = 0; - payload_params.data_payload_addr_msw = 0; - payload_params.mem_map_handle = 0; - payload_params.data_payload_size = - sizeof(struct audproc_chmixer_param_coeff) + - variable_payload + sizeof(struct asm_stream_param_data_v2); - memcpy(((u8 *)asm_params + sizeof(struct apr_hdr)), - &payload_params, - sizeof(struct asm_stream_cmd_set_pp_params_v2)); - - data.module_id = AUDPROC_MODULE_ID_MFC; - data.param_id = AUDPROC_CHMIXER_PARAM_ID_COEFF; - data.param_size = sizeof(struct audproc_chmixer_param_coeff) + - variable_payload; - data.reserved = 0; - memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) + - sizeof(struct asm_stream_cmd_set_pp_params_v2)), - &data, sizeof(struct asm_stream_param_data_v2)); - - pan_cfg.index = 0; - pan_cfg.num_output_channels = pan_param->num_output_channels; - pan_cfg.num_input_channels = pan_param->num_input_channels; - memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) + - sizeof(struct asm_stream_cmd_set_pp_params_v2) + - sizeof(struct asm_stream_param_data_v2)), - &pan_cfg, sizeof(struct audproc_chmixer_param_coeff)); - memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) + - sizeof(struct asm_stream_cmd_set_pp_params_v2) + - sizeof(struct asm_stream_param_data_v2) + - sizeof(struct audproc_chmixer_param_coeff)), - pan_param->output_channel_map, - pan_param->num_output_channels * sizeof(uint16_t)); - memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) + - sizeof(struct asm_stream_cmd_set_pp_params_v2) + - sizeof(struct asm_stream_param_data_v2) + - sizeof(struct audproc_chmixer_param_coeff) + - pan_param->num_output_channels * sizeof(uint16_t)), - pan_param->input_channel_map, - pan_param->num_input_channels * sizeof(uint16_t)); - - dst_gain_ptr = (uint16_t *) ((u8 *)asm_params + sizeof(struct apr_hdr) + - sizeof(struct asm_stream_cmd_set_pp_params_v2) + - sizeof(struct asm_stream_param_data_v2) + - sizeof(struct audproc_chmixer_param_coeff) + - (pan_param->num_output_channels * sizeof(uint16_t)) + - (pan_param->num_input_channels * sizeof(uint16_t))); - for (ii = 0; ii < pan_param->num_output_channels * - pan_param->num_input_channels; ii++) - dst_gain_ptr[ii] = (uint16_t) pan_param->gain[ii]; + chmixer_cfg->index = 0; + chmixer_cfg->num_output_channels = num_out_ch; + chmixer_cfg->num_input_channels = num_in_ch; - rc = apr_send_pkt(ac->apr, (uint32_t *) asm_params); + /* Repack channel data as max channels may not be used */ + memcpy(chmixer_cfg->payload, pan_param->output_channel_map, + out_ch_map_size); + packed_data_size += out_ch_map_size; + + memcpy(chmixer_cfg->payload + packed_data_size, + pan_param->input_channel_map, in_ch_map_size); + packed_data_size += in_ch_map_size; + + dst_gain_ptr = (uint16_t *) chmixer_cfg->payload + packed_data_size; + for (i = 0; i < num_out_ch * num_in_ch; i++) + dst_gain_ptr[i] = (uint16_t) pan_param->gain[i]; + + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_hdr, + (uint8_t *) chmixer_cfg); if (rc < 0) { pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", - __func__, data.param_id, rc); + __func__, param_hdr.param_id, rc); rc = -EINVAL; - goto fail_cmd2; } + kfree(chmixer_cfg); - rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ); - if (!rc) { - pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, - data.param_id); - rc = -ETIMEDOUT; - goto fail_cmd2; - } - if (atomic_read(&ac->cmd_state_pp) > 0) { - pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n", - __func__, adsp_err_get_err_str( - atomic_read(&ac->cmd_state_pp)), - data.param_id); - rc = adsp_err_get_lnx_err_code( - atomic_read(&ac->cmd_state_pp)); - goto fail_cmd2; - } - rc = 0; -fail_cmd2: - kfree(asm_params); -fail_cmd1: return rc; } int q6asm_equalizer(struct audio_client *ac, void *eq_p) { - struct asm_eq_params eq; + struct asm_eq_params eq = {0}; struct msm_audio_eq_stream_config *eq_params = NULL; + struct param_hdr_v3 param_info = {0}; int i = 0; - int sz = 0; int rc = 0; if (ac == NULL) { - pr_err("%s: APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; - } - if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); - rc = -EINVAL; - goto fail_cmd; + pr_err("%s: Audio client is NULL\n", __func__); + return -EINVAL; } - if (eq_p == NULL) { pr_err("%s: [%d]: Invalid Eq param\n", __func__, ac->session); rc = -EINVAL; goto fail_cmd; } - sz = sizeof(struct asm_eq_params); - eq_params = (struct msm_audio_eq_stream_config *) eq_p; - q6asm_add_hdr(ac, &eq.hdr, sz, TRUE); - atomic_set(&ac->cmd_state_pp, -1); - eq.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - eq.param.data_payload_addr_lsw = 0; - eq.param.data_payload_addr_msw = 0; - eq.param.mem_map_handle = 0; - eq.param.data_payload_size = sizeof(eq) - - sizeof(eq.hdr) - sizeof(eq.param); - eq.data.module_id = ASM_MODULE_ID_EQUALIZER; - eq.data.param_id = ASM_PARAM_ID_EQUALIZER_PARAMETERS; - eq.data.param_size = eq.param.data_payload_size - sizeof(eq.data); + eq_params = (struct msm_audio_eq_stream_config *) eq_p; + param_info.module_id = ASM_MODULE_ID_EQUALIZER; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = ASM_PARAM_ID_EQUALIZER_PARAMETERS; + param_info.param_size = sizeof(eq); eq.enable_flag = eq_params->enable; eq.num_bands = eq_params->num_bands; @@ -7753,32 +7456,11 @@ int q6asm_equalizer(struct audio_client *ac, void *eq_p) pr_debug("%s: q_factor:%d bandnum:%d\n", __func__, eq_params->eq_bands[i].q_factor, i); } - rc = apr_send_pkt(ac->apr, (uint32_t *)&eq); - if (rc < 0) { + rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info, (u8 *) &eq); + if (rc) pr_err("%s: set-params send failed paramid[0x%x] rc %d\n", - __func__, eq.data.param_id, rc); - rc = -EINVAL; - goto fail_cmd; - } + __func__, param_info.param_id, rc); - rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ); - if (!rc) { - pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__, - eq.data.param_id); - rc = -ETIMEDOUT; - goto fail_cmd; - } - if (atomic_read(&ac->cmd_state_pp) > 0) { - pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n", - __func__, adsp_err_get_err_str( - atomic_read(&ac->cmd_state_pp)), - eq.data.param_id); - rc = adsp_err_get_lnx_err_code( - atomic_read(&ac->cmd_state_pp)); - goto fail_cmd; - } - rc = 0; fail_cmd: return rc; } @@ -8293,7 +7975,7 @@ int q6asm_get_session_time(struct audio_client *ac, uint64_t *tstamp) mtmx_params.param_info.param_id = ASM_SESSION_MTMX_STRTR_PARAM_SESSION_TIME_V3; mtmx_params.param_info.param_max_size = - sizeof(struct asm_stream_param_data_v2) + + sizeof(struct param_hdr_v1) + sizeof(struct asm_session_mtmx_strtr_param_session_time_v3_t); atomic_set(&ac->time_flag, 1); @@ -8366,79 +8048,6 @@ fail_cmd: return -EINVAL; } - -int q6asm_send_audio_effects_params(struct audio_client *ac, char *params, - uint32_t params_length) -{ - char *asm_params = NULL; - struct apr_hdr hdr; - struct asm_stream_cmd_set_pp_params_v2 payload_params; - int sz, rc; - - pr_debug("%s:\n", __func__); - if (!ac) { - pr_err("%s: APR handle NULL\n", __func__); - return -EINVAL; - } - if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); - return -EINVAL; - } - if (params == NULL) { - pr_err("%s: params NULL\n", __func__); - return -EINVAL; - } - sz = sizeof(struct apr_hdr) + - sizeof(struct asm_stream_cmd_set_pp_params_v2) + - params_length; - asm_params = kzalloc(sz, GFP_KERNEL); - if (!asm_params) { - pr_err("%s, asm params memory alloc failed", __func__); - return -ENOMEM; - } - q6asm_add_hdr_async(ac, &hdr, (sizeof(struct apr_hdr) + - sizeof(struct asm_stream_cmd_set_pp_params_v2) + - params_length), TRUE); - atomic_set(&ac->cmd_state_pp, -1); - hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - payload_params.data_payload_addr_lsw = 0; - payload_params.data_payload_addr_msw = 0; - payload_params.mem_map_handle = 0; - payload_params.data_payload_size = params_length; - memcpy(((u8 *)asm_params), &hdr, sizeof(struct apr_hdr)); - memcpy(((u8 *)asm_params + sizeof(struct apr_hdr)), &payload_params, - sizeof(struct asm_stream_cmd_set_pp_params_v2)); - memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) + - sizeof(struct asm_stream_cmd_set_pp_params_v2)), - params, params_length); - rc = apr_send_pkt(ac->apr, (uint32_t *) asm_params); - if (rc < 0) { - pr_err("%s: audio effects set-params send failed\n", __func__); - rc = -EINVAL; - goto fail_send_param; - } - rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state_pp) >= 0), 1*HZ); - if (!rc) { - pr_err("%s: timeout, audio effects set-params\n", __func__); - rc = -ETIMEDOUT; - goto fail_send_param; - } - if (atomic_read(&ac->cmd_state_pp) > 0) { - pr_err("%s: DSP returned error[%s] set-params\n", - __func__, adsp_err_get_err_str( - atomic_read(&ac->cmd_state_pp))); - rc = adsp_err_get_lnx_err_code( - atomic_read(&ac->cmd_state_pp)); - goto fail_send_param; - } - - rc = 0; -fail_send_param: - kfree(asm_params); - return rc; -} - int q6asm_send_mtmx_strtr_window(struct audio_client *ac, struct asm_session_mtmx_strtr_param_window_v2_t *window_param, uint32_t param_id) @@ -8471,7 +8080,7 @@ int q6asm_send_mtmx_strtr_window(struct audio_client *ac, matrix.param.data_payload_addr_msw = 0; matrix.param.mem_map_handle = 0; matrix.param.data_payload_size = - sizeof(struct asm_stream_param_data_v2) + + sizeof(struct param_hdr_v1) + sizeof(struct asm_session_mtmx_strtr_param_window_v2_t); matrix.param.direction = 0; /* RX */ matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC; @@ -8556,7 +8165,7 @@ int q6asm_send_mtmx_strtr_render_mode(struct audio_client *ac, matrix.param.data_payload_addr_msw = 0; matrix.param.mem_map_handle = 0; matrix.param.data_payload_size = - sizeof(struct asm_stream_param_data_v2) + + sizeof(struct param_hdr_v1) + sizeof(struct asm_session_mtmx_strtr_param_render_mode_t); matrix.param.direction = 0; /* RX */ matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC; @@ -8641,7 +8250,7 @@ int q6asm_send_mtmx_strtr_clk_rec_mode(struct audio_client *ac, matrix.param.data_payload_addr_msw = 0; matrix.param.mem_map_handle = 0; matrix.param.data_payload_size = - sizeof(struct asm_stream_param_data_v2) + + sizeof(struct param_hdr_v1) + sizeof(struct asm_session_mtmx_strtr_param_clk_rec_t); matrix.param.direction = 0; /* RX */ matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC; @@ -8716,7 +8325,7 @@ int q6asm_send_mtmx_strtr_enable_adjust_session_clock(struct audio_client *ac, matrix.param.data_payload_addr_msw = 0; matrix.param.mem_map_handle = 0; matrix.param.data_payload_size = - sizeof(struct asm_stream_param_data_v2) + + sizeof(struct param_hdr_v1) + sizeof(struct asm_session_mtmx_param_adjust_session_time_ctl_t); matrix.param.direction = 0; /* RX */ matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC; @@ -9355,19 +8964,14 @@ done: int q6asm_send_cal(struct audio_client *ac) { struct cal_block_data *cal_block = NULL; - struct apr_hdr hdr; - char *asm_params = NULL; - struct asm_stream_cmd_set_pp_params_v2 payload_params; - int sz, rc = -EINVAL; + struct mem_mapping_hdr mem_hdr = {0}; + u32 payload_size = 0; + int rc = -EINVAL; pr_debug("%s:\n", __func__); if (!ac) { - pr_err("%s: APR handle NULL\n", __func__); - goto done; - } - if (ac->apr == NULL) { - pr_err("%s: AC APR handle NULL\n", __func__); - goto done; + pr_err("%s: Audio client is NULL\n", __func__); + return -EINVAL; } if (ac->io_mode & NT_MODE) { pr_debug("%s: called for NT MODE, exiting\n", __func__); @@ -9404,62 +9008,26 @@ int q6asm_send_cal(struct audio_client *ac) goto unlock; } - sz = sizeof(struct apr_hdr) + - sizeof(struct asm_stream_cmd_set_pp_params_v2); - asm_params = kzalloc(sz, GFP_KERNEL); - if (!asm_params) { - pr_err("%s, asm params memory alloc failed", __func__); - rc = -ENOMEM; - goto unlock; - } - - /* asm_stream_cmd_set_pp_params_v2 has no APR header in it */ - q6asm_add_hdr_async(ac, &hdr, (sizeof(struct apr_hdr) + - sizeof(struct asm_stream_cmd_set_pp_params_v2)), TRUE); - - atomic_set(&ac->cmd_state_pp, -1); - hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2; - payload_params.data_payload_addr_lsw = - lower_32_bits(cal_block->cal_data.paddr); - payload_params.data_payload_addr_msw = - msm_audio_populate_upper_32_bits( - cal_block->cal_data.paddr); - payload_params.mem_map_handle = cal_block->map_data.q6map_handle; - payload_params.data_payload_size = cal_block->cal_data.size; - memcpy(((u8 *)asm_params), &hdr, sizeof(struct apr_hdr)); - memcpy(((u8 *)asm_params + sizeof(struct apr_hdr)), &payload_params, - sizeof(struct asm_stream_cmd_set_pp_params_v2)); + mem_hdr.data_payload_addr_lsw = + lower_32_bits(cal_block->cal_data.paddr); + mem_hdr.data_payload_addr_msw = + msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr); + mem_hdr.mem_map_handle = cal_block->map_data.q6map_handle; + payload_size = cal_block->cal_data.size; pr_debug("%s: phyaddr lsw = %x msw = %x, maphdl = %x calsize = %d\n", - __func__, payload_params.data_payload_addr_lsw, - payload_params.data_payload_addr_msw, - payload_params.mem_map_handle, - payload_params.data_payload_size); + __func__, mem_hdr.data_payload_addr_lsw, + mem_hdr.data_payload_addr_msw, mem_hdr.mem_map_handle, + payload_size); - rc = apr_send_pkt(ac->apr, (uint32_t *) asm_params); - if (rc < 0) { + rc = q6asm_set_pp_params(ac, &mem_hdr, NULL, payload_size); + if (rc) { pr_err("%s: audio audstrm cal send failed\n", __func__); - rc = -EINVAL; - goto free; - } - rc = wait_event_timeout(ac->cmd_wait, - (atomic_read(&ac->cmd_state_pp) >= 0), 5 * HZ); - if (!rc) { - pr_err("%s: timeout, audio audstrm cal send\n", __func__); - rc = -ETIMEDOUT; - goto free; - } - if (atomic_read(&ac->cmd_state_pp) > 0) { - pr_err("%s: DSP returned error[%d] audio audstrm cal send\n", - __func__, atomic_read(&ac->cmd_state_pp)); - rc = -EINVAL; - goto free; + goto unlock; } rc = 0; -free: - kfree(asm_params); unlock: mutex_unlock(&cal_data[ASM_AUDSTRM_CAL]->lock); done: diff --git a/sound/soc/msm/qdsp6v2/q6lsm.c b/sound/soc/msm/qdsp6v2/q6lsm.c index 11574a874a5a..1161bb31c434 100644 --- a/sound/soc/msm/qdsp6v2/q6lsm.c +++ b/sound/soc/msm/qdsp6v2/q6lsm.c @@ -26,6 +26,7 @@ #include <sound/apr_audio-v2.h> #include <sound/lsm_params.h> #include <sound/q6core.h> +#include <sound/q6common.h> #include <sound/q6lsm.h> #include <asm/ioctls.h> #include <linux/memory.h> @@ -73,11 +74,6 @@ struct lsm_common { struct mutex apr_lock; }; -struct lsm_module_param_ids { - uint32_t module_id; - uint32_t param_id; -}; - static struct lsm_common lsm_common; /* * mmap_handle_p can point either client->sound_model.mem_map_handle or @@ -98,38 +94,6 @@ static int q6lsm_memory_map_regions(struct lsm_client *client, static int q6lsm_memory_unmap_regions(struct lsm_client *client, uint32_t handle); -static void q6lsm_set_param_hdr_info( - struct lsm_set_params_hdr *param_hdr, - u32 payload_size, u32 addr_lsw, u32 addr_msw, - u32 mmap_handle) -{ - param_hdr->data_payload_size = payload_size; - param_hdr->data_payload_addr_lsw = addr_lsw; - param_hdr->data_payload_addr_msw = addr_msw; - param_hdr->mem_map_handle = mmap_handle; -} - -static void q6lsm_set_param_common( - struct lsm_param_payload_common *common, - struct lsm_module_param_ids *ids, - u32 param_size, u32 set_param_version) -{ - common->module_id = ids->module_id; - common->param_id = ids->param_id; - - switch (set_param_version) { - case LSM_SESSION_CMD_SET_PARAMS_V2: - common->p_size.param_size = param_size; - break; - case LSM_SESSION_CMD_SET_PARAMS: - default: - common->p_size.sr.param_size = - (u16) param_size; - common->p_size.sr.reserved = 0; - break; - } -} - static int q6lsm_callback(struct apr_client_data *data, void *priv) { struct lsm_client *client = (struct lsm_client *)priv; @@ -199,6 +163,7 @@ static int q6lsm_callback(struct apr_client_data *data, void *priv) case LSM_SESSION_CMD_OPEN_TX_V2: case LSM_CMD_ADD_TOPOLOGIES: case LSM_SESSION_CMD_SET_PARAMS_V2: + case LSM_SESSION_CMD_SET_PARAMS_V3: if (token != client->session && payload[0] != LSM_SESSION_CMD_DEREGISTER_SOUND_MODEL) { @@ -433,6 +398,189 @@ static void q6lsm_add_hdr(struct lsm_client *client, struct apr_hdr *hdr, hdr->token = client->session; } +/* + * LSM still supports 3 versions of commands so it cannot use the common + * Q6Common packing function. No need to check parameter pointers as it + * is static and should only be called internally. + */ +static int q6lsm_pack_params(u8 *dest, struct param_hdr_v3 *param_info, + u8 *param_data, size_t *final_length, + u32 set_param_opcode) +{ + bool iid_supported = q6common_is_instance_id_supported(); + union param_hdrs *param_hdr = NULL; + u32 param_size = param_info->param_size; + size_t hdr_size; + size_t provided_size = *final_length; + + hdr_size = iid_supported ? sizeof(struct param_hdr_v3) : + sizeof(struct param_hdr_v2); + if (provided_size < hdr_size) { + pr_err("%s: Provided size %zu is not large enough, need %zu\n", + __func__, provided_size, hdr_size); + return -EINVAL; + } + + if (iid_supported) { + memcpy(dest, param_info, hdr_size); + } else { + /* MID, PID and structure size are the same in V1 and V2 */ + param_hdr = (union param_hdrs *) dest; + param_hdr->v2.module_id = param_info->module_id; + param_hdr->v2.param_id = param_info->param_id; + + switch (set_param_opcode) { + case LSM_SESSION_CMD_SET_PARAMS_V2: + param_hdr->v2.param_size = param_size; + break; + case LSM_SESSION_CMD_SET_PARAMS: + default: + if (param_size > U16_MAX) { + pr_err("%s: Invalid param size %d\n", __func__, + param_size); + return -EINVAL; + } + + param_hdr->v1.param_size = param_size; + param_hdr->v1.reserved = 0; + break; + } + } + + *final_length = hdr_size; + + if (param_data != NULL) { + if (provided_size < hdr_size + param_size) { + pr_err("%s: Provided size %zu is not large enough, need %zu\n", + __func__, provided_size, hdr_size + param_size); + return -EINVAL; + } + memcpy(dest + hdr_size, param_data, param_size); + *final_length += param_size; + } + return 0; +} + +static int q6lsm_set_params_v2(struct lsm_client *client, + struct mem_mapping_hdr *mem_hdr, + uint8_t *param_data, uint32_t param_size, + uint32_t set_param_opcode) +{ + struct lsm_session_cmd_set_params_v2 *lsm_set_param = NULL; + uint32_t pkt_size = 0; + int ret; + + pkt_size = sizeof(struct lsm_session_cmd_set_params_v2); + /* Only include param size in packet size when inband */ + if (param_data != NULL) + pkt_size += param_size; + + lsm_set_param = kzalloc(pkt_size, GFP_KERNEL); + if (!lsm_set_param) + return -ENOMEM; + + q6lsm_add_hdr(client, &lsm_set_param->apr_hdr, pkt_size, true); + lsm_set_param->apr_hdr.opcode = set_param_opcode; + lsm_set_param->payload_size = param_size; + + if (mem_hdr != NULL) { + lsm_set_param->mem_hdr = *mem_hdr; + } else if (param_data != NULL) { + memcpy(lsm_set_param->param_data, param_data, param_size); + } else { + pr_err("%s: Received NULL pointers for both memory header and data\n", + __func__); + ret = -EINVAL; + goto done; + } + + ret = q6lsm_apr_send_pkt(client, client->apr, lsm_set_param, true, + NULL); +done: + kfree(lsm_set_param); + return ret; +} + +static int q6lsm_set_params_v3(struct lsm_client *client, + struct mem_mapping_hdr *mem_hdr, + uint8_t *param_data, uint32_t param_size) +{ + struct lsm_session_cmd_set_params_v3 *lsm_set_param = NULL; + uint16_t pkt_size = 0; + int ret = 0; + + pkt_size = sizeof(struct lsm_session_cmd_set_params_v3); + /* Only include param size in packet size when inband */ + if (param_data != NULL) + pkt_size += param_size; + + lsm_set_param = kzalloc(pkt_size, GFP_KERNEL); + if (!lsm_set_param) + return -ENOMEM; + + q6lsm_add_hdr(client, &lsm_set_param->apr_hdr, pkt_size, true); + lsm_set_param->apr_hdr.opcode = LSM_SESSION_CMD_SET_PARAMS_V3; + lsm_set_param->payload_size = param_size; + + if (mem_hdr != NULL) { + lsm_set_param->mem_hdr = *mem_hdr; + } else if (param_data != NULL) { + memcpy(lsm_set_param->param_data, param_data, param_size); + } else { + pr_err("%s: Received NULL pointers for both memory header and data\n", + __func__); + ret = -EINVAL; + goto done; + } + + ret = q6lsm_apr_send_pkt(client, client->apr, lsm_set_param, true, + NULL); +done: + kfree(lsm_set_param); + return ret; +} + +static int q6lsm_set_params(struct lsm_client *client, + struct mem_mapping_hdr *mem_hdr, + uint8_t *param_data, uint32_t param_size, + uint32_t set_param_opcode) + +{ + if (q6common_is_instance_id_supported()) + return q6lsm_set_params_v3(client, mem_hdr, param_data, + param_size); + else + return q6lsm_set_params_v2(client, mem_hdr, param_data, + param_size, set_param_opcode); +} + +static int q6lsm_pack_and_set_params(struct lsm_client *client, + struct param_hdr_v3 *param_info, + uint8_t *param_data, + uint32_t set_param_opcode) + +{ + u8 *packed_data = NULL; + size_t total_size = 0; + int ret = 0; + + total_size = sizeof(union param_hdrs) + param_info->param_size; + packed_data = kzalloc(total_size, GFP_KERNEL); + if (!packed_data) + return -ENOMEM; + + ret = q6lsm_pack_params(packed_data, param_info, param_data, + &total_size, set_param_opcode); + if (ret) + goto done; + + ret = q6lsm_set_params(client, NULL, packed_data, total_size, + set_param_opcode); + +done: + kfree(packed_data); + return ret; +} static int q6lsm_send_custom_topologies(struct lsm_client *client) { @@ -586,14 +734,18 @@ void q6lsm_sm_set_param_data(struct lsm_client *client, struct lsm_params_info *p_info, size_t *offset) { - struct lsm_param_payload_common *param; - - param = (struct lsm_param_payload_common *) - client->sound_model.data; - param->module_id = p_info->module_id; - param->param_id = p_info->param_id; - param->p_size.param_size = client->sound_model.size; - *offset = sizeof(*param); + struct param_hdr_v3 param_hdr = {0}; + int ret = 0; + + param_hdr.module_id = p_info->module_id; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = p_info->param_id; + param_hdr.param_size = client->sound_model.size; + + ret = q6lsm_pack_params((u8 *) client->sound_model.data, ¶m_hdr, + NULL, offset, LSM_SESSION_CMD_SET_PARAMS_V2); + if (ret) + pr_err("%s: Failed to pack params, error %d\n", __func__, ret); } int q6lsm_open(struct lsm_client *client, uint16_t app_id) @@ -644,109 +796,64 @@ done: return rc; } -static int q6lsm_send_confidence_levels( - struct lsm_client *client, - struct lsm_module_param_ids *ids, - u32 set_param_opcode) +static int q6lsm_send_confidence_levels(struct lsm_client *client, + struct param_hdr_v3 *param_info, + uint32_t set_param_opcode) { - u8 *packet; - size_t pkt_size; - struct lsm_cmd_set_params_conf *conf_params; - struct apr_hdr *msg_hdr; - struct lsm_param_min_confidence_levels *cfl; + struct lsm_param_confidence_levels *conf_levels = NULL; + uint32_t num_conf_levels = client->num_confidence_levels; uint8_t i = 0; uint8_t padd_size = 0; - u8 *conf_levels; - int rc; - u32 payload_size, param_size; + uint32_t param_size = 0; + int rc = 0; - padd_size = (4 - (client->num_confidence_levels % 4)) - 1; - pkt_size = sizeof(*conf_params) + padd_size + - client->num_confidence_levels; + /* Data must be 4 byte alligned so add any necessary padding. */ + padd_size = (4 - (num_conf_levels % 4)) - 1; + param_size = (sizeof(uint8_t) + num_conf_levels + padd_size) * + sizeof(uint8_t); + param_info->param_size = param_size; + pr_debug("%s: Set Conf Levels PARAM SIZE = %d\n", __func__, param_size); - packet = kzalloc(pkt_size, GFP_KERNEL); - if (!packet) { - pr_err("%s: no memory for confidence level, size = %zd\n", - __func__, pkt_size); + conf_levels = kzalloc(param_size, GFP_KERNEL); + if (!conf_levels) return -ENOMEM; - } - conf_params = (struct lsm_cmd_set_params_conf *) packet; - conf_levels = (u8 *) (packet + sizeof(*conf_params)); - msg_hdr = &conf_params->msg_hdr; - q6lsm_add_hdr(client, msg_hdr, - pkt_size, true); - msg_hdr->opcode = set_param_opcode; - payload_size = pkt_size - sizeof(*msg_hdr) - - sizeof(conf_params->params_hdr); - q6lsm_set_param_hdr_info(&conf_params->params_hdr, - payload_size, 0, 0, 0); - cfl = &conf_params->conf_payload; - param_size = ((sizeof(uint8_t) + padd_size + - client->num_confidence_levels)) * - sizeof(uint8_t); - q6lsm_set_param_common(&cfl->common, ids, - param_size, set_param_opcode); - cfl->num_confidence_levels = client->num_confidence_levels; - - pr_debug("%s: CMD PARAM SIZE = %d\n", - __func__, param_size); - pr_debug("%s: Num conf_level = %d\n", - __func__, client->num_confidence_levels); - - memcpy(conf_levels, client->confidence_levels, - client->num_confidence_levels); - for (i = 0; i < client->num_confidence_levels; i++) - pr_debug("%s: Confidence_level[%d] = %d\n", - __func__, i, conf_levels[i]); + conf_levels->num_confidence_levels = num_conf_levels; + pr_debug("%s: Num conf_level = %d\n", __func__, num_conf_levels); - rc = q6lsm_apr_send_pkt(client, client->apr, - packet, true, NULL); + memcpy(conf_levels->confidence_levels, client->confidence_levels, + num_conf_levels); + for (i = 0; i < num_conf_levels; i++) + pr_debug("%s: Confidence_level[%d] = %d\n", __func__, i, + conf_levels->confidence_levels[i]); + + rc = q6lsm_pack_and_set_params(client, param_info, + (uint8_t *) conf_levels, + set_param_opcode); if (rc) - pr_err("%s: confidence_levels cmd failed, err = %d\n", - __func__, rc); - kfree(packet); + pr_err("%s: Send confidence_levels cmd failed, err = %d\n", + __func__, rc); + kfree(conf_levels); return rc; } static int q6lsm_send_param_opmode(struct lsm_client *client, - struct lsm_module_param_ids *opmode_ids, - u32 set_param_opcode) + struct param_hdr_v3 *param_info, + u32 set_param_opcode) { - int rc; - struct lsm_cmd_set_params_opmode opmode_params; - struct apr_hdr *msg_hdr; - - struct lsm_param_op_mode *op_mode; - u32 data_payload_size, param_size; - - msg_hdr = &opmode_params.msg_hdr; - q6lsm_add_hdr(client, msg_hdr, - sizeof(opmode_params), true); - msg_hdr->opcode = set_param_opcode; - data_payload_size = sizeof(opmode_params) - - sizeof(*msg_hdr) - - sizeof(opmode_params.params_hdr); - q6lsm_set_param_hdr_info(&opmode_params.params_hdr, - data_payload_size, 0, 0, 0); - op_mode = &opmode_params.op_mode; - - - param_size = sizeof(struct lsm_param_op_mode) - - sizeof(op_mode->common); - q6lsm_set_param_common(&op_mode->common, - opmode_ids, param_size, - set_param_opcode); - op_mode->minor_version = QLSM_PARAM_ID_MINOR_VERSION; - op_mode->mode = client->mode; - op_mode->reserved = 0; - pr_debug("%s: mode = 0x%x", __func__, op_mode->mode); + struct lsm_param_op_mode op_mode = {0}; + int rc = 0; - rc = q6lsm_apr_send_pkt(client, client->apr, - &opmode_params, true, NULL); + param_info->param_size = sizeof(op_mode); + + op_mode.minor_version = QLSM_PARAM_ID_MINOR_VERSION; + op_mode.mode = client->mode; + pr_debug("%s: mode = 0x%x", __func__, op_mode.mode); + + rc = q6lsm_pack_and_set_params(client, param_info, (uint8_t *) &op_mode, + set_param_opcode); if (rc) - pr_err("%s: Failed set_params opcode 0x%x, rc %d\n", - __func__, msg_hdr->opcode, rc); + pr_err("%s: Failed set_params, rc %d\n", __func__, rc); pr_debug("%s: leave %d\n", __func__, rc); return rc; @@ -764,138 +871,81 @@ int get_lsm_port(void) int q6lsm_set_port_connected(struct lsm_client *client) { - int rc; - struct lsm_cmd_set_connectport connectport; - struct lsm_module_param_ids connectport_ids; - struct apr_hdr *msg_hdr; - struct lsm_param_connect_to_port *connect_to_port; - u32 data_payload_size, param_size, set_param_opcode; + struct lsm_param_connect_to_port connect_port = {0}; + struct param_hdr_v3 connectport_hdr = {0}; + u32 set_param_opcode = 0; + int rc = 0; if (client->use_topology) { set_param_opcode = LSM_SESSION_CMD_SET_PARAMS_V2; - connectport_ids.module_id = LSM_MODULE_ID_FRAMEWORK; - connectport_ids.param_id = LSM_PARAM_ID_CONNECT_TO_PORT; + connectport_hdr.module_id = LSM_MODULE_ID_FRAMEWORK; } else { set_param_opcode = LSM_SESSION_CMD_SET_PARAMS; - connectport_ids.module_id = LSM_MODULE_ID_VOICE_WAKEUP; - connectport_ids.param_id = LSM_PARAM_ID_CONNECT_TO_PORT; + connectport_hdr.module_id = LSM_MODULE_ID_VOICE_WAKEUP; } - client->connect_to_port = get_lsm_port(); + connectport_hdr.instance_id = INSTANCE_ID_0; + connectport_hdr.param_id = LSM_PARAM_ID_CONNECT_TO_PORT; + connectport_hdr.param_size = sizeof(connect_port); - msg_hdr = &connectport.msg_hdr; - q6lsm_add_hdr(client, msg_hdr, - sizeof(connectport), true); - msg_hdr->opcode = set_param_opcode; - data_payload_size = sizeof(connectport) - - sizeof(*msg_hdr) - - sizeof(connectport.params_hdr); - q6lsm_set_param_hdr_info(&connectport.params_hdr, - data_payload_size, 0, 0, 0); - connect_to_port = &connectport.connect_to_port; - - param_size = (sizeof(struct lsm_param_connect_to_port) - - sizeof(connect_to_port->common)); - q6lsm_set_param_common(&connect_to_port->common, - &connectport_ids, param_size, - set_param_opcode); - connect_to_port->minor_version = QLSM_PARAM_ID_MINOR_VERSION; - connect_to_port->port_id = client->connect_to_port; - connect_to_port->reserved = 0; - pr_debug("%s: port= %d", __func__, connect_to_port->port_id); + client->connect_to_port = get_lsm_port(); + connect_port.minor_version = QLSM_PARAM_ID_MINOR_VERSION; + connect_port.port_id = client->connect_to_port; - rc = q6lsm_apr_send_pkt(client, client->apr, - &connectport, true, NULL); + rc = q6lsm_pack_and_set_params(client, &connectport_hdr, + (uint8_t *) &connect_port, + set_param_opcode); if (rc) - pr_err("%s: Failed set_params opcode 0x%x, rc %d\n", - __func__, msg_hdr->opcode, rc); - + pr_err("%s: Failed set_params, rc %d\n", __func__, rc); return rc; } + static int q6lsm_send_param_polling_enable(struct lsm_client *client, - bool poll_en, - struct lsm_module_param_ids *poll_enable_ids, - u32 set_param_opcode) + bool poll_en, + struct param_hdr_v3 *param_info, + u32 set_param_opcode) { + struct lsm_param_poll_enable polling_enable = {0}; int rc = 0; - struct lsm_cmd_poll_enable cmd; - struct apr_hdr *msg_hdr; - struct lsm_param_poll_enable *poll_enable; - u32 data_payload_size, param_size; - - msg_hdr = &cmd.msg_hdr; - q6lsm_add_hdr(client, msg_hdr, - sizeof(struct lsm_cmd_poll_enable), true); - msg_hdr->opcode = set_param_opcode; - data_payload_size = sizeof(struct lsm_cmd_poll_enable) - - sizeof(struct apr_hdr) - - sizeof(struct lsm_set_params_hdr); - q6lsm_set_param_hdr_info(&cmd.params_hdr, - data_payload_size, 0, 0, 0); - poll_enable = &cmd.poll_enable; - - param_size = (sizeof(struct lsm_param_poll_enable) - - sizeof(poll_enable->common)); - q6lsm_set_param_common(&poll_enable->common, - poll_enable_ids, param_size, - set_param_opcode); - poll_enable->minor_version = QLSM_PARAM_ID_MINOR_VERSION; - poll_enable->polling_enable = (poll_en) ? 1 : 0; - pr_debug("%s: poll enable= %d", __func__, poll_enable->polling_enable); - rc = q6lsm_apr_send_pkt(client, client->apr, - &cmd, true, NULL); - if (rc) - pr_err("%s: Failed set_params opcode 0x%x, rc %d\n", - __func__, msg_hdr->opcode, rc); + param_info->param_size = sizeof(polling_enable); + + polling_enable.minor_version = QLSM_PARAM_ID_MINOR_VERSION; + polling_enable.polling_enable = (poll_en) ? 1 : 0; + rc = q6lsm_pack_and_set_params(client, param_info, + (uint8_t *) &polling_enable, + set_param_opcode); + if (rc) + pr_err("%s: Failed set_params, rc %d\n", __func__, rc); return rc; } int q6lsm_set_fwk_mode_cfg(struct lsm_client *client, uint32_t event_mode) { + struct lsm_param_fwk_mode_cfg fwk_mode_cfg = {0}; + struct param_hdr_v3 fwk_mode_cfg_hdr = {0}; int rc = 0; - struct lsm_cmd_set_fwk_mode_cfg cmd; - struct lsm_module_param_ids fwk_mode_cfg_ids; - struct apr_hdr *msg_hdr; - struct lsm_param_fwk_mode_cfg *fwk_mode_cfg; - u32 data_payload_size, param_size, set_param_opcode; - if (client->use_topology) { - set_param_opcode = LSM_SESSION_CMD_SET_PARAMS_V2; - fwk_mode_cfg_ids.module_id = LSM_MODULE_ID_FRAMEWORK; - fwk_mode_cfg_ids.param_id = LSM_PARAM_ID_FWK_MODE_CONFIG; - } else { + if (!client->use_topology) { pr_debug("%s: Ignore sending event mode\n", __func__); return rc; } - msg_hdr = &cmd.msg_hdr; - q6lsm_add_hdr(client, msg_hdr, - sizeof(struct lsm_cmd_set_fwk_mode_cfg), true); - msg_hdr->opcode = set_param_opcode; - data_payload_size = sizeof(struct lsm_cmd_set_fwk_mode_cfg) - - sizeof(struct apr_hdr) - - sizeof(struct lsm_set_params_hdr); - q6lsm_set_param_hdr_info(&cmd.params_hdr, - data_payload_size, 0, 0, 0); - fwk_mode_cfg = &cmd.fwk_mode_cfg; - - param_size = (sizeof(struct lsm_param_fwk_mode_cfg) - - sizeof(fwk_mode_cfg->common)); - q6lsm_set_param_common(&fwk_mode_cfg->common, - &fwk_mode_cfg_ids, param_size, - set_param_opcode); + fwk_mode_cfg_hdr.module_id = LSM_MODULE_ID_FRAMEWORK; + fwk_mode_cfg_hdr.instance_id = INSTANCE_ID_0; + fwk_mode_cfg_hdr.param_id = LSM_PARAM_ID_FWK_MODE_CONFIG; + fwk_mode_cfg_hdr.param_size = sizeof(fwk_mode_cfg); - fwk_mode_cfg->minor_version = QLSM_PARAM_ID_MINOR_VERSION; - fwk_mode_cfg->mode = event_mode; - pr_debug("%s: mode = %d\n", __func__, fwk_mode_cfg->mode); + fwk_mode_cfg.minor_version = QLSM_PARAM_ID_MINOR_VERSION; + fwk_mode_cfg.mode = event_mode; + pr_debug("%s: mode = %d\n", __func__, fwk_mode_cfg.mode); - rc = q6lsm_apr_send_pkt(client, client->apr, - &cmd, true, NULL); + rc = q6lsm_pack_and_set_params(client, &fwk_mode_cfg_hdr, + (uint8_t *) &fwk_mode_cfg, + LSM_SESSION_CMD_SET_PARAMS_V2); if (rc) - pr_err("%s: Failed set_params opcode 0x%x, rc %d\n", - __func__, msg_hdr->opcode, rc); + pr_err("%s: Failed set_params, rc %d\n", __func__, rc); return rc; } @@ -935,58 +985,38 @@ static int q6lsm_arrange_mch_map(struct lsm_param_media_fmt *media_fmt, int q6lsm_set_media_fmt_params(struct lsm_client *client) { - int rc = 0; - struct lsm_cmd_set_media_fmt cmd; - struct lsm_module_param_ids media_fmt_ids; - struct apr_hdr *msg_hdr; - struct lsm_param_media_fmt *media_fmt; - u32 data_payload_size, param_size, set_param_opcode; + struct lsm_param_media_fmt media_fmt = {0}; struct lsm_hw_params param = client->hw_params; + struct param_hdr_v3 media_fmt_hdr = {0}; + int rc = 0; - if (client->use_topology) { - set_param_opcode = LSM_SESSION_CMD_SET_PARAMS_V2; - media_fmt_ids.module_id = LSM_MODULE_ID_FRAMEWORK; - media_fmt_ids.param_id = LSM_PARAM_ID_MEDIA_FMT; - } else { + if (!client->use_topology) { pr_debug("%s: Ignore sending media format\n", __func__); goto err_ret; } - msg_hdr = &cmd.msg_hdr; - q6lsm_add_hdr(client, msg_hdr, - sizeof(struct lsm_cmd_set_media_fmt), true); - msg_hdr->opcode = set_param_opcode; - data_payload_size = sizeof(struct lsm_cmd_set_media_fmt) - - sizeof(struct apr_hdr) - - sizeof(struct lsm_set_params_hdr); - q6lsm_set_param_hdr_info(&cmd.params_hdr, - data_payload_size, 0, 0, 0); - media_fmt = &cmd.media_fmt; - - param_size = (sizeof(struct lsm_param_media_fmt) - - sizeof(media_fmt->common)); - q6lsm_set_param_common(&media_fmt->common, - &media_fmt_ids, param_size, - set_param_opcode); + media_fmt_hdr.module_id = LSM_MODULE_ID_FRAMEWORK; + media_fmt_hdr.instance_id = INSTANCE_ID_0; + media_fmt_hdr.param_id = LSM_PARAM_ID_MEDIA_FMT; + media_fmt_hdr.param_size = sizeof(media_fmt); - media_fmt->minor_version = QLSM_PARAM_ID_MINOR_VERSION_2; - media_fmt->sample_rate = param.sample_rate; - media_fmt->num_channels = param.num_chs; - media_fmt->bit_width = param.sample_size; - - rc = q6lsm_arrange_mch_map(media_fmt, media_fmt->num_channels); + media_fmt.minor_version = QLSM_PARAM_ID_MINOR_VERSION_2; + media_fmt.sample_rate = param.sample_rate; + media_fmt.num_channels = param.num_chs; + media_fmt.bit_width = param.sample_size; + rc = q6lsm_arrange_mch_map(&media_fmt, media_fmt.num_channels); if (rc) goto err_ret; - pr_debug("%s: sample rate= %d, channels %d bit width %d\n", - __func__, media_fmt->sample_rate, media_fmt->num_channels, - media_fmt->bit_width); + pr_debug("%s: sample rate= %d, channels %d bit width %d\n", __func__, + media_fmt.sample_rate, media_fmt.num_channels, + media_fmt.bit_width); - rc = q6lsm_apr_send_pkt(client, client->apr, - &cmd, true, NULL); + rc = q6lsm_pack_and_set_params(client, &media_fmt_hdr, + (uint8_t *) &media_fmt, + LSM_SESSION_CMD_SET_PARAMS_V2); if (rc) - pr_err("%s: Failed set_params opcode 0x%x, rc %d\n", - __func__, msg_hdr->opcode, rc); + pr_err("%s: Failed set_params, rc %d\n", __func__, rc); err_ret: return rc; } @@ -995,9 +1025,8 @@ int q6lsm_set_data(struct lsm_client *client, enum lsm_detection_mode mode, bool detectfailure) { + struct param_hdr_v3 param_hdr = {0}; int rc = 0; - struct lsm_module_param_ids opmode_ids; - struct lsm_module_param_ids conf_levels_ids; if (!client->confidence_levels) { /* @@ -1021,22 +1050,20 @@ int q6lsm_set_data(struct lsm_client *client, } client->mode |= detectfailure << 2; - opmode_ids.module_id = LSM_MODULE_ID_VOICE_WAKEUP; - opmode_ids.param_id = LSM_PARAM_ID_OPERATION_MODE; - - rc = q6lsm_send_param_opmode(client, &opmode_ids, - LSM_SESSION_CMD_SET_PARAMS); + param_hdr.module_id = LSM_MODULE_ID_VOICE_WAKEUP; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = LSM_PARAM_ID_OPERATION_MODE; + rc = q6lsm_send_param_opmode(client, ¶m_hdr, + LSM_SESSION_CMD_SET_PARAMS); if (rc) { pr_err("%s: Failed to set lsm config params %d\n", __func__, rc); goto err_ret; } - conf_levels_ids.module_id = LSM_MODULE_ID_VOICE_WAKEUP; - conf_levels_ids.param_id = LSM_PARAM_ID_MIN_CONFIDENCE_LEVELS; - - rc = q6lsm_send_confidence_levels(client, &conf_levels_ids, - LSM_SESSION_CMD_SET_PARAMS); + param_hdr.param_id = LSM_PARAM_ID_MIN_CONFIDENCE_LEVELS; + rc = q6lsm_send_confidence_levels(client, ¶m_hdr, + LSM_SESSION_CMD_SET_PARAMS); if (rc) { pr_err("%s: Failed to send conf_levels, err = %d\n", __func__, rc); @@ -1226,9 +1253,7 @@ static int q6lsm_send_cal(struct lsm_client *client, u32 set_params_opcode) { int rc = 0; - struct lsm_cmd_set_params params; - struct lsm_set_params_hdr *params_hdr = ¶ms.param_hdr; - struct apr_hdr *msg_hdr = ¶ms.msg_hdr; + struct mem_mapping_hdr mem_hdr = {0}; struct cal_block_data *cal_block = NULL; pr_debug("%s: Session id %d\n", __func__, client->session); @@ -1258,21 +1283,16 @@ static int q6lsm_send_cal(struct lsm_client *client, } /* Cache mmap address, only map once or if new addr */ lsm_common.common_client[client->session].session = client->session; - q6lsm_add_hdr(client, msg_hdr, sizeof(params), true); - msg_hdr->opcode = set_params_opcode; - q6lsm_set_param_hdr_info(params_hdr, - cal_block->cal_data.size, - lower_32_bits(client->lsm_cal_phy_addr), - msm_audio_populate_upper_32_bits( - client->lsm_cal_phy_addr), - client->sound_model.mem_map_handle); - - pr_debug("%s: Cal Size = %zd", __func__, - cal_block->cal_data.size); - rc = q6lsm_apr_send_pkt(client, client->apr, ¶ms, true, NULL); + mem_hdr.data_payload_addr_lsw = lower_32_bits(client->lsm_cal_phy_addr); + mem_hdr.data_payload_addr_msw = + msm_audio_populate_upper_32_bits(client->lsm_cal_phy_addr); + mem_hdr.mem_map_handle = client->sound_model.mem_map_handle; + + pr_debug("%s: Cal Size = %zd", __func__, cal_block->cal_data.size); + rc = q6lsm_set_params(client, &mem_hdr, NULL, cal_block->cal_data.size, + set_params_opcode); if (rc) - pr_err("%s: Failed set_params opcode 0x%x, rc %d\n", - __func__, msg_hdr->opcode, rc); + pr_err("%s: Failed set_params, rc %d\n", __func__, rc); unlock: mutex_unlock(&lsm_common.cal_data[LSM_CAL_IDX]->lock); done: @@ -1444,7 +1464,7 @@ int q6lsm_snd_model_buf_alloc(struct lsm_client *client, size_t len, * set_param payload as well. */ if (allocate_module_data) - len += sizeof(struct lsm_param_payload_common); + len += sizeof(union param_hdrs); client->sound_model.size = len; pad_zero = (LSM_ALIGN_BOUNDARY - @@ -1539,66 +1559,44 @@ static int q6lsm_cmd(struct lsm_client *client, int opcode, bool wait) return rc; } -static int q6lsm_send_param_epd_thres( - struct lsm_client *client, - void *data, struct lsm_module_param_ids *ids) +static int q6lsm_send_param_epd_thres(struct lsm_client *client, void *data, + struct param_hdr_v3 *param_info) { - struct snd_lsm_ep_det_thres *ep_det_data; - struct lsm_cmd_set_epd_threshold epd_cmd; - struct apr_hdr *msg_hdr = &epd_cmd.msg_hdr; - struct lsm_set_params_hdr *param_hdr = - &epd_cmd.param_hdr; - struct lsm_param_epd_thres *epd_thres = - &epd_cmd.epd_thres; - int rc; + struct snd_lsm_ep_det_thres *ep_det_data = NULL; + struct lsm_param_epd_thres epd_thres = {0}; + int rc = 0; + + param_info->param_size = sizeof(epd_thres); ep_det_data = (struct snd_lsm_ep_det_thres *) data; - q6lsm_add_hdr(client, msg_hdr, - sizeof(epd_cmd), true); - msg_hdr->opcode = LSM_SESSION_CMD_SET_PARAMS_V2; - q6lsm_set_param_hdr_info(param_hdr, - sizeof(*epd_thres), 0, 0, 0); - q6lsm_set_param_common(&epd_thres->common, ids, - sizeof(*epd_thres) - sizeof(epd_thres->common), - LSM_SESSION_CMD_SET_PARAMS_V2); - epd_thres->minor_version = QLSM_PARAM_ID_MINOR_VERSION; - epd_thres->epd_begin = ep_det_data->epd_begin; - epd_thres->epd_end = ep_det_data->epd_end; + epd_thres.minor_version = QLSM_PARAM_ID_MINOR_VERSION; + epd_thres.epd_begin = ep_det_data->epd_begin; + epd_thres.epd_end = ep_det_data->epd_end; - rc = q6lsm_apr_send_pkt(client, client->apr, - &epd_cmd, true, NULL); + rc = q6lsm_pack_and_set_params(client, param_info, + (uint8_t *) &epd_thres, + LSM_SESSION_CMD_SET_PARAMS_V2); if (unlikely(rc)) - pr_err("%s: EPD_THRESHOLD failed, rc %d\n", - __func__, rc); + pr_err("%s: EPD_THRESHOLD failed, rc %d\n", __func__, rc); return rc; } -static int q6lsm_send_param_gain( - struct lsm_client *client, - u16 gain, struct lsm_module_param_ids *ids) +static int q6lsm_send_param_gain(struct lsm_client *client, u16 gain, + struct param_hdr_v3 *param_info) { - struct lsm_cmd_set_gain lsm_cmd_gain; - struct apr_hdr *msg_hdr = &lsm_cmd_gain.msg_hdr; - struct lsm_param_gain *lsm_gain = &lsm_cmd_gain.lsm_gain; - int rc; + struct lsm_param_gain lsm_gain = {0}; + int rc = 0; - q6lsm_add_hdr(client, msg_hdr, - sizeof(lsm_cmd_gain), true); - msg_hdr->opcode = LSM_SESSION_CMD_SET_PARAMS_V2; - q6lsm_set_param_hdr_info(&lsm_cmd_gain.param_hdr, - sizeof(*lsm_gain), 0, 0, 0); - q6lsm_set_param_common(&lsm_gain->common, ids, - sizeof(*lsm_gain) - sizeof(lsm_gain->common), - LSM_SESSION_CMD_SET_PARAMS_V2); - lsm_gain->minor_version = QLSM_PARAM_ID_MINOR_VERSION; - lsm_gain->gain = gain; - lsm_gain->reserved = 0; + param_info->param_size = sizeof(lsm_gain); - rc = q6lsm_apr_send_pkt(client, client->apr, - &lsm_cmd_gain, true, NULL); + lsm_gain.minor_version = QLSM_PARAM_ID_MINOR_VERSION; + lsm_gain.gain = gain; + + rc = q6lsm_pack_and_set_params(client, param_info, + (uint8_t *) &lsm_gain, + LSM_SESSION_CMD_SET_PARAMS_V2); if (unlikely(rc)) - pr_err("%s: LSM_GAIN CMD send failed, rc %d\n", - __func__, rc); + pr_err("%s: LSM_GAIN CMD send failed, rc %d\n", __func__, rc); return rc; } @@ -1606,23 +1604,23 @@ int q6lsm_set_one_param(struct lsm_client *client, struct lsm_params_info *p_info, void *data, uint32_t param_type) { - int rc = 0, pkt_sz; - struct lsm_module_param_ids ids; - u8 *packet; + struct param_hdr_v3 param_info = {0}; + int rc = 0; - memset(&ids, 0, sizeof(ids)); switch (param_type) { case LSM_ENDPOINT_DETECT_THRESHOLD: { - ids.module_id = p_info->module_id; - ids.param_id = p_info->param_id; - rc = q6lsm_send_param_epd_thres(client, data, - &ids); + param_info.module_id = p_info->module_id; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = p_info->param_id; + rc = q6lsm_send_param_epd_thres(client, data, ¶m_info); + if (rc) + pr_err("%s: LSM_ENDPOINT_DETECT_THRESHOLD failed, rc %d\n", + __func__, rc); break; } case LSM_OPERATION_MODE: { struct snd_lsm_detect_mode *det_mode = data; - struct lsm_module_param_ids opmode_ids; if (det_mode->mode == LSM_MODE_KEYWORD_ONLY_DETECTION) { client->mode = 0x01; @@ -1636,11 +1634,12 @@ int q6lsm_set_one_param(struct lsm_client *client, client->mode |= det_mode->detect_failure << 2; - opmode_ids.module_id = p_info->module_id; - opmode_ids.param_id = p_info->param_id; + param_info.module_id = p_info->module_id; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = p_info->param_id; - rc = q6lsm_send_param_opmode(client, &opmode_ids, - LSM_SESSION_CMD_SET_PARAMS_V2); + rc = q6lsm_send_param_opmode(client, ¶m_info, + LSM_SESSION_CMD_SET_PARAMS_V2); if (rc) pr_err("%s: OPERATION_MODE failed, rc %d\n", __func__, rc); @@ -1649,9 +1648,10 @@ int q6lsm_set_one_param(struct lsm_client *client, case LSM_GAIN: { struct snd_lsm_gain *lsm_gain = (struct snd_lsm_gain *) data; - ids.module_id = p_info->module_id; - ids.param_id = p_info->param_id; - rc = q6lsm_send_param_gain(client, lsm_gain->gain, &ids); + param_info.module_id = p_info->module_id; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = p_info->param_id; + rc = q6lsm_send_param_gain(client, lsm_gain->gain, ¶m_info); if (rc) pr_err("%s: LSM_GAIN command failed, rc %d\n", __func__, rc); @@ -1659,10 +1659,11 @@ int q6lsm_set_one_param(struct lsm_client *client, } case LSM_MIN_CONFIDENCE_LEVELS: - ids.module_id = p_info->module_id; - ids.param_id = p_info->param_id; - rc = q6lsm_send_confidence_levels(client, &ids, - LSM_SESSION_CMD_SET_PARAMS_V2); + param_info.module_id = p_info->module_id; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = p_info->param_id; + rc = q6lsm_send_confidence_levels( + client, ¶m_info, LSM_SESSION_CMD_SET_PARAMS_V2); if (rc) pr_err("%s: CONFIDENCE_LEVELS cmd failed, rc %d\n", __func__, rc); @@ -1670,11 +1671,12 @@ int q6lsm_set_one_param(struct lsm_client *client, case LSM_POLLING_ENABLE: { struct snd_lsm_poll_enable *lsm_poll_enable = (struct snd_lsm_poll_enable *) data; - ids.module_id = p_info->module_id; - ids.param_id = p_info->param_id; - rc = q6lsm_send_param_polling_enable(client, - lsm_poll_enable->poll_en, &ids, - LSM_SESSION_CMD_SET_PARAMS_V2); + param_info.module_id = p_info->module_id; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = p_info->param_id; + rc = q6lsm_send_param_polling_enable( + client, lsm_poll_enable->poll_en, ¶m_info, + LSM_SESSION_CMD_SET_PARAMS_V2); if (rc) pr_err("%s: POLLING ENABLE cmd failed, rc %d\n", __func__, rc); @@ -1682,24 +1684,25 @@ int q6lsm_set_one_param(struct lsm_client *client, } case LSM_REG_SND_MODEL: { - struct lsm_cmd_set_params model_param; + struct mem_mapping_hdr mem_hdr = {0}; u32 payload_size; - memset(&model_param, 0, sizeof(model_param)); - q6lsm_add_hdr(client, &model_param.msg_hdr, - sizeof(model_param), true); - model_param.msg_hdr.opcode = LSM_SESSION_CMD_SET_PARAMS_V2; - payload_size = p_info->param_size + - sizeof(struct lsm_param_payload_common); - q6lsm_set_param_hdr_info(&model_param.param_hdr, - payload_size, - lower_32_bits(client->sound_model.phys), - msm_audio_populate_upper_32_bits( - client->sound_model.phys), - client->sound_model.mem_map_handle); - - rc = q6lsm_apr_send_pkt(client, client->apr, - &model_param, true, NULL); + if (q6common_is_instance_id_supported()) + payload_size = p_info->param_size + + sizeof(struct param_hdr_v3); + else + payload_size = p_info->param_size + + sizeof(struct param_hdr_v2); + + mem_hdr.data_payload_addr_lsw = + lower_32_bits(client->sound_model.phys); + mem_hdr.data_payload_addr_msw = + msm_audio_populate_upper_32_bits( + client->sound_model.phys), + mem_hdr.mem_map_handle = client->sound_model.mem_map_handle; + + rc = q6lsm_set_params(client, &mem_hdr, NULL, payload_size, + LSM_SESSION_CMD_SET_PARAMS_V2); if (rc) { pr_err("%s: REG_SND_MODEL failed, rc %d\n", __func__, rc); @@ -1714,69 +1717,33 @@ int q6lsm_set_one_param(struct lsm_client *client, } case LSM_DEREG_SND_MODEL: { - struct lsm_param_payload_common *common; - struct lsm_cmd_set_params *param; - - pkt_sz = sizeof(*param) + sizeof(*common); - packet = kzalloc(pkt_sz, GFP_KERNEL); - if (!packet) { - pr_err("%s: No memory for DEREG_SND_MODEL pkt, size = %d\n", - __func__, pkt_sz); - return -ENOMEM; - } - - param = (struct lsm_cmd_set_params *) packet; - common = (struct lsm_param_payload_common *) - (packet + sizeof(*param)); - q6lsm_add_hdr(client, ¶m->msg_hdr, pkt_sz, true); - param->msg_hdr.opcode = LSM_SESSION_CMD_SET_PARAMS_V2; - q6lsm_set_param_hdr_info(¶m->param_hdr, - sizeof(*common), - 0, 0, 0); - ids.module_id = p_info->module_id; - ids.param_id = p_info->param_id; - q6lsm_set_param_common(common, &ids, 0, - LSM_SESSION_CMD_SET_PARAMS_V2); - rc = q6lsm_apr_send_pkt(client, client->apr, - packet, true, NULL); + param_info.module_id = p_info->module_id; + param_info.instance_id = INSTANCE_ID_0; + param_info.param_id = p_info->param_id; + param_info.param_size = 0; + rc = q6lsm_pack_and_set_params(client, ¶m_info, NULL, + LSM_SESSION_CMD_SET_PARAMS_V2); if (rc) pr_err("%s: DEREG_SND_MODEL failed, rc %d\n", __func__, rc); - kfree(packet); break; } case LSM_CUSTOM_PARAMS: { - struct apr_hdr *hdr; - u8 *custom_data; + u32 param_size = p_info->param_size; - if (p_info->param_size < - sizeof(struct lsm_param_payload_common)) { - pr_err("%s: Invalid param_size %d\n", - __func__, p_info->param_size); + /* Check minimum size, V2 structure is smaller than V3 */ + if (param_size < sizeof(struct param_hdr_v2)) { + pr_err("%s: Invalid param_size %d\n", __func__, + param_size); return -EINVAL; } - pkt_sz = p_info->param_size + sizeof(*hdr); - packet = kzalloc(pkt_sz, GFP_KERNEL); - if (!packet) { - pr_err("%s: no memory for CUSTOM_PARAMS, size = %d\n", - __func__, pkt_sz); - return -ENOMEM; - } - - hdr = (struct apr_hdr *) packet; - custom_data = (u8 *) (packet + sizeof(*hdr)); - q6lsm_add_hdr(client, hdr, pkt_sz, true); - hdr->opcode = LSM_SESSION_CMD_SET_PARAMS_V2; - memcpy(custom_data, data, p_info->param_size); - - rc = q6lsm_apr_send_pkt(client, client->apr, - packet, true, NULL); + rc = q6lsm_set_params(client, NULL, data, param_size, + LSM_SESSION_CMD_SET_PARAMS_V2); if (rc) pr_err("%s: CUSTOM_PARAMS failed, rc %d\n", __func__, rc); - kfree(packet); break; } default: @@ -1805,60 +1772,51 @@ int q6lsm_close(struct lsm_client *client) int q6lsm_lab_control(struct lsm_client *client, u32 enable) { + struct lsm_param_lab_enable lab_enable = {0}; + struct param_hdr_v3 lab_enable_hdr = {0}; + struct lsm_param_lab_config lab_config = {0}; + struct param_hdr_v3 lab_config_hdr = {0}; int rc = 0; - struct lsm_params_lab_enable lab_enable; - struct lsm_params_lab_config lab_config; - struct lsm_module_param_ids lab_ids; - u32 param_size; if (!client) { pr_err("%s: invalid param client %pK\n", __func__, client); return -EINVAL; } + /* enable/disable lab on dsp */ - q6lsm_add_hdr(client, &lab_enable.msg_hdr, sizeof(lab_enable), true); - lab_enable.msg_hdr.opcode = LSM_SESSION_CMD_SET_PARAMS; - q6lsm_set_param_hdr_info(&lab_enable.params_hdr, - sizeof(struct lsm_lab_enable), - 0, 0, 0); - param_size = (sizeof(struct lsm_lab_enable) - - sizeof(struct lsm_param_payload_common)); - lab_ids.module_id = LSM_MODULE_ID_LAB; - lab_ids.param_id = LSM_PARAM_ID_LAB_ENABLE; - q6lsm_set_param_common(&lab_enable.lab_enable.common, - &lab_ids, param_size, - LSM_SESSION_CMD_SET_PARAMS); - lab_enable.lab_enable.enable = (enable) ? 1 : 0; - rc = q6lsm_apr_send_pkt(client, client->apr, &lab_enable, true, NULL); + lab_enable_hdr.module_id = LSM_MODULE_ID_LAB; + lab_enable_hdr.instance_id = INSTANCE_ID_0; + lab_enable_hdr.param_id = LSM_PARAM_ID_LAB_ENABLE; + lab_enable_hdr.param_size = sizeof(lab_enable); + lab_enable.enable = (enable) ? 1 : 0; + rc = q6lsm_pack_and_set_params(client, &lab_enable_hdr, + (uint8_t *) &lab_enable, + LSM_SESSION_CMD_SET_PARAMS); if (rc) { pr_err("%s: Lab enable failed rc %d\n", __func__, rc); return rc; } if (!enable) goto exit; + /* lab session is being enabled set the config values */ - q6lsm_add_hdr(client, &lab_config.msg_hdr, sizeof(lab_config), true); - lab_config.msg_hdr.opcode = LSM_SESSION_CMD_SET_PARAMS; - q6lsm_set_param_hdr_info(&lab_config.params_hdr, - sizeof(struct lsm_lab_config), - 0, 0, 0); - lab_ids.module_id = LSM_MODULE_ID_LAB; - lab_ids.param_id = LSM_PARAM_ID_LAB_CONFIG; - param_size = (sizeof(struct lsm_lab_config) - - sizeof(struct lsm_param_payload_common)); - q6lsm_set_param_common(&lab_config.lab_config.common, - &lab_ids, param_size, - LSM_SESSION_CMD_SET_PARAMS); - lab_config.lab_config.minor_version = 1; - lab_config.lab_config.wake_up_latency_ms = 250; - rc = q6lsm_apr_send_pkt(client, client->apr, &lab_config, true, NULL); + lab_config_hdr.module_id = LSM_MODULE_ID_LAB; + lab_config_hdr.instance_id = INSTANCE_ID_0; + lab_config_hdr.param_id = LSM_PARAM_ID_LAB_CONFIG; + lab_config_hdr.param_size = sizeof(lab_config); + lab_config.minor_version = 1; + lab_config.wake_up_latency_ms = 250; + rc = q6lsm_pack_and_set_params(client, &lab_config_hdr, + (uint8_t *) &lab_config, + LSM_SESSION_CMD_SET_PARAMS); if (rc) { pr_err("%s: Lab config failed rc %d disable lab\n", __func__, rc); /* Lab config failed disable lab */ - lab_enable.lab_enable.enable = 0; - if (q6lsm_apr_send_pkt(client, client->apr, - &lab_enable, true, NULL)) + lab_enable.enable = 0; + if (q6lsm_pack_and_set_params(client, &lab_enable_hdr, + (uint8_t *) &lab_enable, + LSM_SESSION_CMD_SET_PARAMS)) pr_err("%s: Lab disable failed\n", __func__); } exit: @@ -2142,6 +2100,8 @@ static int __init q6lsm_init(void) { int i = 0; pr_debug("%s:\n", __func__); + + memset(&lsm_common, 0, sizeof(struct lsm_common)); spin_lock_init(&lsm_session_lock); spin_lock_init(&mmap_lock); mutex_init(&lsm_common.apr_lock); diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c index 01e31578f107..a0f30a32f8e6 100644 --- a/sound/soc/msm/qdsp6v2/q6voice.c +++ b/sound/soc/msm/qdsp6v2/q6voice.c @@ -24,6 +24,7 @@ #include "sound/q6audio-v2.h" #include "sound/apr_audio-v2.h" #include "sound/q6afe-v2.h" +#include <sound/q6common.h> #include <sound/audio_cal_utils.h> #include "q6voice.h" #include <sound/adsp_err.h> @@ -93,8 +94,9 @@ static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv); static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv); static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv); -static int voice_send_set_pp_enable_cmd(struct voice_data *v, - uint32_t module_id, int enable); +static int voice_send_set_pp_enable_cmd( + struct voice_data *v, struct module_instance_info mod_inst_info, + int enable); static int is_cal_memory_allocated(void); static bool is_cvd_version_queried(void); static int is_voip_memory_allocated(void); @@ -126,6 +128,12 @@ static int voice_send_get_sound_focus_cmd(struct voice_data *v, struct sound_focus_param *soundFocusData); static int voice_send_get_source_tracking_cmd(struct voice_data *v, struct source_tracking_param *sourceTrackingData); +static int voice_pack_and_set_cvp_param(struct voice_data *v, + struct param_hdr_v3 param_hdr, + u8 *param_data); +static int voice_pack_and_set_cvs_ui_property(struct voice_data *v, + struct param_hdr_v3 param_hdr, + u8 *param_data); static void voice_itr_init(struct voice_session_itr *itr, u32 session_id) @@ -1451,70 +1459,29 @@ fail: return ret; } -static int voice_send_set_pp_enable_cmd(struct voice_data *v, - uint32_t module_id, int enable) +static int voice_send_set_pp_enable_cmd( + struct voice_data *v, struct module_instance_info mod_inst_info, + int enable) { - struct cvs_set_pp_enable_cmd cvs_set_pp_cmd; + struct enable_param enable_param = {0}; + struct param_hdr_v3 param_hdr = {0}; int ret = 0; - void *apr_cvs; - u16 cvs_handle; - if (v == NULL) { - pr_err("%s: v is NULL\n", __func__); - return -EINVAL; - } - apr_cvs = common.apr_q6_cvs; + param_hdr.module_id = mod_inst_info.module_id; + param_hdr.instance_id = mod_inst_info.instance_id; + param_hdr.param_id = VOICE_PARAM_MOD_ENABLE; + param_hdr.param_size = sizeof(enable_param); + enable_param.enable = enable ? 1 : 0; - if (!apr_cvs) { - pr_err("%s: apr_cvs is NULL.\n", __func__); - return -EINVAL; - } - cvs_handle = voice_get_cvs_handle(v); + pr_debug("%s: voice_send_set_pp_enable_cmd, module_id=%d, instance_id=%d, enable=%d\n", + __func__, mod_inst_info.module_id, mod_inst_info.instance_id, + enable); - cvs_set_pp_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, - APR_HDR_LEN(APR_HDR_SIZE), - APR_PKT_VER); - cvs_set_pp_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE, - sizeof(cvs_set_pp_cmd) - - APR_HDR_SIZE); - cvs_set_pp_cmd.hdr.src_port = voice_get_idx_for_session(v->session_id); - cvs_set_pp_cmd.hdr.dest_port = cvs_handle; - cvs_set_pp_cmd.hdr.token = 0; - cvs_set_pp_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_UI_PROPERTY; - - cvs_set_pp_cmd.vss_set_pp.module_id = module_id; - cvs_set_pp_cmd.vss_set_pp.param_id = VOICE_PARAM_MOD_ENABLE; - cvs_set_pp_cmd.vss_set_pp.param_size = MOD_ENABLE_PARAM_LEN; - cvs_set_pp_cmd.vss_set_pp.reserved = 0; - cvs_set_pp_cmd.vss_set_pp.enable = enable; - cvs_set_pp_cmd.vss_set_pp.reserved_field = 0; - pr_debug("voice_send_set_pp_enable_cmd, module_id=%d, enable=%d\n", - module_id, enable); + ret = voice_pack_and_set_cvs_ui_property(v, param_hdr, + (uint8_t *) &enable_param); + if (ret < 0) + pr_err("Fail: sending cvs set pp enable\n"); - v->cvs_state = CMD_STATUS_FAIL; - v->async_err = 0; - ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_pp_cmd); - if (ret < 0) { - pr_err("Fail: sending cvs set pp enable,\n"); - goto fail; - } - ret = wait_event_timeout(v->cvs_wait, - (v->cvs_state == CMD_STATUS_SUCCESS), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: wait_event timeout\n", __func__); - goto fail; - } - if (v->async_err > 0) { - pr_err("%s: DSP returned error[%s]\n", - __func__, adsp_err_get_err_str( - v->async_err)); - ret = adsp_err_get_lnx_err_code( - v->async_err); - goto fail; - } - return 0; -fail: return ret; } @@ -3823,6 +3790,7 @@ done: static int voice_setup_vocproc(struct voice_data *v) { + struct module_instance_info mod_inst_info = {0}; int ret = 0; ret = voice_send_cvp_create_cmd(v); @@ -3845,6 +3813,9 @@ static int voice_setup_vocproc(struct voice_data *v) goto fail; } + mod_inst_info.module_id = MODULE_ID_VOICE_MODULE_ST; + mod_inst_info.instance_id = INSTANCE_ID_0; + voice_send_cvs_register_cal_cmd(v); voice_send_cvp_register_dev_cfg_cmd(v); voice_send_cvp_register_cal_cmd(v); @@ -3878,9 +3849,7 @@ static int voice_setup_vocproc(struct voice_data *v) } if (v->st_enable && !v->tty_mode) - voice_send_set_pp_enable_cmd(v, - MODULE_ID_VOICE_MODULE_ST, - v->st_enable); + voice_send_set_pp_enable_cmd(v, mod_inst_info, v->st_enable); /* Start in-call music delivery if this feature is enabled */ if (v->music_info.play_enable) voice_cvs_start_playback(v); @@ -4017,14 +3986,9 @@ done: static int voice_send_cvp_media_format_cmd(struct voice_data *v, uint32_t param_type) { + struct vss_param_endpoint_media_format_info media_fmt_info = {0}; + struct param_hdr_v3 param_hdr = {0}; int ret = 0; - struct cvp_set_media_format_cmd cvp_set_media_format_cmd; - void *apr_cvp; - u16 cvp_handle; - struct vss_icommon_param_data_t *media_fmt_param_data = - &cvp_set_media_format_cmd.cvp_set_param_v2.param_data; - struct vss_param_endpoint_media_format_info_t *media_fmt_info = - &media_fmt_param_data->media_format_info; if (v == NULL) { pr_err("%s: v is NULL\n", __func__); @@ -4032,75 +3996,41 @@ static int voice_send_cvp_media_format_cmd(struct voice_data *v, goto done; } - apr_cvp = common.apr_q6_cvp; - if (!apr_cvp) { - pr_err("%s: apr_cvp is NULL.\n", __func__); - ret = -EINVAL; - goto done; - } - - cvp_handle = voice_get_cvp_handle(v); - memset(&cvp_set_media_format_cmd, 0, sizeof(cvp_set_media_format_cmd)); + param_hdr.module_id = VSS_MODULE_CVD_GENERIC; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_size = sizeof(media_fmt_info); - /* Fill header data */ - cvp_set_media_format_cmd.hdr.hdr_field = - APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), - APR_PKT_VER); - cvp_set_media_format_cmd.hdr.pkt_size = - APR_PKT_SIZE(APR_HDR_SIZE, - sizeof(cvp_set_media_format_cmd) - APR_HDR_SIZE); - cvp_set_media_format_cmd.hdr.src_svc = 0; - cvp_set_media_format_cmd.hdr.src_domain = APR_DOMAIN_APPS; - cvp_set_media_format_cmd.hdr.src_port = - voice_get_idx_for_session(v->session_id); - cvp_set_media_format_cmd.hdr.dest_svc = 0; - cvp_set_media_format_cmd.hdr.dest_domain = APR_DOMAIN_ADSP; - cvp_set_media_format_cmd.hdr.dest_port = cvp_handle; - cvp_set_media_format_cmd.hdr.token = VOC_SET_MEDIA_FORMAT_PARAM_TOKEN; - cvp_set_media_format_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_PARAM_V2; - - /* Fill param data */ - cvp_set_media_format_cmd.cvp_set_param_v2.mem_size = - sizeof(struct vss_icommon_param_data_t); - media_fmt_param_data->module_id = VSS_MODULE_CVD_GENERIC; - media_fmt_param_data->param_size = - sizeof(struct vss_param_endpoint_media_format_info_t); - - /* Fill device specific data */ switch (param_type) { case RX_PATH: - media_fmt_param_data->param_id = - VSS_PARAM_RX_PORT_ENDPOINT_MEDIA_INFO; - media_fmt_info->port_id = v->dev_rx.port_id; - media_fmt_info->num_channels = v->dev_rx.no_of_channels; - media_fmt_info->bits_per_sample = v->dev_rx.bits_per_sample; - media_fmt_info->sample_rate = v->dev_rx.sample_rate; - memcpy(&media_fmt_info->channel_mapping, + param_hdr.param_id = VSS_PARAM_RX_PORT_ENDPOINT_MEDIA_INFO; + media_fmt_info.port_id = v->dev_rx.port_id; + media_fmt_info.num_channels = v->dev_rx.no_of_channels; + media_fmt_info.bits_per_sample = v->dev_rx.bits_per_sample; + media_fmt_info.sample_rate = v->dev_rx.sample_rate; + memcpy(&media_fmt_info.channel_mapping, &v->dev_rx.channel_mapping, VSS_CHANNEL_MAPPING_SIZE); break; case TX_PATH: - media_fmt_param_data->param_id = - VSS_PARAM_TX_PORT_ENDPOINT_MEDIA_INFO; - media_fmt_info->port_id = v->dev_tx.port_id; - media_fmt_info->num_channels = v->dev_tx.no_of_channels; - media_fmt_info->bits_per_sample = v->dev_tx.bits_per_sample; - media_fmt_info->sample_rate = v->dev_tx.sample_rate; - memcpy(&media_fmt_info->channel_mapping, + param_hdr.param_id = VSS_PARAM_TX_PORT_ENDPOINT_MEDIA_INFO; + media_fmt_info.port_id = v->dev_tx.port_id; + media_fmt_info.num_channels = v->dev_tx.no_of_channels; + media_fmt_info.bits_per_sample = v->dev_tx.bits_per_sample; + media_fmt_info.sample_rate = v->dev_tx.sample_rate; + memcpy(&media_fmt_info.channel_mapping, &v->dev_tx.channel_mapping, VSS_CHANNEL_MAPPING_SIZE); break; case EC_REF_PATH: - media_fmt_param_data->param_id = - VSS_PARAM_EC_REF_PORT_ENDPOINT_MEDIA_INFO; - media_fmt_info->port_id = common.ec_media_fmt_info.port_id; - media_fmt_info->num_channels = + param_hdr.param_id = VSS_PARAM_EC_REF_PORT_ENDPOINT_MEDIA_INFO; + media_fmt_info.port_id = common.ec_media_fmt_info.port_id; + media_fmt_info.num_channels = common.ec_media_fmt_info.num_channels; - media_fmt_info->bits_per_sample = + media_fmt_info.bits_per_sample = common.ec_media_fmt_info.bits_per_sample; - media_fmt_info->sample_rate = + media_fmt_info.sample_rate = common.ec_media_fmt_info.sample_rate; - memcpy(&media_fmt_info->channel_mapping, + memcpy(&media_fmt_info.channel_mapping, &common.ec_media_fmt_info.channel_mapping, VSS_CHANNEL_MAPPING_SIZE); break; @@ -4111,32 +4041,11 @@ static int voice_send_cvp_media_format_cmd(struct voice_data *v, goto done; } - /* Send command */ - v->cvp_state = CMD_STATUS_FAIL; - v->async_err = 0; - ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_set_media_format_cmd); - if (ret < 0) { - pr_err("%s: Fail in sending VSS_ICOMMON_CMD_SET_PARAM_V2\n", - __func__); - ret = -EINVAL; - goto done; - } - - ret = wait_event_timeout(v->cvp_wait, - (v->cvp_state == CMD_STATUS_SUCCESS), - msecs_to_jiffies(TIMEOUT_MS)); - if (!ret) { - pr_err("%s: wait_event timeout\n", __func__); - ret = -EINVAL; - goto done; - } - - if (v->async_err > 0) { - pr_err("%s: DSP returned error[%s] handle = %d\n", __func__, - adsp_err_get_err_str(v->async_err), cvp_handle); - ret = adsp_err_get_lnx_err_code(v->async_err); - goto done; - } + ret = voice_pack_and_set_cvp_param(v, param_hdr, + (u8 *) &media_fmt_info); + if (ret) + pr_err("%s: Failed to set media format params on CVP, err %d\n", + __func__, ret); done: return ret; @@ -4532,6 +4441,7 @@ static int voice_destroy_vocproc(struct voice_data *v) { struct mvm_detach_vocproc_cmd mvm_d_vocproc_cmd; struct apr_hdr cvp_destroy_session_cmd; + struct module_instance_info mod_inst_info = {0}; int ret = 0; void *apr_mvm, *apr_cvp; u16 mvm_handle, cvp_handle; @@ -4550,9 +4460,12 @@ static int voice_destroy_vocproc(struct voice_data *v) mvm_handle = voice_get_mvm_handle(v); cvp_handle = voice_get_cvp_handle(v); + mod_inst_info.module_id = MODULE_ID_VOICE_MODULE_ST; + mod_inst_info.instance_id = INSTANCE_ID_0; + /* disable slowtalk if st_enable is set */ if (v->st_enable) - voice_send_set_pp_enable_cmd(v, MODULE_ID_VOICE_MODULE_ST, 0); + voice_send_set_pp_enable_cmd(v, mod_inst_info, 0); /* Disable HD Voice if hd_enable is set */ if (v->hd_enable) @@ -5789,11 +5702,15 @@ uint8_t voc_get_tty_mode(uint32_t session_id) return ret; } -int voc_set_pp_enable(uint32_t session_id, uint32_t module_id, uint32_t enable) +int voc_set_pp_enable(uint32_t session_id, + struct module_instance_info mod_inst_info, + uint32_t enable) { struct voice_data *v = NULL; int ret = 0; struct voice_session_itr itr; + int mid = mod_inst_info.module_id; + int iid = mod_inst_info.instance_id; voice_itr_init(&itr, session_id); while (voice_itr_get_next_session(&itr, &v)) { @@ -5802,15 +5719,15 @@ int voc_set_pp_enable(uint32_t session_id, uint32_t module_id, uint32_t enable) continue; mutex_lock(&v->lock); - if (module_id == MODULE_ID_VOICE_MODULE_ST) + if (mid == MODULE_ID_VOICE_MODULE_ST && + iid == INSTANCE_ID_0) v->st_enable = enable; if (v->voc_state == VOC_RUN) { - if ((module_id == MODULE_ID_VOICE_MODULE_ST) && - (!v->tty_mode)) - ret = voice_send_set_pp_enable_cmd(v, - MODULE_ID_VOICE_MODULE_ST, - enable); + if ((mid == MODULE_ID_VOICE_MODULE_ST) && + iid == INSTANCE_ID_0 && (!v->tty_mode)) + ret = voice_send_set_pp_enable_cmd( + v, mod_inst_info, enable); } mutex_unlock(&v->lock); } else { @@ -5893,7 +5810,8 @@ bool voc_get_afe_sidetone(void) return ret; } -int voc_get_pp_enable(uint32_t session_id, uint32_t module_id) +int voc_get_pp_enable(uint32_t session_id, + struct module_instance_info mod_inst_info) { struct voice_data *v = voice_get_session(session_id); int ret = 0; @@ -5905,7 +5823,8 @@ int voc_get_pp_enable(uint32_t session_id, uint32_t module_id) } mutex_lock(&v->lock); - if (module_id == MODULE_ID_VOICE_MODULE_ST) + if (mod_inst_info.module_id == MODULE_ID_VOICE_MODULE_ST && + mod_inst_info.instance_id == INSTANCE_ID_0) ret = v->st_enable; mutex_unlock(&v->lock); @@ -6180,6 +6099,7 @@ done: int voc_enable_device(uint32_t session_id) { struct voice_data *v = voice_get_session(session_id); + struct module_instance_info mod_inst_info = {0}; int ret = 0; if (v == NULL) { @@ -6197,15 +6117,15 @@ int voc_enable_device(uint32_t session_id) /* Not a critical error, allow voice call to continue */ } + mod_inst_info.module_id = MODULE_ID_VOICE_MODULE_ST; + mod_inst_info.instance_id = INSTANCE_ID_0; + if (v->tty_mode) { /* disable slowtalk */ - voice_send_set_pp_enable_cmd(v, - MODULE_ID_VOICE_MODULE_ST, - 0); + voice_send_set_pp_enable_cmd(v, mod_inst_info, 0); } else { /* restore slowtalk */ - voice_send_set_pp_enable_cmd(v, - MODULE_ID_VOICE_MODULE_ST, + voice_send_set_pp_enable_cmd(v, mod_inst_info, v->st_enable); } @@ -6787,6 +6707,7 @@ static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv) case VSS_ICOMMON_CMD_MAP_MEMORY: case VSS_ICOMMON_CMD_UNMAP_MEMORY: case VSS_ICOMMON_CMD_SET_UI_PROPERTY: + case VSS_ICOMMON_CMD_SET_UI_PROPERTY_V2: case VSS_IPLAYBACK_CMD_START: case VSS_IPLAYBACK_CMD_STOP: case VSS_IRECORD_CMD_START: @@ -6800,12 +6721,14 @@ static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv) wake_up(&v->cvs_wait); break; case VSS_ICOMMON_CMD_SET_PARAM_V2: - pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2\n", + case VSS_ICOMMON_CMD_SET_PARAM_V3: + pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM\n", __func__); rtac_make_voice_callback(RTAC_CVS, ptr, data->payload_size); break; case VSS_ICOMMON_CMD_GET_PARAM_V2: + case VSS_ICOMMON_CMD_GET_PARAM_V3: pr_debug("%s: VSS_ICOMMON_CMD_GET_PARAM_V2\n", __func__); /* Should only come here if there is an APR */ @@ -6938,7 +6861,8 @@ static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv) pr_debug("Recd VSS_ISTREAM_EVT_NOT_READY\n"); } else if (data->opcode == VSS_ISTREAM_EVT_READY) { pr_debug("Recd VSS_ISTREAM_EVT_READY\n"); - } else if (data->opcode == VSS_ICOMMON_RSP_GET_PARAM) { + } else if (data->opcode == VSS_ICOMMON_RSP_GET_PARAM || + VSS_ICOMMON_RSP_GET_PARAM_V3) { pr_debug("%s: VSS_ICOMMON_RSP_GET_PARAM\n", __func__); ptr = data->payload; if (ptr[0] != 0) { @@ -7081,28 +7005,30 @@ static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv) case VSS_IVPCM_EVT_PUSH_BUFFER_V2: break; case VSS_ICOMMON_CMD_SET_PARAM_V2: + case VSS_ICOMMON_CMD_SET_PARAM_V3: switch (data->token) { case VOC_SET_MEDIA_FORMAT_PARAM_TOKEN: - pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2 called by voice_send_cvp_media_format_cmd\n", + pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM called by voice_send_cvp_media_format_cmd\n", __func__); v->cvp_state = CMD_STATUS_SUCCESS; v->async_err = ptr[1]; wake_up(&v->cvp_wait); break; case VOC_RTAC_SET_PARAM_TOKEN: - pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2 called by rtac\n", + pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM called by rtac\n", __func__); rtac_make_voice_callback( RTAC_CVP, ptr, data->payload_size); break; default: - pr_debug("%s: invalid token for command VSS_ICOMMON_CMD_SET_PARAM_V2: %d\n", + pr_debug("%s: invalid token for command VSS_ICOMMON_CMD_SET_PARAM: %d\n", __func__, data->token); break; } break; case VSS_ICOMMON_CMD_GET_PARAM_V2: + case VSS_ICOMMON_CMD_GET_PARAM_V3: pr_debug("%s: VSS_ICOMMON_CMD_GET_PARAM_V2\n", __func__); /* Should only come here if there is an APR */ @@ -7169,7 +7095,8 @@ static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv) break; } } - } else if (data->opcode == VSS_ICOMMON_RSP_GET_PARAM) { + } else if (data->opcode == VSS_ICOMMON_RSP_GET_PARAM || + VSS_ICOMMON_RSP_GET_PARAM_V3) { pr_debug("%s: VSS_ICOMMON_RSP_GET_PARAM\n", __func__); ptr = data->payload; if (ptr[0] != 0) { @@ -8578,6 +8505,199 @@ int voc_get_source_tracking(struct source_tracking_param *sourceTrackingData) return ret; } +static int voice_set_cvp_param(struct voice_data *v, + struct vss_icommon_mem_mapping_hdr *mem_hdr, + u32 *param_data, u32 param_size) +{ + struct vss_icommon_cmd_set_param *set_param = NULL; + uint32_t pkt_size = sizeof(struct vss_icommon_cmd_set_param); + void *apr_cvp; + int ret = 0; + + apr_cvp = common.apr_q6_cvp; + if (!apr_cvp) { + pr_err("%s: apr_cvp is NULL\n", __func__); + return -EINVAL; + } + + if (param_data != NULL) + pkt_size += param_size; + set_param = kzalloc(pkt_size, GFP_KERNEL); + if (!set_param) + return -ENOMEM; + + set_param->apr_hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + set_param->apr_hdr.pkt_size = + APR_PKT_SIZE(APR_HDR_SIZE, pkt_size - APR_HDR_SIZE); + set_param->apr_hdr.src_svc = 0; + set_param->apr_hdr.src_domain = APR_DOMAIN_APPS; + set_param->apr_hdr.src_port = voice_get_idx_for_session(v->session_id); + set_param->apr_hdr.dest_svc = 0; + set_param->apr_hdr.dest_domain = APR_DOMAIN_ADSP; + set_param->apr_hdr.dest_port = voice_get_cvp_handle(v); + set_param->apr_hdr.token = VOC_SET_MEDIA_FORMAT_PARAM_TOKEN; + set_param->apr_hdr.opcode = q6common_is_instance_id_supported() ? + VSS_ICOMMON_CMD_SET_PARAM_V3 : + VSS_ICOMMON_CMD_SET_PARAM_V2; + + set_param->payload_size = param_size; + + if (mem_hdr != NULL) { + set_param->mem_hdr = *mem_hdr; + } else if (param_data != NULL) { + memcpy(set_param->param_data, param_data, param_size); + } else { + pr_err("%s: Both memory header and param data are NULL\n", + __func__); + ret = -EINVAL; + goto done; + } + + v->cvp_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvp, (u32 *) set_param); + if (ret < 0) { + pr_err("%s: Failed to send apr packet, error %d\n", __func__, + ret); + goto done; + } + + ret = wait_event_timeout(v->cvp_wait, + v->cvp_state == CMD_STATUS_SUCCESS, + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -ETIMEDOUT; + goto done; + } + + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", __func__, + adsp_err_get_err_str(v->async_err)); + ret = adsp_err_get_lnx_err_code(v->async_err); + goto done; + } + ret = 0; + +done: + kfree(set_param); + return ret; +} + +static int voice_pack_and_set_cvp_param(struct voice_data *v, + struct param_hdr_v3 param_hdr, + u8 *param_data) +{ + u8 *packed_data = NULL; + u32 total_size = 0; + int ret = 0; + + total_size = sizeof(union param_hdrs) + param_hdr.param_size; + packed_data = kzalloc(total_size, GFP_KERNEL); + if (!packed_data) + return -ENOMEM; + + ret = q6common_pack_pp_params(packed_data, ¶m_hdr, param_data, + &total_size); + if (ret) { + pr_err("%s: Failed to pack params, error %d", __func__, ret); + goto done; + } + + ret = voice_set_cvp_param(v, NULL, (u32 *) packed_data, total_size); + +done: + kfree(packed_data); + return ret; +} + +/* + * Out of band is not supported and there are currently no pre-packed cases, + * so pack and set in the same function. When needed, split up. + */ +static int voice_pack_and_set_cvs_ui_property(struct voice_data *v, + struct param_hdr_v3 param_hdr, + u8 *param_data) +{ + struct vss_icommon_cmd_set_ui_property *set_ui_property = NULL; + u32 total_size = 0; + bool iid_supported = q6common_is_instance_id_supported(); + void *apr_cvs; + int ret = 0; + + apr_cvs = common.apr_q6_cvs; + if (!apr_cvs) { + pr_err("%s: apr_cvs is NULL\n", __func__); + return -EINVAL; + } + + total_size = sizeof(struct vss_icommon_cmd_set_ui_property) + + sizeof(union param_hdrs) + param_hdr.param_size; + set_ui_property = kzalloc(total_size, GFP_KERNEL); + if (!set_ui_property) + return -ENOMEM; + + ret = q6common_pack_pp_params(set_ui_property->param_data, ¶m_hdr, + param_data, &total_size); + if (ret) { + pr_err("%s: Failed to pack params, error %d", __func__, ret); + goto done; + } + + /* + * Pack the APR header after packing the data so we have the actual + * total size of the payload + */ + set_ui_property->apr_hdr.hdr_field = + APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), + APR_PKT_VER); + set_ui_property->apr_hdr.pkt_size = + APR_PKT_SIZE(APR_HDR_SIZE, total_size - APR_HDR_SIZE); + set_ui_property->apr_hdr.src_svc = 0; + set_ui_property->apr_hdr.src_domain = APR_DOMAIN_APPS; + set_ui_property->apr_hdr.src_port = + voice_get_idx_for_session(v->session_id); + set_ui_property->apr_hdr.dest_svc = 0; + set_ui_property->apr_hdr.dest_domain = APR_DOMAIN_ADSP; + set_ui_property->apr_hdr.dest_port = voice_get_cvs_handle(v); + set_ui_property->apr_hdr.token = 0; + + set_ui_property->apr_hdr.opcode = + iid_supported ? VSS_ICOMMON_CMD_SET_UI_PROPERTY_V2 : + VSS_ICOMMON_CMD_SET_UI_PROPERTY; + + v->cvs_state = CMD_STATUS_FAIL; + v->async_err = 0; + ret = apr_send_pkt(apr_cvs, (u32 *) set_ui_property); + if (ret < 0) { + pr_err("%s: Failed to send apr packet, error %d\n", __func__, + ret); + goto done; + } + + ret = wait_event_timeout(v->cvs_wait, + v->cvs_state == CMD_STATUS_SUCCESS, + msecs_to_jiffies(TIMEOUT_MS)); + if (!ret) { + pr_err("%s: wait_event timeout\n", __func__); + ret = -ETIMEDOUT; + goto done; + } + + if (v->async_err > 0) { + pr_err("%s: DSP returned error[%s]\n", __func__, + adsp_err_get_err_str(v->async_err)); + ret = adsp_err_get_lnx_err_code(v->async_err); + goto done; + } + ret = 0; +done: + kfree(set_ui_property); + return ret; +} + int is_voc_initialized(void) { return module_initialized; diff --git a/sound/soc/msm/qdsp6v2/q6voice.h b/sound/soc/msm/qdsp6v2/q6voice.h index f7ea650dfda9..f448e701d564 100644 --- a/sound/soc/msm/qdsp6v2/q6voice.h +++ b/sound/soc/msm/qdsp6v2/q6voice.h @@ -172,6 +172,7 @@ struct mem_map_table { /* Common */ #define VSS_ICOMMON_CMD_SET_UI_PROPERTY 0x00011103 +#define VSS_ICOMMON_CMD_SET_UI_PROPERTY_V2 0x00013248 /* Set a UI property */ #define VSS_ICOMMON_CMD_MAP_MEMORY 0x00011025 #define VSS_ICOMMON_CMD_UNMAP_MEMORY 0x00011026 @@ -213,7 +214,7 @@ struct vss_unmap_memory_cmd { struct vss_icommon_cmd_unmap_memory_t vss_unmap_mem; } __packed; -struct vss_param_endpoint_media_format_info_t { +struct vss_param_endpoint_media_format_info { /* AFE port ID to which this media format corresponds to. */ uint32_t port_id; /* @@ -240,29 +241,7 @@ struct vss_param_endpoint_media_format_info_t { uint8_t channel_mapping[VSS_NUM_CHANNELS_MAX]; } __packed; -struct vss_icommon_param_data_t { - /* Valid ID of the module. */ - uint32_t module_id; - /* Valid ID of the parameter. */ - uint32_t param_id; - /* - * Data size of the structure relating to the param_id/module_id - * combination in uint8_t bytes. - */ - uint16_t param_size; - /* This field must be set to zero. */ - uint16_t reserved; - /* - * Parameter data payload when inband. Should have size param_size. - * Bit size of payload must be a multiple of 4. - */ - union { - struct vss_param_endpoint_media_format_info_t media_format_info; - }; -} __packed; - -/* Payload structure for the VSS_ICOMMON_CMD_SET_PARAM_V2 command. */ -struct vss_icommon_cmd_set_param_v2_t { +struct vss_icommon_mem_mapping_hdr { /* * Pointer to the unique identifier for an address (physical/virtual). * @@ -275,6 +254,7 @@ struct vss_icommon_cmd_set_param_v2_t { * data. */ uint32_t mem_handle; + /* * Location of the parameter data payload. * @@ -282,12 +262,25 @@ struct vss_icommon_cmd_set_param_v2_t { * mem_handle is 0, this field is ignored. */ uint64_t mem_address; - /* Size of the parameter data payload in bytes. */ - uint32_t mem_size; - /* Parameter data payload when the data is inband. */ - struct vss_icommon_param_data_t param_data; + } __packed; +struct vss_icommon_cmd_set_param { + /* APR Header */ + struct apr_hdr apr_hdr; + + /* The memory mapping header to be used when sending outband */ + struct vss_icommon_mem_mapping_hdr mem_hdr; + + /* Size of the parameter data payload in bytes. */ + uint32_t payload_size; + + /* + * Parameter data payload when inband. Should have size param_size. + * Bit size of payload must be a multiple of 4. + */ + uint8_t param_data[0]; +} __packed; /* TO MVM commands */ #define VSS_IMVM_CMD_CREATE_PASSIVE_CONTROL_SESSION 0x000110FF /**< No payload. Wait for APRV2_IBASIC_RSP_RESULT response. */ @@ -638,7 +631,6 @@ struct vss_imemory_cmd_unmap_t { #define MODULE_ID_VOICE_MODULE_ST 0x00010EE3 #define VOICE_PARAM_MOD_ENABLE 0x00010E00 -#define MOD_ENABLE_PARAM_LEN 4 #define VSS_IPLAYBACK_CMD_START 0x000112BD /* Start in-call music delivery on the Tx voice path. */ @@ -907,20 +899,20 @@ struct vss_istream_cmd_register_calibration_data_v2_t { */ } __packed; -struct vss_icommon_cmd_set_ui_property_enable_t { - uint32_t module_id; - /* Unique ID of the module. */ - uint32_t param_id; - /* Unique ID of the parameter. */ - uint16_t param_size; - /* Size of the parameter in bytes: MOD_ENABLE_PARAM_LEN */ - uint16_t reserved; - /* Reserved; set to 0. */ +struct enable_param { uint16_t enable; uint16_t reserved_field; /* Reserved, set to 0. */ }; +struct vss_icommon_cmd_set_ui_property { + /* APR Header */ + struct apr_hdr apr_hdr; + + /* The parameter data to be filled when sent inband */ + u8 param_data[0]; +} __packed; + /* * Event sent by the stream to the client that enables Rx DTMF * detection whenever DTMF is detected in the Rx path. @@ -1029,10 +1021,6 @@ struct cvs_deregister_cal_data_cmd { struct apr_hdr hdr; } __packed; -struct cvs_set_pp_enable_cmd { - struct apr_hdr hdr; - struct vss_icommon_cmd_set_ui_property_enable_t vss_set_pp; -} __packed; struct cvs_start_record_cmd { struct apr_hdr hdr; struct vss_irecord_cmd_start_t rec_mode; @@ -1105,6 +1093,8 @@ struct vss_istream_cmd_set_packet_exchange_mode_t { */ #define VSS_IVOCPROC_CMD_DEREGISTER_DEVICE_CONFIG 0x00011372 +#define CVD_CAL_DATA_FORMAT_MINOR_VERSION_V0 0x00000000 +#define CVD_CAL_DATA_FORMAT_MINOR_VERSION_V1 0x00000001 #define VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA_V2 0x00011373 #define VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA 0x00011276 @@ -1484,11 +1474,6 @@ struct cvp_set_dev_channels_cmd { struct vss_ivocproc_cmd_topology_set_dev_channels_t cvp_set_channels; } __packed; -struct cvp_set_media_format_cmd { - struct apr_hdr hdr; - struct vss_icommon_cmd_set_param_v2_t cvp_set_param_v2; -} __packed; - struct cvp_set_vp3_data_cmd { struct apr_hdr hdr; } __packed; @@ -1836,9 +1821,11 @@ enum { #define VSID_MAX ALL_SESSION_VSID /* called by alsa driver */ -int voc_set_pp_enable(uint32_t session_id, uint32_t module_id, +int voc_set_pp_enable(uint32_t session_id, + struct module_instance_info mod_inst_info, uint32_t enable); -int voc_get_pp_enable(uint32_t session_id, uint32_t module_id); +int voc_get_pp_enable(uint32_t session_id, + struct module_instance_info mod_inst_info); int voc_set_hd_enable(uint32_t session_id, uint32_t enable); uint8_t voc_get_tty_mode(uint32_t session_id); int voc_set_tty_mode(uint32_t session_id, uint8_t tty_mode); diff --git a/sound/soc/msm/qdsp6v2/rtac.c b/sound/soc/msm/qdsp6v2/rtac.c index 77c6dfbbe8c1..5e33fb508455 100644 --- a/sound/soc/msm/qdsp6v2/rtac.c +++ b/sound/soc/msm/qdsp6v2/rtac.c @@ -27,6 +27,7 @@ #include <sound/q6afe-v2.h> #include <sound/q6adm-v2.h> #include <sound/apr_audio-v2.h> +#include <sound/q6common.h> #include "q6voice.h" #include "msm-pcm-routing-v2.h" #include <sound/adsp_err.h> @@ -104,14 +105,10 @@ struct rtac_afe_user_data { uint32_t cmd_size; uint32_t port_id; union { - struct rtac_afe_set { - struct afe_port_cmd_set_param_v2 cmd; - struct afe_port_param_data_v2 data; - } rtac_afe_set; - struct rtac_afe_get { - struct afe_port_cmd_get_param_v2 cmd; - struct afe_port_param_data_v2 data; - } rtac_afe_get; + struct afe_rtac_user_data_set_v2 v2_set; + struct afe_rtac_user_data_set_v3 v3_set; + struct afe_rtac_user_data_get_v2 v2_get; + struct afe_rtac_user_data_get_v3 v3_get; }; } __packed; @@ -800,7 +797,9 @@ int send_adm_apr(void *buf, u32 opcode) goto err; } - if (opcode == ADM_CMD_SET_PP_PARAMS_V5) { + switch (opcode) { + case ADM_CMD_SET_PP_PARAMS_V5: + case ADM_CMD_SET_PP_PARAMS_V6: /* set payload size to in-band payload */ /* set data size to actual out of band payload size */ data_size = payload_size - 4 * sizeof(u32); @@ -818,12 +817,15 @@ int send_adm_apr(void *buf, u32 opcode) buf + 7 * sizeof(u32), data_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); - result = -EINVAL; + result = -EFAULT; goto err; } + /* set payload size in packet */ rtac_adm_buffer[8] = data_size; - } else { + break; + case ADM_CMD_GET_PP_PARAMS_V5: + case ADM_CMD_GET_PP_PARAMS_V6: if (payload_size > MAX_PAYLOAD_SIZE) { pr_err("%s: Invalid payload size = %d\n", __func__, payload_size); @@ -837,9 +839,14 @@ int send_adm_apr(void *buf, u32 opcode) buf + 3 * sizeof(u32), payload_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); - result = -EINVAL; + result = -EFAULT; goto err; } + break; + default: + pr_err("%s: Invalid opcode %d\n", __func__, opcode); + result = -EINVAL; + goto err; } /* Pack header */ @@ -900,33 +907,39 @@ int send_adm_apr(void *buf, u32 opcode) if (opcode == ADM_CMD_GET_PP_PARAMS_V5) { bytes_returned = ((u32 *)rtac_cal[ADM_RTAC_CAL].cal_data. kvaddr)[2] + 3 * sizeof(u32); + } else if (opcode == ADM_CMD_GET_PP_PARAMS_V6) { + bytes_returned = + ((u32 *) rtac_cal[ADM_RTAC_CAL].cal_data.kvaddr)[3] + + 4 * sizeof(u32); + } else { + bytes_returned = data_size; + goto unlock; + } - if (bytes_returned > rtac_cal[ADM_RTAC_CAL]. - map_data.map_size) { - pr_err("%s: Invalid data size = %d\n", - __func__, bytes_returned); - result = -EINVAL; - goto err; - } + if (bytes_returned > rtac_cal[ADM_RTAC_CAL].map_data.map_size) { + pr_err("%s: Invalid data size = %d\n", __func__, + bytes_returned); + result = -EINVAL; + goto err; + } - 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); - result = -EINVAL; - goto err; - } + 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); + result = -EINVAL; + 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); - result = -EINVAL; - goto err; - } - } else { - bytes_returned = data_size; + if (copy_to_user((void __user *) buf, + 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); + result = -EFAULT; + goto err; } + +unlock: mutex_unlock(&rtac_adm_apr_mutex); done: return bytes_returned; @@ -1027,7 +1040,9 @@ int send_rtac_asm_apr(void *buf, u32 opcode) goto err; } - if (opcode == ASM_STREAM_CMD_SET_PP_PARAMS_V2) { + switch (opcode) { + case ASM_STREAM_CMD_SET_PP_PARAMS_V2: + case ASM_STREAM_CMD_SET_PP_PARAMS_V3: /* set payload size to in-band payload */ /* set data size to actual out of band payload size */ data_size = payload_size - 4 * sizeof(u32); @@ -1045,13 +1060,14 @@ int send_rtac_asm_apr(void *buf, u32 opcode) buf + 7 * sizeof(u32), data_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); - result = -EINVAL; + result = -EFAULT; goto err; } /* set payload size in packet */ rtac_asm_buffer[8] = data_size; - - } else { + break; + case ASM_STREAM_CMD_GET_PP_PARAMS_V2: + case ASM_STREAM_CMD_GET_PP_PARAMS_V3: if (payload_size > MAX_PAYLOAD_SIZE) { pr_err("%s: Invalid payload size = %d\n", __func__, payload_size); @@ -1065,9 +1081,15 @@ int send_rtac_asm_apr(void *buf, u32 opcode) buf + 3 * sizeof(u32), payload_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); - result = -EINVAL; + result = -EFAULT; goto err; } + + break; + default: + pr_err("%s: Invalid opcode %d\n", __func__, opcode); + result = -EINVAL; + goto err; } /* Pack header */ @@ -1130,33 +1152,39 @@ int send_rtac_asm_apr(void *buf, u32 opcode) if (opcode == ASM_STREAM_CMD_GET_PP_PARAMS_V2) { bytes_returned = ((u32 *)rtac_cal[ASM_RTAC_CAL].cal_data. kvaddr)[2] + 3 * sizeof(u32); + } else if (opcode == ASM_STREAM_CMD_GET_PP_PARAMS_V3) { + bytes_returned = + ((u32 *) rtac_cal[ASM_RTAC_CAL].cal_data.kvaddr)[3] + + 4 * sizeof(u32); + } else { + bytes_returned = data_size; + goto unlock; + } - if (bytes_returned > rtac_cal[ASM_RTAC_CAL]. - map_data.map_size) { - pr_err("%s: Invalid data size = %d\n", - __func__, bytes_returned); - result = -EINVAL; - goto err; - } + if (bytes_returned > rtac_cal[ASM_RTAC_CAL].map_data.map_size) { + pr_err("%s: Invalid data size = %d\n", __func__, + bytes_returned); + result = -EINVAL; + goto err; + } - 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); - result = -EINVAL; - goto err; - } + 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); + result = -EINVAL; + 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); - result = -EINVAL; - goto err; - } - } else { - bytes_returned = data_size; + if (copy_to_user((void __user *) buf, + 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); + result = -EFAULT; + goto err; } + +unlock: mutex_unlock(&rtac_asm_apr_mutex); done: return bytes_returned; @@ -1213,13 +1241,18 @@ static int fill_afe_apr_hdr(struct apr_hdr *apr_hdr, uint32_t port, return 0; } -static int send_rtac_afe_apr(void *buf, uint32_t opcode) +static int send_rtac_afe_apr(void __user *buf, uint32_t opcode) { int32_t result; uint32_t bytes_returned = 0; + uint32_t payload_size = 0; uint32_t port_index = 0; + uint32_t *afe_cmd = NULL; uint32_t apr_msg_size = 0; struct rtac_afe_user_data user_afe_buf; + struct mem_mapping_hdr *mem_hdr = NULL; + struct param_hdr_v1 *get_resp_v2; + struct param_hdr_v3 *get_resp_v3; pr_debug("%s\n", __func__); @@ -1267,93 +1300,126 @@ static int send_rtac_afe_apr(void *buf, uint32_t opcode) result = -EINVAL; goto err; } - if (opcode == AFE_PORT_CMD_SET_PARAM_V2) { - struct afe_port_cmd_set_param_v2 *afe_set_apr_msg; - /* set data size to actual out of band payload size */ - if (user_afe_buf.rtac_afe_set.cmd.payload_size > - rtac_cal[AFE_RTAC_CAL].map_data.map_size) { - pr_err("%s: Invalid data size = %d\n", - __func__, - user_afe_buf.rtac_afe_set.cmd.payload_size); + afe_cmd = + (u32 *) rtac_afe_buffer + sizeof(struct apr_hdr) / sizeof(u32); + + switch (opcode) { + case AFE_PORT_CMD_SET_PARAM_V2: + apr_msg_size = sizeof(struct afe_port_cmd_set_param_v2); + payload_size = user_afe_buf.v2_set.payload_size; + if (payload_size > rtac_cal[AFE_RTAC_CAL].map_data.map_size) { + pr_err("%s: Invalid payload size = %d\n", __func__, + payload_size); result = -EINVAL; goto err; } - /* Copy buffer to out-of-band payload */ - if (copy_from_user((void *) - rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr, - buf+offsetof(struct rtac_afe_user_data, - rtac_afe_set.data), - user_afe_buf.rtac_afe_set.cmd.payload_size)) { + /* Copy the command to the rtac buffer */ + memcpy(afe_cmd, &user_afe_buf.v2_set, + sizeof(user_afe_buf.v2_set)); + + /* Copy the param data to the out-of-band location */ + if (copy_from_user(rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr, + (void __user *) buf + + offsetof(struct rtac_afe_user_data, + v2_set.param_hdr), + payload_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); + result = -EFAULT; + goto err; + } + break; + case AFE_PORT_CMD_SET_PARAM_V3: + apr_msg_size = sizeof(struct afe_port_cmd_set_param_v3); + payload_size = user_afe_buf.v3_set.payload_size; + if (payload_size > rtac_cal[AFE_RTAC_CAL].map_data.map_size) { + pr_err("%s: Invalid payload size = %d\n", __func__, + payload_size); result = -EINVAL; goto err; } - /* Copy AFE APR Message */ - afe_set_apr_msg = (struct afe_port_cmd_set_param_v2 *) - ((u8 *)rtac_afe_buffer + - sizeof(struct apr_hdr)); - if (copy_from_user((void *) - afe_set_apr_msg, - buf + offsetof(struct rtac_afe_user_data, - rtac_afe_set.cmd) , - sizeof(struct afe_port_cmd_set_param_v2))) { + /* Copy the command to the rtac buffer */ + memcpy(afe_cmd, &user_afe_buf.v3_set, + sizeof(user_afe_buf.v3_set)); + + /* Copy the param data to the out-of-band location */ + if (copy_from_user(rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr, + (void __user *) buf + + offsetof(struct rtac_afe_user_data, + v3_get.param_hdr), + payload_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); - result = -EINVAL; + result = -EFAULT; goto err; } + break; + case AFE_PORT_CMD_GET_PARAM_V2: + apr_msg_size = sizeof(struct afe_port_cmd_get_param_v2); - afe_set_apr_msg->payload_address_lsw = - lower_32_bits(rtac_cal[AFE_RTAC_CAL].cal_data.paddr); - afe_set_apr_msg->payload_address_msw = - msm_audio_populate_upper_32_bits( - rtac_cal[AFE_RTAC_CAL].cal_data.paddr); - afe_set_apr_msg->mem_map_handle = - rtac_cal[AFE_RTAC_CAL].map_data.map_handle; - - apr_msg_size = sizeof(struct apr_hdr) + - sizeof(struct afe_port_cmd_set_param_v2); + if (user_afe_buf.cmd_size > MAX_PAYLOAD_SIZE) { + pr_err("%s: Invalid payload size = %d\n", __func__, + user_afe_buf.cmd_size); + result = -EINVAL; + goto err; + } - } else { - struct afe_port_cmd_get_param_v2 *afe_get_apr_msg; + /* Copy the command and param data in-band */ + if (copy_from_user(afe_cmd, + (void __user *) buf + + offsetof(struct rtac_afe_user_data, + v2_get), + user_afe_buf.cmd_size)) { + pr_err("%s: Could not copy payload from user buffer\n", + __func__); + result = -EFAULT; + goto err; + } + break; + case AFE_PORT_CMD_GET_PARAM_V3: + apr_msg_size = sizeof(struct afe_port_cmd_get_param_v3); if (user_afe_buf.cmd_size > MAX_PAYLOAD_SIZE) { - pr_err("%s: Invalid payload size = %d\n", - __func__, user_afe_buf.cmd_size); + pr_err("%s: Invalid payload size = %d\n", __func__, + user_afe_buf.cmd_size); result = -EINVAL; goto err; } - /* Copy buffer to in-band payload */ - afe_get_apr_msg = (struct afe_port_cmd_get_param_v2 *) - ((u8 *) rtac_afe_buffer + - sizeof(struct apr_hdr)); - if (copy_from_user((void *)afe_get_apr_msg, - buf+offsetof(struct rtac_afe_user_data, - rtac_afe_get.cmd), - sizeof(struct afe_port_cmd_get_param_v2))) { + /* Copy the command and param data in-band */ + if (copy_from_user(afe_cmd, + (void __user *) buf + + offsetof(struct rtac_afe_user_data, + v3_get), + user_afe_buf.cmd_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); - result = -EINVAL; + result = -EFAULT; goto err; } - - afe_get_apr_msg->payload_address_lsw = - lower_32_bits(rtac_cal[AFE_RTAC_CAL].cal_data.paddr); - afe_get_apr_msg->payload_address_msw = - msm_audio_populate_upper_32_bits( - rtac_cal[AFE_RTAC_CAL].cal_data.paddr); - afe_get_apr_msg->mem_map_handle = - rtac_cal[AFE_RTAC_CAL].map_data.map_handle; - afe_get_apr_msg->payload_size -= sizeof(struct apr_hdr); - apr_msg_size = sizeof(struct apr_hdr) + - sizeof(struct afe_port_cmd_get_param_v2); + break; + default: + pr_err("%s: Invalid opcode %d\n", __func__, opcode); + result = -EINVAL; + goto err; } + /* + * The memory header is in the same location in all commands. Therefore, + * it doesn't matter what command the buffer is cast into. + */ + mem_hdr = &((struct afe_port_cmd_set_param_v3 *) rtac_afe_buffer) + ->mem_hdr; + mem_hdr->data_payload_addr_lsw = + lower_32_bits(rtac_cal[AFE_RTAC_CAL].cal_data.paddr); + mem_hdr->data_payload_addr_msw = msm_audio_populate_upper_32_bits( + rtac_cal[AFE_RTAC_CAL].cal_data.paddr); + mem_hdr->mem_map_handle = rtac_cal[AFE_RTAC_CAL].map_data.map_handle; + + /* Fill the APR header at the end so we have the correct message size */ fill_afe_apr_hdr((struct apr_hdr *) rtac_afe_buffer, port_index, opcode, apr_msg_size); @@ -1391,40 +1457,44 @@ static int send_rtac_afe_apr(void *buf, uint32_t opcode) } if (opcode == AFE_PORT_CMD_GET_PARAM_V2) { - struct afe_port_param_data_v2 *get_resp; - get_resp = (struct afe_port_param_data_v2 *) - rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr; - - bytes_returned = get_resp->param_size + - sizeof(struct afe_port_param_data_v2); + get_resp_v2 = (struct param_hdr_v1 *) rtac_cal[AFE_RTAC_CAL] + .cal_data.kvaddr; + bytes_returned = + get_resp_v2->param_size + sizeof(struct param_hdr_v1); + } else if (opcode == AFE_PORT_CMD_GET_PARAM_V3) { + get_resp_v3 = (struct param_hdr_v3 *) rtac_cal[AFE_RTAC_CAL] + .cal_data.kvaddr; + bytes_returned = + get_resp_v3->param_size + sizeof(struct param_hdr_v3); + } else { + bytes_returned = payload_size; + goto unlock; + } - if (bytes_returned > rtac_cal[AFE_RTAC_CAL]. - map_data.map_size) { - pr_err("%s: Invalid data size = %d\n", - __func__, bytes_returned); - result = -EINVAL; - goto err; - } + if (bytes_returned > rtac_cal[AFE_RTAC_CAL].map_data.map_size) { + pr_err("%s: Invalid data size = %d\n", __func__, + bytes_returned); + result = -EINVAL; + goto err; + } - if (bytes_returned > user_afe_buf.buf_size) { - pr_err("%s: user size = 0x%x, returned size = 0x%x\n", - __func__, user_afe_buf.buf_size, - bytes_returned); - result = -EINVAL; - goto err; - } + if (bytes_returned > user_afe_buf.buf_size) { + pr_err("%s: user size = 0x%x, returned size = 0x%x\n", __func__, + user_afe_buf.buf_size, bytes_returned); + result = -EINVAL; + goto err; + } - if (copy_to_user(buf, (void *) - rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr, - bytes_returned)) { - pr_err("%s: Could not copy buffer to user,size = %d\n", - __func__, bytes_returned); - result = -EINVAL; - goto err; - } - } else { - bytes_returned = user_afe_buf.rtac_afe_set.cmd.payload_size; + if (copy_to_user((void __user *) buf, + rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr, + bytes_returned)) { + pr_err("%s: Could not copy buffer to user,size = %d\n", + __func__, bytes_returned); + result = -EFAULT; + goto err; } + +unlock: mutex_unlock(&rtac_afe_apr_mutex); done: return bytes_returned; @@ -1526,7 +1596,9 @@ int send_voice_apr(u32 mode, void *buf, u32 opcode) goto err; } - if (opcode == VSS_ICOMMON_CMD_SET_PARAM_V2) { + switch (opcode) { + case VSS_ICOMMON_CMD_SET_PARAM_V2: + case VSS_ICOMMON_CMD_SET_PARAM_V3: /* set payload size to in-band payload */ /* set data size to actual out of band payload size */ data_size = payload_size - 4 * sizeof(u32); @@ -1544,12 +1616,16 @@ int send_voice_apr(u32 mode, void *buf, u32 opcode) buf + 7 * sizeof(u32), data_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); - result = -EINVAL; + result = -EFAULT; goto err; } /* set payload size in packet */ rtac_voice_buffer[8] = data_size; - } else { + /* set token for set param case */ + voice_params.token = VOC_RTAC_SET_PARAM_TOKEN; + break; + case VSS_ICOMMON_CMD_GET_PARAM_V2: + case VSS_ICOMMON_CMD_GET_PARAM_V3: if (payload_size > MAX_PAYLOAD_SIZE) { pr_err("%s: Invalid payload size = %d\n", __func__, payload_size); @@ -1563,9 +1639,16 @@ int send_voice_apr(u32 mode, void *buf, u32 opcode) buf + 3 * sizeof(u32), payload_size)) { pr_err("%s: Could not copy payload from user buffer\n", __func__); - result = -EINVAL; + result = -EFAULT; goto err; } + /* set token for get param case */ + voice_params.token = 0; + break; + default: + pr_err("%s: Invalid opcode %d\n", __func__, opcode); + result = -EINVAL; + goto err; } /* Pack header */ @@ -1579,18 +1662,14 @@ int send_voice_apr(u32 mode, void *buf, u32 opcode) voice_params.dest_svc = 0; voice_params.dest_domain = APR_DOMAIN_MODEM; voice_params.dest_port = (u16)dest_port; - voice_params.token = (opcode == VSS_ICOMMON_CMD_SET_PARAM_V2) ? - VOC_RTAC_SET_PARAM_TOKEN : - 0; voice_params.opcode = opcode; /* fill for out-of-band */ rtac_voice_buffer[5] = rtac_cal[VOICE_RTAC_CAL].map_data.map_handle; rtac_voice_buffer[6] = lower_32_bits(rtac_cal[VOICE_RTAC_CAL].cal_data.paddr); - rtac_voice_buffer[7] = - msm_audio_populate_upper_32_bits( - rtac_cal[VOICE_RTAC_CAL].cal_data.paddr); + rtac_voice_buffer[7] = msm_audio_populate_upper_32_bits( + rtac_cal[VOICE_RTAC_CAL].cal_data.paddr); memcpy(rtac_voice_buffer, &voice_params, sizeof(voice_params)); atomic_set(&rtac_voice_apr_data[mode].cmd_state, 1); @@ -1629,33 +1708,39 @@ int send_voice_apr(u32 mode, void *buf, u32 opcode) if (opcode == VSS_ICOMMON_CMD_GET_PARAM_V2) { bytes_returned = ((u32 *)rtac_cal[VOICE_RTAC_CAL].cal_data. kvaddr)[2] + 3 * sizeof(u32); + } else if (opcode == VSS_ICOMMON_CMD_GET_PARAM_V3) { + bytes_returned = + ((u32 *) rtac_cal[VOICE_RTAC_CAL].cal_data.kvaddr)[3] + + 4 * sizeof(u32); + } else { + bytes_returned = data_size; + goto unlock; + } - if (bytes_returned > rtac_cal[VOICE_RTAC_CAL]. - map_data.map_size) { - pr_err("%s: Invalid data size = %d\n", - __func__, bytes_returned); - result = -EINVAL; - goto err; - } + if (bytes_returned > rtac_cal[VOICE_RTAC_CAL].map_data.map_size) { + pr_err("%s: Invalid data size = %d\n", __func__, + bytes_returned); + result = -EINVAL; + goto err; + } - 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); - result = -EINVAL; - goto err; - } + 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); + result = -EINVAL; + 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); - result = -EINVAL; - goto err; - } - } else { - bytes_returned = data_size; + if (copy_to_user((void __user *) buf, + 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); + result = -EFAULT; + goto err; } + +unlock: mutex_unlock(&rtac_voice_apr_mutex); done: return bytes_returned; @@ -1675,6 +1760,7 @@ void get_rtac_adm_data(struct rtac_adm *adm_data) static long rtac_ioctl_shared(struct file *f, unsigned int cmd, void *arg) { + u32 opcode; int result = 0; if (!arg) { pr_err("%s: No data sent to driver!\n", __func__); @@ -1713,42 +1799,64 @@ static long rtac_ioctl_shared(struct file *f, } case AUDIO_GET_RTAC_ADM_CAL: - result = send_adm_apr((void *)arg, ADM_CMD_GET_PP_PARAMS_V5); + opcode = q6common_is_instance_id_supported() ? + ADM_CMD_GET_PP_PARAMS_V6 : + ADM_CMD_GET_PP_PARAMS_V5; + result = send_adm_apr((void *) arg, opcode); break; case AUDIO_SET_RTAC_ADM_CAL: - result = send_adm_apr((void *)arg, ADM_CMD_SET_PP_PARAMS_V5); + opcode = q6common_is_instance_id_supported() ? + ADM_CMD_SET_PP_PARAMS_V6 : + ADM_CMD_SET_PP_PARAMS_V5; + result = send_adm_apr((void *) arg, opcode); break; case AUDIO_GET_RTAC_ASM_CAL: - result = send_rtac_asm_apr((void *)arg, - ASM_STREAM_CMD_GET_PP_PARAMS_V2); + opcode = q6common_is_instance_id_supported() ? + ASM_STREAM_CMD_GET_PP_PARAMS_V3 : + ASM_STREAM_CMD_GET_PP_PARAMS_V2; + result = send_rtac_asm_apr((void *) arg, opcode); break; case AUDIO_SET_RTAC_ASM_CAL: - result = send_rtac_asm_apr((void *)arg, - ASM_STREAM_CMD_SET_PP_PARAMS_V2); + opcode = q6common_is_instance_id_supported() ? + ASM_STREAM_CMD_SET_PP_PARAMS_V3 : + ASM_STREAM_CMD_SET_PP_PARAMS_V2; + result = send_rtac_asm_apr((void *) arg, opcode); break; case AUDIO_GET_RTAC_CVS_CAL: - result = send_voice_apr(RTAC_CVS, (void *) arg, - VSS_ICOMMON_CMD_GET_PARAM_V2); + opcode = q6common_is_instance_id_supported() ? + VSS_ICOMMON_CMD_GET_PARAM_V3 : + VSS_ICOMMON_CMD_GET_PARAM_V2; + result = send_voice_apr(RTAC_CVS, (void *) arg, opcode); break; case AUDIO_SET_RTAC_CVS_CAL: - result = send_voice_apr(RTAC_CVS, (void *) arg, - VSS_ICOMMON_CMD_SET_PARAM_V2); + opcode = q6common_is_instance_id_supported() ? + VSS_ICOMMON_CMD_SET_PARAM_V3 : + VSS_ICOMMON_CMD_SET_PARAM_V2; + result = send_voice_apr(RTAC_CVS, (void *) arg, opcode); break; case AUDIO_GET_RTAC_CVP_CAL: - result = send_voice_apr(RTAC_CVP, (void *) arg, - VSS_ICOMMON_CMD_GET_PARAM_V2); + opcode = q6common_is_instance_id_supported() ? + VSS_ICOMMON_CMD_GET_PARAM_V3 : + VSS_ICOMMON_CMD_GET_PARAM_V2; + result = send_voice_apr(RTAC_CVP, (void *) arg, opcode); break; case AUDIO_SET_RTAC_CVP_CAL: - result = send_voice_apr(RTAC_CVP, (void *) arg, - VSS_ICOMMON_CMD_SET_PARAM_V2); + opcode = q6common_is_instance_id_supported() ? + VSS_ICOMMON_CMD_SET_PARAM_V3 : + VSS_ICOMMON_CMD_SET_PARAM_V2; + result = send_voice_apr(RTAC_CVP, (void *) arg, opcode); break; case AUDIO_GET_RTAC_AFE_CAL: - result = send_rtac_afe_apr((void *)arg, - AFE_PORT_CMD_GET_PARAM_V2); + opcode = q6common_is_instance_id_supported() ? + AFE_PORT_CMD_GET_PARAM_V3 : + AFE_PORT_CMD_GET_PARAM_V2; + result = send_rtac_afe_apr((void __user *) arg, opcode); break; case AUDIO_SET_RTAC_AFE_CAL: - result = send_rtac_afe_apr((void *)arg, - AFE_PORT_CMD_SET_PARAM_V2); + opcode = q6common_is_instance_id_supported() ? + AFE_PORT_CMD_SET_PARAM_V3 : + AFE_PORT_CMD_SET_PARAM_V2; + result = send_rtac_afe_apr((void __user *) arg, opcode); break; default: pr_err("%s: Invalid IOCTL, command = %d!\n", |