drivers: dai: add dai driver subdir and ssp driver
Add Intel ssp driver using dai interface. Signed-off-by: Jaska Uimonen <jaska.uimonen@linux.intel.com>
This commit is contained in:
parent
fa1eb1d774
commit
8d38b64fdc
12 changed files with 2812 additions and 1 deletions
|
@ -240,6 +240,9 @@
|
|||
/drivers/crypto/*nrf_ecb* @maciekfabia @anangl
|
||||
/drivers/display/display_framebuf.c @dcpleung
|
||||
/drivers/dac/ @martinjaeger
|
||||
/drivers/dai/ @juimonen
|
||||
/drivers/dai/intel/ @juimonen
|
||||
/drivers/dai/intel/ssp/ @juimonen
|
||||
/drivers/dma/*dw* @tbursztyka
|
||||
/drivers/dma/*sam0* @Sizurka
|
||||
/drivers/dma/dma_stm32* @cybertale @lowlander
|
||||
|
|
|
@ -48,7 +48,7 @@ add_subdirectory_ifdef(CONFIG_MEMC memc)
|
|||
add_subdirectory_ifdef(CONFIG_VIRTUALIZATION virtualization)
|
||||
add_subdirectory_ifdef(CONFIG_PM_CPU_OPS pm_cpu_ops)
|
||||
add_subdirectory_ifdef(CONFIG_POWER_DOMAIN power_domain)
|
||||
|
||||
add_subdirectory_ifdef(CONFIG_DAI dai)
|
||||
add_subdirectory_ifdef(CONFIG_FLASH_HAS_DRIVER_ENABLED flash)
|
||||
add_subdirectory_ifdef(CONFIG_SERIAL_HAS_DRIVER serial)
|
||||
add_subdirectory_ifdef(CONFIG_BT_DRIVERS bluetooth)
|
||||
|
|
|
@ -43,6 +43,8 @@ source "drivers/i2c/Kconfig"
|
|||
|
||||
source "drivers/i2s/Kconfig"
|
||||
|
||||
source "drivers/dai/Kconfig"
|
||||
|
||||
source "drivers/pwm/Kconfig"
|
||||
|
||||
source "drivers/pinmux/Kconfig"
|
||||
|
|
3
drivers/dai/CMakeLists.txt
Normal file
3
drivers/dai/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
add_subdirectory_ifdef(CONFIG_DAI_INTEL_SSP intel/ssp)
|
30
drivers/dai/Kconfig
Normal file
30
drivers/dai/Kconfig
Normal file
|
@ -0,0 +1,30 @@
|
|||
# Dai driver configuration options
|
||||
|
||||
# Copyright (c) 2022 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#
|
||||
# DAI Drivers
|
||||
#
|
||||
menuconfig DAI
|
||||
bool "DAI drivers"
|
||||
help
|
||||
Enable support for the DAI interface drivers.
|
||||
|
||||
if DAI
|
||||
|
||||
config DAI_INIT_PRIORITY
|
||||
int "Init priority"
|
||||
default 70
|
||||
help
|
||||
Device driver initialization priority.
|
||||
|
||||
module = DAI
|
||||
module-str = dai
|
||||
source "subsys/logging/Kconfig.template.log_config"
|
||||
|
||||
comment "Device Drivers"
|
||||
|
||||
source "drivers/dai/intel/ssp/Kconfig.ssp"
|
||||
|
||||
endif # DAI
|
5
drivers/dai/intel/ssp/CMakeLists.txt
Normal file
5
drivers/dai/intel/ssp/CMakeLists.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
zephyr_library()
|
||||
zephyr_library_sources_ifdef(CONFIG_DAI_INTEL_SSP ssp.c)
|
||||
zephyr_library_compile_options(-std=gnu99)
|
11
drivers/dai/intel/ssp/Kconfig.ssp
Normal file
11
drivers/dai/intel/ssp/Kconfig.ssp
Normal file
|
@ -0,0 +1,11 @@
|
|||
# SOF SSP configuration options
|
||||
|
||||
# Copyright (c) 2022 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
config DAI_INTEL_SSP
|
||||
bool "Intel I2S (SSP) Bus Driver for Dai interface"
|
||||
select DMA
|
||||
help
|
||||
Enable Inter Sound (I2S) bus driver based on
|
||||
Synchronous Serial Port (SSP) module.
|
132
drivers/dai/intel/ssp/dai-params-intel-ipc3.h
Normal file
132
drivers/dai/intel/ssp/dai-params-intel-ipc3.h
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright (c) 2022 Intel Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __DAI_PARAMS_INTEL_IPC3_H__
|
||||
#define __DAI_PARAMS_INTEL_IPC3_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define DAI_INTEL_IPC3_SSP_FMT_I2S 1 /**< I2S mode */
|
||||
#define DAI_INTEL_IPC3_SSP_FMT_RIGHT_J 2 /**< Right Justified mode */
|
||||
#define DAI_INTEL_IPC3_SSP_FMT_LEFT_J 3 /**< Left Justified mode */
|
||||
#define DAI_INTEL_IPC3_SSP_FMT_DSP_A 4 /**< L data MSB after FRM LRC */
|
||||
#define DAI_INTEL_IPC3_SSP_FMT_DSP_B 5 /**< L data MSB during FRM LRC */
|
||||
#define DAI_INTEL_IPC3_SSP_FMT_PDM 6 /**< Pulse density modulation */
|
||||
|
||||
#define DAI_INTEL_IPC3_SSP_FMT_CONT (1 << 4) /**< continuous clock */
|
||||
#define DAI_INTEL_IPC3_SSP_FMT_GATED (0 << 4) /**< clock is gated */
|
||||
|
||||
#define DAI_INTEL_IPC3_SSP_FMT_NB_NF (0 << 8) /**< normal bit clock + frame */
|
||||
#define DAI_INTEL_IPC3_SSP_FMT_NB_IF (2 << 8) /**< normal BCLK + inv FRM */
|
||||
#define DAI_INTEL_IPC3_SSP_FMT_IB_NF (3 << 8) /**< invert BCLK + nor FRM */
|
||||
#define DAI_INTEL_IPC3_SSP_FMT_IB_IF (4 << 8) /**< invert BCLK + FRM */
|
||||
|
||||
#define DAI_INTEL_IPC3_SSP_FMT_CBP_CFP (0 << 12) /**< codec bclk provider & frame provider */
|
||||
#define DAI_INTEL_IPC3_SSP_FMT_CBC_CFP (2 << 12) /**< codec bclk consumer & frame provider */
|
||||
#define DAI_INTEL_IPC3_SSP_FMT_CBP_CFC (3 << 12) /**< codec bclk provider & frame consumer */
|
||||
#define DAI_INTEL_IPC3_SSP_FMT_CBC_CFC (4 << 12) /**< codec bclk consumer & frame consumer */
|
||||
|
||||
#define DAI_INTEL_IPC3_SSP_FMT_FORMAT_MASK 0x000f
|
||||
#define DAI_INTEL_IPC3_SSP_FMT_CLOCK_MASK 0x00f0
|
||||
#define DAI_INTEL_IPC3_SSP_FMT_INV_MASK 0x0f00
|
||||
#define DAI_INTEL_IPC3_SSP_FMT_CLOCK_PROVIDER_MASK 0xf000
|
||||
|
||||
/*
|
||||
* DAI_CONFIG flags. The 4 LSB bits are used for the commands, HW_PARAMS, HW_FREE and PAUSE
|
||||
* representing when the IPC is sent. The 4 MSB bits are used to add quirks along with the above
|
||||
* commands.
|
||||
*/
|
||||
#define DAI_INTEL_IPC3_SSP_CONFIG_FLAGS_CMD_MASK 0xF
|
||||
#define DAI_INTEL_IPC3_SSP_CONFIG_FLAGS_NONE 0 /**< config without stage information */
|
||||
#define DAI_INTEL_IPC3_SSP_CONFIG_FLAGS_HW_PARAMS BIT(0) /**< config during hw_params stage */
|
||||
#define DAI_INTEL_IPC3_SSP_CONFIG_FLAGS_HW_FREE BIT(1) /**< config during hw_free stage */
|
||||
|
||||
/**< DAI_CONFIG sent during pause trigger. Only available ABI 3.20 onwards */
|
||||
#define DAI_INTEL_IPC3_SSP_CONFIG_FLAGS_PAUSE BIT(2)
|
||||
#define DAI_INTEL_IPC3_SSP_CONFIG_FLAGS_QUIRK_SHIFT 4
|
||||
#define DAI_INTEL_IPC3_SSP_CONFIG_FLAGS_QUIRK_MASK (0xF << SOF_DAI_CONFIG_FLAGS_QUIRK_SHIFT)
|
||||
/*
|
||||
* This should be used along with the DAI_INTEL_IPC3_SSP_CONFIG_FLAGS_HW_PARAMS to indicate that
|
||||
* pipeline stop/pause and DAI DMA stop/pause should happen in two steps. This change is only
|
||||
* available ABI 3.20 onwards.
|
||||
*/
|
||||
#define DAI_INTEL_IPC3_SSP_CONFIG_FLAGS_2_STEP_STOP BIT(0)
|
||||
|
||||
/* ssc1: TINTE */
|
||||
#define DAI_INTEL_IPC3_SSP_QUIRK_TINTE (1 << 0)
|
||||
/* ssc1: PINTE */
|
||||
#define DAI_INTEL_IPC3_SSP_QUIRK_PINTE (1 << 1)
|
||||
/* ssc2: SMTATF */
|
||||
#define DAI_INTEL_IPC3_SSP_QUIRK_SMTATF (1 << 2)
|
||||
/* ssc2: MMRATF */
|
||||
#define DAI_INTEL_IPC3_SSP_QUIRK_MMRATF (1 << 3)
|
||||
/* ssc2: PSPSTWFDFD */
|
||||
#define DAI_INTEL_IPC3_SSP_QUIRK_PSPSTWFDFD (1 << 4)
|
||||
/* ssc2: PSPSRWFDFD */
|
||||
#define DAI_INTEL_IPC3_SSP_QUIRK_PSPSRWFDFD (1 << 5)
|
||||
/* ssc1: LBM */
|
||||
#define DAI_INTEL_IPC3_SSP_QUIRK_LBM (1 << 6)
|
||||
|
||||
/* here is the possibility to define others aux macros */
|
||||
|
||||
#define DAI_INTEL_IPC3_SSP_FRAME_PULSE_WIDTH_MAX 38
|
||||
#define DAI_INTEL_IPC3_SSP_SLOT_PADDING_MAX 31
|
||||
|
||||
/* SSP clocks control settings
|
||||
*
|
||||
* Macros for clks_control field in sof_dai_ssp_params struct.
|
||||
*/
|
||||
|
||||
/* mclk 0 disable */
|
||||
#define DAI_INTEL_IPC3_SSP_MCLK_0_DISABLE BIT(0)
|
||||
/* mclk 1 disable */
|
||||
#define DAI_INTEL_IPC3_SSP_MCLK_1_DISABLE BIT(1)
|
||||
/* mclk keep active */
|
||||
#define DAI_INTEL_IPC3_SSP_CLKCTRL_MCLK_KA BIT(2)
|
||||
/* bclk keep active */
|
||||
#define DAI_INTEL_IPC3_SSP_CLKCTRL_BCLK_KA BIT(3)
|
||||
/* fs keep active */
|
||||
#define DAI_INTEL_IPC3_SSP_CLKCTRL_FS_KA BIT(4)
|
||||
/* bclk idle */
|
||||
#define DAI_INTEL_IPC3_SSP_CLKCTRL_BCLK_IDLE_HIGH BIT(5)
|
||||
/* mclk early start */
|
||||
#define DAI_INTEL_IPC3_SSP_CLKCTRL_MCLK_ES BIT(6)
|
||||
/* bclk early start */
|
||||
#define DAI_INTEL_IPC3_SSP_CLKCTRL_BCLK_ES BIT(7)
|
||||
|
||||
/* SSP Configuration Request - SOF_DAI_SSP_CONFIG */
|
||||
struct dai_intel_ipc3_ssp_params {
|
||||
uint32_t reserved0;
|
||||
uint16_t reserved1;
|
||||
uint16_t mclk_id;
|
||||
|
||||
uint32_t mclk_rate; /* mclk frequency in Hz */
|
||||
uint32_t fsync_rate; /* fsync frequency in Hz */
|
||||
uint32_t bclk_rate; /* bclk frequency in Hz */
|
||||
|
||||
/* TDM */
|
||||
uint32_t tdm_slots;
|
||||
uint32_t rx_slots;
|
||||
uint32_t tx_slots;
|
||||
|
||||
/* data */
|
||||
uint32_t sample_valid_bits;
|
||||
uint16_t tdm_slot_width;
|
||||
uint16_t reserved2; /* alignment */
|
||||
|
||||
/* MCLK */
|
||||
uint32_t mclk_direction;
|
||||
|
||||
uint16_t frame_pulse_width;
|
||||
uint16_t tdm_per_slot_padding_flag;
|
||||
uint32_t clks_control;
|
||||
uint32_t quirks;
|
||||
uint32_t bclk_delay; /* guaranteed time (ms) for which BCLK
|
||||
* will be driven, before sending data
|
||||
*/
|
||||
} __packed;
|
||||
|
||||
#endif /* __DAI_PARAMS_INTEL_IPC3_H__ */
|
255
drivers/dai/intel/ssp/dai-params-intel-ipc4.h
Normal file
255
drivers/dai/intel/ssp/dai-params-intel-ipc4.h
Normal file
|
@ -0,0 +1,255 @@
|
|||
/*
|
||||
* Copyright (c) 2022 Intel Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __DAI_PARAMS_INTEL_IPC4_H__
|
||||
#define __DAI_PARAMS_INTEL_IPC4_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define DAI_INTEL_I2S_TDM_MAX_SLOT_MAP_COUNT 8
|
||||
|
||||
/**< Type of the gateway. */
|
||||
enum dai_intel_ipc4_connector_node_id_type {
|
||||
/**< HD/A host output (-> DSP). */
|
||||
dai_intel_ipc4_hda_host_output_class = 0,
|
||||
/**< HD/A host input (<- DSP). */
|
||||
dai_intel_ipc4_hda_host_input_class = 1,
|
||||
/**< HD/A host input/output (rsvd for future use). */
|
||||
dai_intel_ipc4_hda_host_inout_class = 2,
|
||||
|
||||
/**< HD/A link output (DSP ->). */
|
||||
dai_intel_ipc4_hda_link_output_class = 8,
|
||||
/**< HD/A link input (DSP <-). */
|
||||
dai_intel_ipc4_hda_link_input_class = 9,
|
||||
/**< HD/A link input/output (rsvd for future use). */
|
||||
dai_intel_ipc4_hda_link_inout_class = 10,
|
||||
|
||||
/**< DMIC link input (DSP <-). */
|
||||
dai_intel_ipc4_dmic_link_input_class = 11,
|
||||
|
||||
/**< I2S link output (DSP ->). */
|
||||
dai_intel_ipc4_i2s_link_output_class = 12,
|
||||
/**< I2S link input (DSP <-). */
|
||||
dai_intel_ipc4_i2s_link_input_class = 13,
|
||||
|
||||
/**< ALH link output, legacy for SNDW (DSP ->). */
|
||||
dai_intel_ipc4_alh_link_output_class = 16,
|
||||
/**< ALH link input, legacy for SNDW (DSP <-). */
|
||||
dai_intel_ipc4_alh_link_input_class = 17,
|
||||
|
||||
/**< SNDW link output (DSP ->). */
|
||||
dai_intel_ipc4_alh_snd_wire_stream_link_output_class = 16,
|
||||
/**< SNDW link input (DSP <-). */
|
||||
dai_intel_ipc4_alh_snd_wire_stream_link_input_class = 17,
|
||||
|
||||
/**< UAOL link output (DSP ->). */
|
||||
dai_intel_ipc4_alh_uaol_stream_link_output_class = 18,
|
||||
/**< UAOL link input (DSP <-). */
|
||||
dai_intel_ipc4_alh_uaol_stream_link_input_class = 19,
|
||||
|
||||
/**< IPC output (DSP ->). */
|
||||
dai_intel_ipc4_ipc_output_class = 20,
|
||||
/**< IPC input (DSP <-). */
|
||||
dai_intel_ipc4_ipc_input_class = 21,
|
||||
|
||||
/**< I2S Multi gtw output (DSP ->). */
|
||||
dai_intel_ipc4_i2s_multi_link_output_class = 22,
|
||||
/**< I2S Multi gtw input (DSP <-). */
|
||||
dai_intel_ipc4_i2s_multi_link_input_class = 23,
|
||||
/**< GPIO */
|
||||
dai_intel_ipc4_gpio_class = 24,
|
||||
/**< SPI */
|
||||
dai_intel_ipc4_spi_output_class = 25,
|
||||
dai_intel_ipc4_spi_input_class = 26,
|
||||
dai_intel_ipc4_max_connector_node_id_type
|
||||
};
|
||||
|
||||
/**< Base top-level structure of an address of a gateway. */
|
||||
/*!
|
||||
* The virtual index value, presented on the top level as raw 8 bits,
|
||||
* is expected to be encoded in a gateway specific way depending on
|
||||
* the actual type of gateway.
|
||||
*/
|
||||
union dai_intel_ipc4_connector_node_id {
|
||||
|
||||
/**< Raw 32-bit value of node id. */
|
||||
uint32_t dw;
|
||||
|
||||
/**< Bit fields */
|
||||
struct {
|
||||
/**< Index of the virtual DMA at the gateway. */
|
||||
uint32_t v_index : 8;
|
||||
|
||||
/**< Type of the gateway, one of ConnectorNodeId::Type values. */
|
||||
uint32_t dma_type : 5;
|
||||
|
||||
/**< Rsvd field. */
|
||||
uint32_t _rsvd : 19;
|
||||
} f; /**<< Bits */
|
||||
} __packed;
|
||||
|
||||
/*!
|
||||
* Attributes are usually provided along with the gateway configuration
|
||||
* BLOB when the FW is requested to instantiate that gateway.
|
||||
*
|
||||
* There are flags which requests FW to allocate gateway related data
|
||||
* (buffers and other items used while transferring data, like linked list)
|
||||
* to be allocated from a special memory area, e.g low power memory.
|
||||
*/
|
||||
union dai_intel_ipc4_gateway_attributes {
|
||||
|
||||
/**< Raw value */
|
||||
uint32_t dw;
|
||||
|
||||
/**< Access to the fields */
|
||||
struct {
|
||||
/**< Gateway data requested in low power memory. */
|
||||
uint32_t lp_buffer_alloc : 1;
|
||||
|
||||
/**< Gateway data requested in register file memory. */
|
||||
uint32_t alloc_from_reg_file : 1;
|
||||
|
||||
/**< Reserved field */
|
||||
uint32_t _rsvd : 30;
|
||||
} bits; /**<< Bits */
|
||||
} __packed;
|
||||
|
||||
/**< Configuration for the IPC Gateway */
|
||||
struct dai_intel_ipc4_gateway_config_blob {
|
||||
|
||||
/**< Size of the gateway buffer, specified in bytes */
|
||||
uint32_t buffer_size;
|
||||
|
||||
/**< Flags */
|
||||
union flags {
|
||||
struct bits {
|
||||
/**< Activates high threshold notification */
|
||||
/*!
|
||||
* Indicates whether notification should be sent to the host
|
||||
* when the size of data in the buffer reaches the high threshold
|
||||
* specified by threshold_high parameter.
|
||||
*/
|
||||
uint32_t notif_high : 1;
|
||||
|
||||
/**< Activates low threshold notification */
|
||||
/*!
|
||||
* Indicates whether notification should be sent to the host
|
||||
* when the size of data in the buffer reaches the low threshold
|
||||
* specified by threshold_low parameter.
|
||||
*/
|
||||
uint32_t notif_low : 1;
|
||||
|
||||
/**< Reserved field */
|
||||
uint32_t rsvd : 30;
|
||||
} f; /**<< Bits */
|
||||
/**< Raw value of flags */
|
||||
uint32_t flags_raw;
|
||||
} u; /**<< Flags */
|
||||
|
||||
/**< High threshold */
|
||||
/*!
|
||||
* Specifies the high threshold (in bytes) for notifying the host
|
||||
* about the buffered data level.
|
||||
*/
|
||||
uint32_t threshold_high;
|
||||
|
||||
/**< Low threshold */
|
||||
/*!
|
||||
* Specifies the low threshold (in bytes) for notifying the host
|
||||
* about the buffered data level.
|
||||
*/
|
||||
uint32_t threshold_low;
|
||||
} __packed;
|
||||
|
||||
/* i2s Configuration BLOB building blocks */
|
||||
|
||||
/* i2s registers for i2s Configuration */
|
||||
struct dai_intel_ipc4_ssp_config {
|
||||
uint32_t ssc0;
|
||||
uint32_t ssc1;
|
||||
uint32_t sscto;
|
||||
uint32_t sspsp;
|
||||
uint32_t sstsa;
|
||||
uint32_t ssrsa;
|
||||
uint32_t ssc2;
|
||||
uint32_t sspsp2;
|
||||
uint32_t ssc3;
|
||||
uint32_t ssioc;
|
||||
} __packed;
|
||||
|
||||
struct dai_intel_ipc4_ssp_mclk_config {
|
||||
/* master clock divider control register */
|
||||
uint32_t mdivc;
|
||||
|
||||
/* master clock divider ratio register */
|
||||
uint32_t mdivr;
|
||||
} __packed;
|
||||
|
||||
struct dai_intel_ipc4_ssp_driver_config {
|
||||
struct dai_intel_ipc4_ssp_config i2s_config;
|
||||
struct dai_intel_ipc4_ssp_mclk_config mclk_config;
|
||||
} __packed;
|
||||
|
||||
struct dai_intel_ipc4_ssp_start_control {
|
||||
/* delay in msec between enabling interface (moment when
|
||||
* Copier instance is being attached to the interface) and actual
|
||||
* interface start. Value of 0 means no delay.
|
||||
*/
|
||||
uint32_t clock_warm_up : 16;
|
||||
|
||||
/* specifies if parameters target MCLK (1) or SCLK (0) */
|
||||
uint32_t mclk : 1;
|
||||
|
||||
/* value of 1 means that clock should be started immediately
|
||||
* even if no Copier instance is currently attached to the interface.
|
||||
*/
|
||||
uint32_t warm_up_ovr : 1;
|
||||
uint32_t rsvd0 : 14;
|
||||
} __packed;
|
||||
|
||||
struct dai_intel_ipc4_ssp_stop_control {
|
||||
/* delay in msec between stopping the interface
|
||||
* (moment when Copier instance is being detached from the interface)
|
||||
* and interface clock stop. Value of 0 means no delay.
|
||||
*/
|
||||
uint32_t clock_stop_delay : 16;
|
||||
|
||||
/* value of 1 means that clock should be kept running (infinite
|
||||
* stop delay) after Copier instance detaches from the interface.
|
||||
*/
|
||||
uint32_t keep_running : 1;
|
||||
|
||||
/* value of 1 means that clock should be stopped immediately */
|
||||
uint32_t clock_stop_ovr : 1;
|
||||
uint32_t rsvd1 : 14;
|
||||
} __packed;
|
||||
|
||||
union dai_intel_ipc4_ssp_dma_control {
|
||||
struct dai_intel_ipc4_ssp_control {
|
||||
struct dai_intel_ipc4_ssp_start_control start_control;
|
||||
struct dai_intel_ipc4_ssp_stop_control stop_control;
|
||||
} control_data;
|
||||
|
||||
struct dai_intel_ipc4_mn_div_config {
|
||||
uint32_t mval;
|
||||
uint32_t nval;
|
||||
} mndiv_control_data;
|
||||
} __packed;
|
||||
|
||||
struct dai_intel_ipc4_ssp_configuration_blob {
|
||||
union dai_intel_ipc4_gateway_attributes gw_attr;
|
||||
|
||||
/* TDM time slot mappings */
|
||||
uint32_t tdm_ts_group[DAI_INTEL_I2S_TDM_MAX_SLOT_MAP_COUNT];
|
||||
|
||||
/* i2s port configuration */
|
||||
struct dai_intel_ipc4_ssp_driver_config i2s_driver_config;
|
||||
|
||||
/* optional configuration parameters */
|
||||
union dai_intel_ipc4_ssp_dma_control i2s_dma_control[0];
|
||||
} __packed;
|
||||
|
||||
#endif
|
2021
drivers/dai/intel/ssp/ssp.c
Normal file
2021
drivers/dai/intel/ssp/ssp.c
Normal file
File diff suppressed because it is too large
Load diff
341
drivers/dai/intel/ssp/ssp.h
Normal file
341
drivers/dai/intel/ssp/ssp.h
Normal file
|
@ -0,0 +1,341 @@
|
|||
/*
|
||||
* Copyright (c) 2022 Intel Corporation.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __INTEL_DAI_DRIVER_SSP_H__
|
||||
#define __INTEL_DAI_DRIVER_SSP_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <drivers/dai.h>
|
||||
#include "dai-params-intel-ipc3.h"
|
||||
#include "dai-params-intel-ipc4.h"
|
||||
|
||||
#define DAI_INTEL_SSP_MASK(b_hi, b_lo) \
|
||||
(((1ULL << ((b_hi) - (b_lo) + 1ULL)) - 1ULL) << (b_lo))
|
||||
#define DAI_INTEL_SSP_SET_BIT(b, x) (((x) & 1) << (b))
|
||||
#define DAI_INTEL_SSP_SET_BITS(b_hi, b_lo, x) \
|
||||
(((x) & ((1ULL << ((b_hi) - (b_lo) + 1ULL)) - 1ULL)) << (b_lo))
|
||||
#define DAI_INTEL_SSP_GET_BIT(b, x) \
|
||||
(((x) & (1ULL << (b))) >> (b))
|
||||
#define DAI_INTEL_SSP_GET_BITS(b_hi, b_lo, x) \
|
||||
(((x) & MASK(b_hi, b_lo)) >> (b_lo))
|
||||
|
||||
/* ssp_freq array constants */
|
||||
#define DAI_INTEL_SSP_NUM_FREQ 3
|
||||
#define DAI_INTEL_SSP_MAX_FREQ_INDEX (DAI_INTEL_SSP_NUM_FREQ - 1)
|
||||
#define DAI_INTEL_SSP_DEFAULT_IDX 1
|
||||
|
||||
/* the SSP port fifo depth */
|
||||
#define DAI_INTEL_SSP_FIFO_DEPTH 16
|
||||
|
||||
/* the watermark for the SSP fifo depth setting */
|
||||
#define DAI_INTEL_SSP_FIFO_WATERMARK 8
|
||||
|
||||
/* minimal SSP port delay in cycles */
|
||||
#define DAI_INTEL_SSP_PLATFORM_DELAY 1600
|
||||
/* minimal SSP port delay in useconds */
|
||||
#define DAI_INTEL_SSP_PLATFORM_DELAY_US 42
|
||||
#define DAI_INTEL_SSP_PLATFORM_DEFAULT_DELAY 12
|
||||
#define DAI_INTEL_SSP_DEFAULT_TRY_TIMES 8
|
||||
|
||||
#if CONFIG_SOC_SERIES_INTEL_CAVS_V15
|
||||
/** \brief Number of 'base' SSP ports available */
|
||||
#define DAI_INTEL_SSP_NUM_BASE 4
|
||||
/** \brief Number of 'extended' SSP ports available */
|
||||
#define DAI_INTEL_SSP_NUM_EXT 2
|
||||
#else
|
||||
/** \brief Number of 'base' SSP ports available */
|
||||
#define DAI_INTEL_SSP_NUM_BASE 6
|
||||
/** \brief Number of 'extended' SSP ports available */
|
||||
#define DAI_INTEL_SSP_NUM_EXT 0
|
||||
#endif
|
||||
|
||||
/** \brief Number of SSP MCLKs available */
|
||||
#define DAI_INTEL_SSP_NUM_MCLK 2
|
||||
|
||||
#define DAI_INTEL_SSP_CLOCK_XTAL_OSCILLATOR 0x0
|
||||
#define DAI_INTEL_SSP_CLOCK_AUDIO_CARDINAL 0x1
|
||||
#define DAI_INTEL_SSP_CLOCK_PLL_FIXED 0x2
|
||||
|
||||
/* SSP register offsets */
|
||||
#define SSCR0 0x00
|
||||
#define SSCR1 0x04
|
||||
#define SSSR 0x08
|
||||
#define SSITR 0x0C
|
||||
#define SSDR 0x10
|
||||
#define SSTO 0x28
|
||||
#define SSPSP 0x2C
|
||||
#define SSTSA 0x30
|
||||
#define SSRSA 0x34
|
||||
#define SSTSS 0x38
|
||||
#define SSCR2 0x40
|
||||
|
||||
/* SSCR0 bits */
|
||||
#define SSCR0_DSIZE(x) DAI_INTEL_SSP_SET_BITS(3, 0, (x) - 1)
|
||||
#define SSCR0_DSIZE_GET(x) (((x) & DAI_INTEL_SSP_MASK(3, 0)) + 1)
|
||||
#define SSCR0_FRF DAI_INTEL_SSP_MASK(5, 4)
|
||||
#define SSCR0_MOT DAI_INTEL_SSP_SET_BITS(5, 4, 0)
|
||||
#define SSCR0_TI DAI_INTEL_SSP_SET_BITS(5, 4, 1)
|
||||
#define SSCR0_NAT DAI_INTEL_SSP_SET_BITS(5, 4, 2)
|
||||
#define SSCR0_PSP DAI_INTEL_SSP_SET_BITS(5, 4, 3)
|
||||
#define SSCR0_ECS BIT(6)
|
||||
#define SSCR0_SSE BIT(7)
|
||||
#define SSCR0_SCR_MASK DAI_INTEL_SSP_MASK(19, 8)
|
||||
#define SSCR0_SCR(x) DAI_INTEL_SSP_SET_BITS(19, 8, x)
|
||||
#define SSCR0_EDSS BIT(20)
|
||||
#define SSCR0_NCS BIT(21)
|
||||
#define SSCR0_RIM BIT(22)
|
||||
#define SSCR0_TIM BIT(23)
|
||||
#define SSCR0_FRDC(x) DAI_INTEL_SSP_SET_BITS(26, 24, (x) - 1)
|
||||
#define SSCR0_FRDC_GET(x) ((((x) & DAI_INTEL_SSP_MASK(26, 24)) >> 24) + 1)
|
||||
#define SSCR0_ACS BIT(30)
|
||||
#define SSCR0_MOD BIT(31)
|
||||
|
||||
/* SSCR1 bits */
|
||||
#define SSCR1_RIE BIT(0)
|
||||
#define SSCR1_TIE BIT(1)
|
||||
#define SSCR1_LBM BIT(2)
|
||||
#define SSCR1_SPO BIT(3)
|
||||
#define SSCR1_SPH BIT(4)
|
||||
#define SSCR1_MWDS BIT(5)
|
||||
#define SSCR1_TFT_MASK DAI_INTEL_SSP_MASK(9, 6)
|
||||
#define SSCR1_TFT(x) DAI_INTEL_SSP_SET_BITS(9, 6, (x) - 1)
|
||||
#define SSCR1_RFT_MASK DAI_INTEL_SSP_MASK(13, 10)
|
||||
#define SSCR1_RFT(x) DAI_INTEL_SSP_SET_BITS(13, 10, (x) - 1)
|
||||
#define SSCR1_EFWR BIT(14)
|
||||
#define SSCR1_STRF BIT(15)
|
||||
#define SSCR1_IFS BIT(16)
|
||||
#define SSCR1_PINTE BIT(18)
|
||||
#define SSCR1_TINTE BIT(19)
|
||||
#define SSCR1_RSRE BIT(20)
|
||||
#define SSCR1_TSRE BIT(21)
|
||||
#define SSCR1_TRAIL BIT(22)
|
||||
#define SSCR1_RWOT BIT(23)
|
||||
#define SSCR1_SFRMDIR BIT(24)
|
||||
#define SSCR1_SCLKDIR BIT(25)
|
||||
#define SSCR1_ECRB BIT(26)
|
||||
#define SSCR1_ECRA BIT(27)
|
||||
#define SSCR1_SCFR BIT(28)
|
||||
#define SSCR1_EBCEI BIT(29)
|
||||
#define SSCR1_TTE BIT(30)
|
||||
#define SSCR1_TTELP BIT(31)
|
||||
|
||||
#define SSCR2_TURM1 BIT(1)
|
||||
#define SSCR2_PSPSRWFDFD BIT(3)
|
||||
#define SSCR2_PSPSTWFDFD BIT(4)
|
||||
#define SSCR2_SDFD BIT(14)
|
||||
#define SSCR2_SDPM BIT(16)
|
||||
#define SSCR2_LJDFD BIT(17)
|
||||
#define SSCR2_MMRATF BIT(18)
|
||||
#define SSCR2_SMTATF BIT(19)
|
||||
|
||||
/* SSR bits */
|
||||
#define SSSR_TNF BIT(2)
|
||||
#define SSSR_RNE BIT(3)
|
||||
#define SSSR_BSY BIT(4)
|
||||
#define SSSR_TFS BIT(5)
|
||||
#define SSSR_RFS BIT(6)
|
||||
#define SSSR_ROR BIT(7)
|
||||
#define SSSR_TUR BIT(21)
|
||||
|
||||
/* SSPSP bits */
|
||||
#define SSPSP_SCMODE(x) DAI_INTEL_SSP_SET_BITS(1, 0, x)
|
||||
#define SSPSP_SFRMP(x) DAI_INTEL_SSP_SET_BIT(2, x)
|
||||
#define SSPSP_ETDS BIT(3)
|
||||
#define SSPSP_STRTDLY(x) DAI_INTEL_SSP_SET_BITS(6, 4, x)
|
||||
#define SSPSP_DMYSTRT(x) DAI_INTEL_SSP_SET_BITS(8, 7, x)
|
||||
#define SSPSP_SFRMDLY(x) DAI_INTEL_SSP_SET_BITS(15, 9, x)
|
||||
#define SSPSP_SFRMWDTH(x) DAI_INTEL_SSP_SET_BITS(21, 16, x)
|
||||
#define SSPSP_DMYSTOP(x) DAI_INTEL_SSP_SET_BITS(24, 23, x)
|
||||
#define SSPSP_DMYSTOP_BITS 2
|
||||
#define SSPSP_DMYSTOP_MASK DAI_INTEL_SSP_MASK(SSPSP_DMYSTOP_BITS - 1, 0)
|
||||
#define SSPSP_FSRT BIT(25)
|
||||
#define SSPSP_EDMYSTOP(x) DAI_INTEL_SSP_SET_BITS(28, 26, x)
|
||||
|
||||
#define SSPSP2 0x44
|
||||
#define SSPSP2_FEP_MASK 0xff
|
||||
|
||||
#define SSCR3 0x48
|
||||
#define SSIOC 0x4C
|
||||
#define SSP_REG_MAX SSIOC
|
||||
|
||||
/* SSTSA bits */
|
||||
#define SSTSA_SSTSA(x) DAI_INTEL_SSP_SET_BITS(7, 0, x)
|
||||
#define SSTSA_GET(x) ((x) & DAI_INTEL_SSP_MASK(7, 0))
|
||||
#define SSTSA_TXEN BIT(8)
|
||||
|
||||
/* SSRSA bits */
|
||||
#define SSRSA_SSRSA(x) DAI_INTEL_SSP_SET_BITS(7, 0, x)
|
||||
#define SSRSA_GET(x) ((x) & DAI_INTEL_SSP_MASK(7, 0))
|
||||
#define SSRSA_RXEN BIT(8)
|
||||
|
||||
/* SSCR3 bits */
|
||||
#define SSCR3_FRM_MST_EN BIT(0)
|
||||
#define SSCR3_I2S_MODE_EN BIT(1)
|
||||
#define SSCR3_I2S_FRM_POL(x) DAI_INTEL_SSP_SET_BIT(2, x)
|
||||
#define SSCR3_I2S_TX_SS_FIX_EN BIT(3)
|
||||
#define SSCR3_I2S_RX_SS_FIX_EN BIT(4)
|
||||
#define SSCR3_I2S_TX_EN BIT(9)
|
||||
#define SSCR3_I2S_RX_EN BIT(10)
|
||||
#define SSCR3_CLK_EDGE_SEL BIT(12)
|
||||
#define SSCR3_STRETCH_TX BIT(14)
|
||||
#define SSCR3_STRETCH_RX BIT(15)
|
||||
#define SSCR3_MST_CLK_EN BIT(16)
|
||||
#define SSCR3_SYN_FIX_EN BIT(17)
|
||||
|
||||
/* SSCR4 bits */
|
||||
#define SSCR4_TOT_FRM_PRD(x) ((x) << 7)
|
||||
|
||||
/* SSCR5 bits */
|
||||
#define SSCR5_FRM_ASRT_CLOCKS(x) (((x) - 1) << 1)
|
||||
#define SSCR5_FRM_POLARITY(x) DAI_INTEL_SSP_SET_BIT(0, x)
|
||||
|
||||
/* SFIFOTT bits */
|
||||
#define SFIFOTT_TX(x) ((x) - 1)
|
||||
#define SFIFOTT_RX(x) (((x) - 1) << 16)
|
||||
|
||||
/* SFIFOL bits */
|
||||
#define SFIFOL_TFL(x) ((x) & 0xFFFF)
|
||||
#define SFIFOL_RFL(x) ((x) >> 16)
|
||||
|
||||
#define SSTSA_TSEN BIT(8)
|
||||
#define SSRSA_RSEN BIT(8)
|
||||
|
||||
#define SSCR3_TFL_MASK DAI_INTEL_SSP_MASK(5, 0)
|
||||
#define SSCR3_RFL_MASK DAI_INTEL_SSP_MASK(13, 8)
|
||||
#define SSCR3_TFL_VAL(scr3_val) (((scr3_val) >> 0) & DAI_INTEL_SSP_MASK(5, 0))
|
||||
#define SSCR3_RFL_VAL(scr3_val) (((scr3_val) >> 8) & DAI_INTEL_SSP_MASK(5, 0))
|
||||
#define SSCR3_TX(x) DAI_INTEL_SSP_SET_BITS(21, 16, (x) - 1)
|
||||
#define SSCR3_RX(x) DAI_INTEL_SSP_SET_BITS(29, 24, (x) - 1)
|
||||
|
||||
#define SSIOC_TXDPDEB BIT(1)
|
||||
#define SSIOC_SFCR BIT(4)
|
||||
#define SSIOC_SCOE BIT(5)
|
||||
|
||||
/* For 8000 Hz rate one sample is transmitted within 125us */
|
||||
#define DAI_INTEL_SSP_MAX_SEND_TIME_PER_SAMPLE 125
|
||||
|
||||
/* SSP flush retry counts maximum */
|
||||
#define DAI_INTEL_SSP_RX_FLUSH_RETRY_MAX 16
|
||||
|
||||
#define SSP_CLK_MCLK_ES_REQ BIT(0)
|
||||
#define SSP_CLK_MCLK_ACTIVE BIT(1)
|
||||
#define SSP_CLK_BCLK_ES_REQ BIT(2)
|
||||
#define SSP_CLK_BCLK_ACTIVE BIT(3)
|
||||
|
||||
#define I2SLCTL_OFFSET 0x04
|
||||
#define I2SLCTL_SPA(x) BIT(0 + x)
|
||||
#define I2SLCTL_CPA(x) BIT(8 + x)
|
||||
|
||||
#define SHIM_CLKCTL 0x78
|
||||
#define SHIM_CLKCTL_I2SFDCGB(x) BIT(20 + x)
|
||||
#define SHIM_CLKCTL_I2SEFDCGB(x) BIT(18 + x)
|
||||
|
||||
/** \brief Offset of MCLK Divider Control Register. */
|
||||
#define MN_MDIVCTRL 0x0
|
||||
|
||||
/** \brief Enables the output of MCLK Divider. */
|
||||
#define MN_MDIVCTRL_M_DIV_ENABLE(x) BIT(x)
|
||||
|
||||
/** \brief Offset of MCLK Divider x Ratio Register. */
|
||||
#define MN_MDIVR(x) (0x80 + (x) * 0x4)
|
||||
|
||||
/** \brief Bits for setting MCLK source clock. */
|
||||
#define MCDSS(x) DAI_INTEL_SSP_SET_BITS(17, 16, x)
|
||||
|
||||
/** \brief Offset of BCLK x M/N Divider M Value Register. */
|
||||
#define MN_MDIV_M_VAL(x) (0x100 + (x) * 0x8 + 0x0)
|
||||
|
||||
/** \brief Offset of BCLK x M/N Divider N Value Register. */
|
||||
#define MN_MDIV_N_VAL(x) (0x100 + (x) * 0x8 + 0x4)
|
||||
|
||||
/** \brief Bits for setting M/N source clock. */
|
||||
#define MNDSS(x) DAI_INTEL_SSP_SET_BITS(21, 20, x)
|
||||
|
||||
/** \brief Mask for clearing mclk and bclk source in MN_MDIVCTRL */
|
||||
#define MN_SOURCE_CLKS_MASK 0x3
|
||||
|
||||
#if CONFIG_INTEL_MN
|
||||
/** \brief BCLKs can be driven by multiple sources - M/N or XTAL directly.
|
||||
* Even in the case of M/N, the actual clock source can be XTAL,
|
||||
* Audio cardinal clock (24.576) or 96 MHz PLL.
|
||||
* The MN block is not really the source of clocks, but rather
|
||||
* an intermediate component.
|
||||
* Input for source is shared by all outputs coming from that source
|
||||
* and once it's in use, it can be adjusted only with dividers.
|
||||
* In order to change input, the source should not be in use, that's why
|
||||
* it's necessary to keep track of BCLKs sources to know when it's safe
|
||||
* to change shared input clock.
|
||||
*/
|
||||
enum bclk_source {
|
||||
MN_BCLK_SOURCE_NONE = 0, /**< port is not using any clock */
|
||||
MN_BCLK_SOURCE_MN, /**< port is using clock driven by M/N */
|
||||
MN_BCLK_SOURCE_XTAL, /**< port is using XTAL directly */
|
||||
};
|
||||
#endif
|
||||
|
||||
struct dai_intel_ssp_mn {
|
||||
uint32_t base;
|
||||
/**< keep track of which MCLKs are in use to know when it's safe to
|
||||
* change shared clock
|
||||
*/
|
||||
int mclk_sources_ref[DAI_INTEL_SSP_NUM_MCLK];
|
||||
int mclk_rate[DAI_INTEL_SSP_NUM_MCLK];
|
||||
int mclk_source_clock;
|
||||
|
||||
#if CONFIG_INTEL_MN
|
||||
enum bclk_source bclk_sources[(DAI_INTEL_SSP_NUM_BASE + DAI_INTEL_SSP_NUM_EXT)];
|
||||
int bclk_source_mn_clock;
|
||||
#endif
|
||||
|
||||
struct k_spinlock lock; /**< lock mechanism */
|
||||
};
|
||||
|
||||
struct dai_intel_ssp_freq_table {
|
||||
uint32_t freq;
|
||||
uint32_t ticks_per_msec;
|
||||
};
|
||||
|
||||
struct dai_intel_ssp_plat_fifo_data {
|
||||
uint32_t offset;
|
||||
uint32_t width;
|
||||
uint32_t depth;
|
||||
uint32_t watermark;
|
||||
uint32_t handshake;
|
||||
};
|
||||
|
||||
struct dai_intel_ssp_plat_data {
|
||||
uint32_t base;
|
||||
uint32_t ip_base;
|
||||
uint32_t shim_base;
|
||||
int irq;
|
||||
const char *irq_name;
|
||||
uint32_t flags;
|
||||
struct dai_intel_ssp_plat_fifo_data fifo[2];
|
||||
struct dai_intel_ssp_mn *mn_inst;
|
||||
struct dai_intel_ssp_freq_table *ftable;
|
||||
uint32_t *fsources;
|
||||
};
|
||||
|
||||
struct dai_intel_ssp_pdata {
|
||||
uint32_t sscr0;
|
||||
uint32_t sscr1;
|
||||
uint32_t psp;
|
||||
uint32_t state[2];
|
||||
uint32_t clk_active;
|
||||
struct dai_config config;
|
||||
struct dai_properties props;
|
||||
struct dai_intel_ipc3_ssp_params params;
|
||||
};
|
||||
|
||||
struct dai_intel_ssp {
|
||||
uint32_t index; /**< index */
|
||||
struct k_spinlock lock; /**< locking mechanism */
|
||||
int sref; /**< simple ref counter, guarded by lock */
|
||||
struct dai_intel_ssp_plat_data plat_data;
|
||||
void *priv_data;
|
||||
};
|
||||
|
||||
#endif
|
8
tests/boards/intel_adsp/ssp/CMakeLists.txt
Normal file
8
tests/boards/intel_adsp/ssp/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.20.0)
|
||||
|
||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||
project(adsp_ssp)
|
||||
|
||||
target_sources(app PRIVATE src/main.c)
|
Loading…
Add table
Add a link
Reference in a new issue