Skip to content

Commit

Permalink
ASoC: SOF: Add userspace ABI support
Browse files Browse the repository at this point in the history
Add userspace ABI for audio userspace application IO outside of regular
ALSA PCM and kcontrols. This is intended to be used to format
coefficients and data for custom processing components.

Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
Liam Girdwood authored and Mark Brown committed Apr 27, 2019
1 parent 70cd525 commit 4483151
Show file tree
Hide file tree
Showing 8 changed files with 721 additions and 0 deletions.
62 changes: 62 additions & 0 deletions include/uapi/sound/sof/abi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
/*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
*
* Copyright(c) 2018 Intel Corporation. All rights reserved.
*/

/**
* SOF ABI versioning is based on Semantic Versioning where we have a given
* MAJOR.MINOR.PATCH version number. See https://semver.org/
*
* Rules for incrementing or changing version :-
*
* 1) Increment MAJOR version if you make incompatible API changes. MINOR and
* PATCH should be reset to 0.
*
* 2) Increment MINOR version if you add backwards compatible features or
* changes. PATCH should be reset to 0.
*
* 3) Increment PATCH version if you add backwards compatible bug fixes.
*/

#ifndef __INCLUDE_UAPI_SOUND_SOF_ABI_H__
#define __INCLUDE_UAPI_SOUND_SOF_ABI_H__

/* SOF ABI version major, minor and patch numbers */
#define SOF_ABI_MAJOR 3
#define SOF_ABI_MINOR 4
#define SOF_ABI_PATCH 0

/* SOF ABI version number. Format within 32bit word is MMmmmppp */
#define SOF_ABI_MAJOR_SHIFT 24
#define SOF_ABI_MAJOR_MASK 0xff
#define SOF_ABI_MINOR_SHIFT 12
#define SOF_ABI_MINOR_MASK 0xfff
#define SOF_ABI_PATCH_SHIFT 0
#define SOF_ABI_PATCH_MASK 0xfff

#define SOF_ABI_VER(major, minor, patch) \
(((major) << SOF_ABI_MAJOR_SHIFT) | \
((minor) << SOF_ABI_MINOR_SHIFT) | \
((patch) << SOF_ABI_PATCH_SHIFT))

#define SOF_ABI_VERSION_MAJOR(version) \
(((version) >> SOF_ABI_MAJOR_SHIFT) & SOF_ABI_MAJOR_MASK)
#define SOF_ABI_VERSION_MINOR(version) \
(((version) >> SOF_ABI_MINOR_SHIFT) & SOF_ABI_MINOR_MASK)
#define SOF_ABI_VERSION_PATCH(version) \
(((version) >> SOF_ABI_PATCH_SHIFT) & SOF_ABI_PATCH_MASK)

#define SOF_ABI_VERSION_INCOMPATIBLE(sof_ver, client_ver) \
(SOF_ABI_VERSION_MAJOR((sof_ver)) != \
SOF_ABI_VERSION_MAJOR((client_ver)) \
)

#define SOF_ABI_VERSION SOF_ABI_VER(SOF_ABI_MAJOR, SOF_ABI_MINOR, SOF_ABI_PATCH)

/* SOF ABI magic number "SOF\0". */
#define SOF_ABI_MAGIC 0x00464F53

#endif
172 changes: 172 additions & 0 deletions include/uapi/sound/sof/eq.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
/*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
*
* Copyright(c) 2018 Intel Corporation. All rights reserved.
*/

#ifndef __INCLUDE_UAPI_SOUND_SOF_USER_EQ_H__
#define __INCLUDE_UAPI_SOUND_SOF_USER_EQ_H__

/* FIR EQ type */

#define SOF_EQ_FIR_IDX_SWITCH 0

#define SOF_EQ_FIR_MAX_SIZE 4096 /* Max size allowed for coef data in bytes */

#define SOF_EQ_FIR_MAX_LENGTH 192 /* Max length for individual filter */

#define SOF_EQ_FIR_MAX_RESPONSES 8 /* A blob can define max 8 FIR EQs */

