diff --git a/dsp/q6common.c b/dsp/q6common.c index 014ab4ce4d..7a186dc566 100644 --- a/dsp/q6common.c +++ b/dsp/q6common.c @@ -41,3 +41,73 @@ bool q6common_is_instance_id_supported(void) return common.instance_id_supported; } EXPORT_SYMBOL(q6common_is_instance_id_supported); + +/** + * q6common_pack_pp_params + * + * Populate params header based on instance ID support and pack + * it with payload. + * Instance ID support - + * yes - param_hdr_v3 + payload + * no - param_hdr_v1 + payload + * + * @dest: destination data pointer to be packed into + * @v3_hdr: param header v3 + * @param_data: param payload + * @total_size: total size of packed data (hdr + payload) + * + * Returns 0 on success or error on failure + */ +int q6common_pack_pp_params(u8 *dest, struct param_hdr_v3 *v3_hdr, + u8 *param_data, u32 *total_size) +{ + struct param_hdr_v1 *v1_hdr = NULL; + u32 packed_size = 0; + u32 param_size = 0; + bool iid_supported = q6common_is_instance_id_supported(); + + if (dest == NULL) { + pr_err("%s: Received NULL pointer for destination\n", __func__); + return -EINVAL; + } else if (v3_hdr == NULL) { + pr_err("%s: Received NULL pointer for header\n", __func__); + return -EINVAL; + } else if (total_size == NULL) { + pr_err("%s: Received NULL pointer for total size\n", __func__); + return -EINVAL; + } + + param_size = v3_hdr->param_size; + packed_size = iid_supported ? sizeof(struct param_hdr_v3) : + sizeof(struct param_hdr_v1); + + if (iid_supported) { + memcpy(dest, v3_hdr, packed_size); + } else { + v1_hdr = (struct param_hdr_v1 *) dest; + v1_hdr->module_id = v3_hdr->module_id; + v1_hdr->param_id = v3_hdr->param_id; + + if (param_size > U16_MAX) { + pr_err("%s: Invalid param size for V1 %d\n", __func__, + param_size); + return -EINVAL; + } + v1_hdr->param_size = param_size; + v1_hdr->reserved = 0; + } + + /* + * Make param_data optional for cases when there is no data + * present as in some set cases and all get cases. + */ + if (param_data != NULL) { + memcpy(dest + packed_size, param_data, param_size); + packed_size += param_size; + } + + *total_size = packed_size; + + return 0; +} +EXPORT_SYMBOL(q6common_pack_pp_params); diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h index 4cef82ef06..3c2f86ffbe 100644 --- a/include/dsp/apr_audio-v2.h +++ b/include/dsp/apr_audio-v2.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-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 @@ -29,6 +29,107 @@ struct param_outband { phys_addr_t paddr; }; +/* Common structures and definitions used for instance ID support */ +/* Instance ID definitions */ +#define INSTANCE_ID_0 0x0000 + +struct mem_mapping_hdr { + /* + * LSW of parameter data payload address. Supported values: any. + * - Must be set to zero for in-band data. + */ + u32 data_payload_addr_lsw; + + /* + * 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. + */ + u32 data_payload_addr_msw; + + /* + * Memory map handle returned by DSP through + * ASM_CMD_SHARED_MEM_MAP_REGIONS command. + * Supported Values: Any. + * If memory map handle is NULL, the parameter data payloads are + * within the message payload (in-band). + * If memory map handle is non-NULL, the parameter data payloads begin + * at the address specified in the address MSW and LSW (out-of-band). + */ + u32 mem_map_handle; + +} __packed; + +/* + * Payload format for parameter data. + * Immediately following these structures are param_size bytes of parameter + * data. + */ +struct param_hdr_v1 { + /* Valid ID of the module. */ + uint32_t module_id; + + /* Valid ID of the parameter. */ + uint32_t param_id; + + /* The size of the parameter specified by the module/param ID combo */ + uint16_t param_size; + + /* This field must be set to zero. */ + uint16_t reserved; +} __packed; + +struct param_hdr_v2 { + /* Valid ID of the module. */ + uint32_t module_id; + + /* Valid ID of the parameter. */ + uint32_t param_id; + + /* The size of the parameter specified by the module/param ID combo */ + uint32_t param_size; +} __packed; + +struct param_hdr_v3 { + /* Valid ID of the module. */ + uint32_t module_id; + + /* Instance of the module. */ + uint16_t instance_id; + + /* This field must be set to zero. */ + uint16_t reserved; + + /* Valid ID of the parameter. */ + uint32_t param_id; + + /* The size of the parameter specified by the module/param ID combo */ + uint32_t param_size; +} __packed; + +/* A union of all param_hdr versions for versitility and max size */ +union param_hdrs { + struct param_hdr_v1 v1; + struct param_hdr_v2 v2; + struct param_hdr_v3 v3; +}; + +struct module_instance_info { + /* Module ID. */ + u32 module_id; + + /* Instance of the module */ + u16 instance_id; + + /* Reserved. This field must be set to zero. */ + u16 reserved; +} __packed; + +/* Begin service specific definitions and structures */ + #define ADSP_ADM_VERSION 0x00070000 #define ADM_CMD_SHARED_MEM_MAP_REGIONS 0x00010322 diff --git a/include/dsp/q6common.h b/include/dsp/q6common.h index 587a6b645d..552f97632d 100644 --- a/include/dsp/q6common.h +++ b/include/dsp/q6common.h @@ -13,9 +13,11 @@ #ifndef __Q6COMMON_H__ #define __Q6COMMON_H__ -#include +#include void q6common_update_instance_id_support(bool supported); bool q6common_is_instance_id_supported(void); +int q6common_pack_pp_params(u8 *dest, struct param_hdr_v3 *v3_hdr, + u8 *param_data, u32 *total_size); #endif /* __Q6COMMON_H__ */