/*
* eq_fir_configuration data structure contains this information
* uint32_t size
* This is the number of bytes need to store the received EQ
* configuration.
* uint16_t channels_in_config
* This describes the number of channels in this EQ config data. It
* can be different from PLATFORM_MAX_CHANNELS.
* uint16_t number_of_responses
* 0=no responses, 1=one response defined, 2=two responses defined, etc.
* int16_t data[]
* assign_response[channels_in_config]
* 0 = use first response, 1 = use 2nd response, etc.
* E.g. {0, 0, 0, 0, 1, 1, 1, 1} would apply to channels 0-3 the
* same first defined response and for to channels 4-7 the second.
* coef_data[]
* Repeated data
* { filter_length, output_shift, h[] }
* for every EQ response defined where vector h has filter_length
* number of coefficients. Coefficients in h[] are in Q1.15 format.
* E.g. 16384 (Q1.15) = 0.5. The shifts are number of right shifts.
*
* NOTE: The channels_in_config must be even to have coef_data aligned to
* 32 bit word in RAM. Therefore a mono EQ assign must be duplicated to 2ch
* even if it would never used. Similarly a 5ch EQ assign must be increased
* to 6ch. EQ init will return an error if this is not met.
*
* NOTE: The filter_length must be multiple of four. Therefore the filter must
* be padded from the end with zeros have this condition met.
*/

struct sof_eq_fir_config {
uint32_t size;
uint16_t channels_in_config;
uint16_t number_of_responses;

/* reserved */
uint32_t reserved[4];

int16_t data[];
} __packed;

struct sof_eq_fir_coef_data {
int16_t length; /* Number of FIR taps */
int16_t out_shift; /* Amount of right shifts at output */

/* reserved */
uint32_t reserved[4];

int16_t coef[]; /* FIR coefficients */
} __packed;

/* In the struct above there's two 16 bit words (length, shift) and four
* reserved 32 bit words before the actual FIR coefficients. This information
* is used in parsing of the configuration blob.
*/
#define SOF_EQ_FIR_COEF_NHEADER \
(sizeof(struct sof_eq_fir_coef_data) / sizeof(int16_t))

/* IIR EQ type */

#define SOF_EQ_IIR_IDX_SWITCH 0

#define SOF_EQ_IIR_MAX_SIZE 1024 /* Max size allowed for coef data in bytes */

#define SOF_EQ_IIR_MAX_RESPONSES 8 /* A blob can define max 8 IIR EQs */

/* eq_iir_configuration
* uint32_t channels_in_config
* This describes the number of channels in this EQ config data. It
* can be different from PLATFORM_MAX_CHANNELS.
* uint32_t number_of_responses_defined
* 0=no responses, 1=one response defined, 2=two responses defined, etc.
* int32_t data[]
* Data consist of two parts. First is the response assign vector that
* has length of channels_in_config. The latter part is coefficient
* data.
* uint32_t assign_response[channels_in_config]
* -1 = not defined, 0 = use first response, 1 = use 2nd, etc.
* E.g. {0, 0, 0, 0, -1, -1, -1, -1} would apply to channels 0-3 the
* same first defined response and leave channels 4-7 unequalized.
* coefficient_data[]
* <1st EQ>
* uint32_t num_biquads
* uint32_t num_biquads_in_series
* <1st biquad>
* int32_t coef_a2 Q2.30 format
* int32_t coef_a1 Q2.30 format
* int32_t coef_b2 Q2.30 format
* int32_t coef_b1 Q2.30 format
* int32_t coef_b0 Q2.30 format
* int32_t output_shift number of shifts right, shift left is negative
* int32_t output_gain Q2.14 format
* <2nd biquad>
* ...
* <2nd EQ>
*
* Note: A flat response biquad can be made with a section set to
* b0 = 1.0, gain = 1.0, and other parameters set to 0
* {0, 0, 0, 0, 1073741824, 0, 16484}
*/

struct sof_eq_iir_config {
uint32_t size;
uint32_t channels_in_config;
uint32_t number_of_responses;

/* reserved */
uint32_t reserved[4];

int32_t data[]; /* eq_assign[channels], eq 0, eq 1, ... */
} __packed;

struct sof_eq_iir_header_df2t {
uint32_t num_sections;
uint32_t num_sections_in_series;

/* reserved */
uint32_t reserved[4];

int32_t biquads[]; /* Repeated biquad coefficients */
} __packed;

struct sof_eq_iir_biquad_df2t {
int32_t a2; /* Q2.30 */
int32_t a1; /* Q2.30 */
int32_t b2; /* Q2.30 */
int32_t b1; /* Q2.30 */
int32_t b0; /* Q2.30 */
int32_t output_shift; /* Number of right shifts */
int32_t output_gain; /* Q2.14 */
} __packed;

/* A full 22th order equalizer with 11 biquads cover octave bands 1-11 in
* in the 0 - 20 kHz bandwidth.
*/
#define SOF_EQ_IIR_DF2T_BIQUADS_MAX 11

/* The number of int32_t words in sof_eq_iir_header_df2t:
* num_sections, num_sections_in_series, reserved[4]
*/
#define SOF_EQ_IIR_NHEADER_DF2T \
(sizeof(struct sof_eq_iir_header_df2t) / sizeof(int32_t))

/* The number of int32_t words in sof_eq_iir_biquad_df2t:
* a2, a1, b2, b1, b0, output_shift, output_gain
*/
#define SOF_EQ_IIR_NBIQUAD_DF2T \
(sizeof(struct sof_eq_iir_biquad_df2t) / sizeof(int32_t))

#endif
78 changes: 78 additions & 0 deletions include/uapi/sound/sof/fw.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
/*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
*
* Copyright(c) 2018 Intel Corporation. All rights reserved.
*/

/*
* Firmware file format .
*/

#ifndef __INCLUDE_UAPI_SOF_FW_H__
#define __INCLUDE_UAPI_SOF_FW_H__

#define SND_SOF_FW_SIG_SIZE 4
#define SND_SOF_FW_ABI 1
#define SND_SOF_FW_SIG "Reef"

/*
* Firmware module is made up of 1 . N blocks of different types. The
* Block header is used to determine where and how block is to be copied in the
* DSP/host memory space.
*/
enum snd_sof_fw_blk_type {
SOF_FW_BLK_TYPE_INVALID = -1,
SOF_FW_BLK_TYPE_START = 0,
SOF_FW_BLK_TYPE_RSRVD0 = SOF_FW_BLK_TYPE_START,
SOF_FW_BLK_TYPE_IRAM = 1, /* local instruction RAM */
SOF_FW_BLK_TYPE_DRAM = 2, /* local data RAM */
SOF_FW_BLK_TYPE_SRAM = 3, /* system RAM */
SOF_FW_BLK_TYPE_ROM = 4,
SOF_FW_BLK_TYPE_IMR = 5,
SOF_FW_BLK_TYPE_RSRVD6 = 6,
SOF_FW_BLK_TYPE_RSRVD7 = 7,
SOF_FW_BLK_TYPE_RSRVD8 = 8,
SOF_FW_BLK_TYPE_RSRVD9 = 9,
SOF_FW_BLK_TYPE_RSRVD10 = 10,
SOF_FW_BLK_TYPE_RSRVD11 = 11,
SOF_FW_BLK_TYPE_RSRVD12 = 12,
SOF_FW_BLK_TYPE_RSRVD13 = 13,
SOF_FW_BLK_TYPE_RSRVD14 = 14,
/* use SOF_FW_BLK_TYPE_RSVRDX for new block types */
SOF_FW_BLK_TYPE_NUM
};

struct snd_sof_blk_hdr {
enum snd_sof_fw_blk_type type;
uint32_t size; /* bytes minus this header */
uint32_t offset; /* offset from base */
} __packed;

/*
* Firmware file is made up of 1 .. N different modules types. The module
* type is used to determine how to load and parse the module.
*/
enum snd_sof_fw_mod_type {
SOF_FW_BASE = 0, /* base firmware image */
SOF_FW_MODULE = 1, /* firmware module */
};

struct snd_sof_mod_hdr {
enum snd_sof_fw_mod_type type;
uint32_t size; /* bytes minus this header */
uint32_t num_blocks; /* number of blocks */
} __packed;

/*
* Firmware file header.
*/
struct snd_sof_fw_header {
unsigned char sig[SND_SOF_FW_SIG_SIZE]; /* "Reef" */
uint32_t file_size; /* size of file minus this header */
uint32_t num_modules; /* number of modules */
uint32_t abi; /* version of header format */
} __packed;

#endif
27 changes: 27 additions & 0 deletions include/uapi/sound/sof/header.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
/*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
*
* Copyright(c) 2018 Intel Corporation. All rights reserved.
*/

#ifndef __INCLUDE_UAPI_SOUND_SOF_USER_HEADER_H__
#define __INCLUDE_UAPI_SOUND_SOF_USER_HEADER_H__

/*
* Header for all non IPC ABI data.
*
* Identifies data type, size and ABI.
* Used by any bespoke component data structures or binary blobs.
*/
struct sof_abi_hdr {
uint32_t magic; /**< 'S', 'O', 'F', '\0' */
uint32_t type; /**< component specific type */
uint32_t size; /**< size in bytes of data excl. this struct */
uint32_t abi; /**< SOF ABI version */
uint32_t reserved[4]; /**< reserved for future use */
uint32_t data[0]; /**< Component data - opaque to core */
} __packed;

#endif
Loading

0 comments on commit 4483151

Please sign in to comment.