// SPDX-License-Identifier: GPL-2.0-or-later /* * Support for Digigram AlpX PCI-e boards * * Copyright (c) 2024 Digigram Digital (info@digigram.com) */ #ifndef _ALPX_VARIANTS_DANTE_H_ #define _ALPX_VARIANTS_DANTE_H_ #include "alpx.h" #include "alpx_reg.h" #include #include "alpx_variants_common.h" #include "alpx_axcmem.h" #include "alpx_controls.h" /* DANTE card */ #define ALPDANTE_DEFAULT_FS 48000 static struct snd_pcm_hardware alpdante_hardware_specs = { .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_RESUME, .formats = SNDRV_PCM_FMTBIT_S32_LE, .rates = SNDRV_PCM_RATE_48000, .rate_min = ALPDANTE_DEFAULT_FS, .rate_max = ALPDANTE_DEFAULT_FS, .channels_min = 64, .channels_max = 64, .buffer_bytes_max = SZ_1M * 4, /* period_bytes_max * periods_max */ .period_bytes_min = 48, /* min latency 1ms */ .period_bytes_max = SZ_1M, /* 20ms at 192kHz * nchans * 4B, rounded at 2^n */ .periods_min = 1, .periods_max = 4, }; /* FFPR Support */ /* FPPR Parameters */ static const u32 ALPDANTE_FLASH_UNLOCK = 1; static const u32 ALPDANTE_FLASH_WAIT_STEP_TIME = 10; static const u32 ALPDANTE_FLASH_LOCK_ACCESS_TRY_QTY = 1; static const u32 ALPDANTE_FPPR_SAVE_REGS_CMD_COMPLETION_WAIT_STEPS_QTY = 200; static const u32 ALPDANTE_FPPR_NOPE_CMD_ID = 0; static const u32 ALPDANTE_FPPR_SAVE_REGISTERS_CMD_ID = 6; static const u32 ALPDANTE_FCAR_STATUS_MASK = 0xFFFFFF; static const u32 ALPDANTE_SMALAR_AVAILABLE = 0; static const u32 ALPDANTE_SMALAR_IN_USE = 1; /* PROD TEST Parameters */ static const u32 ALPDANTE_PROD_TEST_LOOPBACK = BIT(1); /* FPPR Macros */ #define ALPDANTE_FPPR_CMD_STATUS(reg_val) ((reg_val) & ALPDANTE_FCAR_STATUS_MASK) /* AXCmem Registers locations */ static const struct alpx_axcmem_loc ALPDANTE_FIR_LOC = {1,0,2}; static const struct alpx_axcmem_loc ALPDANTE_CSPPR_LOC = {1,3,2}; static const struct alpx_axcmem_loc ALPDANTE_CLKPR_LOC = {1,3,1}; #define DEF_ALPDANTE_CLKPR_LOC {1,3,1} static const struct alpx_axcmem_loc ALPDANTE_FPPR_LOC = {1,4,0}; static const struct alpx_axcmem_loc ALPDANTE_ERRTST_LOC = {1,4,3}; static const struct alpx_axcmem_loc ALPDANTE_UBLAZE_VERSION_LOC = {3,1,2}; static const struct alpx_axcmem_loc ALPDANTE_DESIGN_BLOC_VERSION_LOC = {3,1,0}; static const struct alpx_axcmem_loc ALPDANTE_LOW_SERIAL_NUM_LOC = {3,2,0}; static const struct alpx_axcmem_loc ALPDANTE_HIGH_SERIAL_NUM_LOC = {3,3,0}; static const struct alpx_axcmem_loc ALPDANTE_SRConfig_LOC = {0,6,2}; static const struct alpx_axcmem_loc ALPDANTE_Frequency_Measure_LOC = {0,6,0}; #define DEF_ALPDANTE_Frequency_Measure_LOC {0,6,0} static const struct alpx_axcmem_loc ALPDANTE_Clock_Status_LOC = {0,3,0}; #define DEF_ALPDANTE_Clock_Status_LOC {0,3,0} static const struct alpx_axcmem_loc ALPDANTE_CLCSR_LOC = {1,1,0}; static const struct alpx_axcmem_loc ALPDANTE_FSDR_LOC = {0,1,1}; static const struct alpx_axcmem_loc ALPDANTE_FCR_LOC = {0,5,3}; static const struct alpx_axcmem_loc ALPDANTE_FCAR_LOC = {0,6,0}; static const struct alpx_axcmem_loc ALPDANTE_SMALAR_LOC = {0,4,0}; static const struct alpx_axcmem_loc ALPDANTE_CNAMPR_LOC = {1,3,3}; static const struct alpx_axcmem_loc ALPDANTE_NAME_LOC = {0,1,0}; static const struct alpx_axcmem_loc ALPDANTE_SAMPLE_COUNT_LOC = {3,0,0}; static const struct alpx_axcmem_loc ALPDANTE_PROD_TEST_LOC = {1,0,0}; /* NETWORK NAME support */ #define ALPDANTE_NETWORK_NAME_LENGTH 29 /* Controls support */ /* Clk controls support */ #define ALPDANTE_CLK_MANAGER_CONFIG_CLK_SRC_QTY 2 #define ALPDANTE_CLK_MANAGER_SOURCE_INTERNAL 0 #define ALPDANTE_CLK_MANAGER_SOURCE_SIC 1 static const char* alpdante_control_choice_clk_src_entries[ALPDANTE_CLK_MANAGER_CONFIG_CLK_SRC_QTY] __attribute__((unused)) = { "Internal", /* Only this one at the moment */ "SIC" }; /* Same order than the constants values */ static u32 alpdante_control_choice_clk_src_entries_values[ALPDANTE_CLK_MANAGER_CONFIG_CLK_SRC_QTY] __attribute__((unused)) = { ALPDANTE_CLK_MANAGER_SOURCE_INTERNAL, /* Only this one at the moment */ ALPDANTE_CLK_MANAGER_SOURCE_SIC, }; #if 0 #define ALPDANTE_CLK_MANAGER_CLK_VALUES_QTY 6 static const char* alpdante_control_choice_current_clk_values_entries[ALPDANTE_CLK_MANAGER_CLK_VALUES_QTY] __attribute__((unused)) = { "44.1kHz", "48kHz", "88.2kHz", "96kHz", "176,4kHz","192kHz" }; /* Same order than the constant values above */ static u32 alpdante_control_choice_current_clk_values_entries_values[ALPDANTE_CLK_MANAGER_CLK_VALUES_QTY] __attribute__((unused)) = { ALPDANTE_CLK_MANAGER_CLK_VALUE_44_1K, ALPDANTE_CLK_MANAGER_CLK_VALUE_48K, ALPDANTE_CLK_MANAGER_CLK_VALUE_88_2K, ALPDANTE_CLK_MANAGER_CLK_VALUE_96K, ALPDANTE_CLK_MANAGER_CLK_VALUE_176_4K, ALPDANTE_CLK_MANAGER_CLK_VALUE_192K , }; #endif /* Clock source register access */ #define ALPDANTE_Clock_Status_CLK_SRC_MASK GENMASK(2, 2) #define ALPDANTE_Clock_Status_CLK_SRC_POS 2 #define ALPDANTE_Clock_Status_Sample_Rate_MASK GENMASK(5,7) #define ALPDANTE_Clock_Status_Sample_Rate_POS 5 static struct alpx_control_descriptor alpdante_control_descriptors[] = { /* Clock sources Read Only */ { .type = ALPX_CONTROL_TYPE_AXCMEM_REL_CHOICE, .base = 0, .prefix = "Clk Eff Src", .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .data.axcmem_rel_choice = { .base_loc = DEF_ALPDANTE_CLKPR_LOC, .reg_loc = DEF_ALPDANTE_Clock_Status_LOC, .mask = ALPDANTE_Clock_Status_CLK_SRC_MASK, .pos = ALPDANTE_Clock_Status_CLK_SRC_POS, .getter = alpx_axcmem_getRegU8Value_ptr, .setter = NULL, .entries = alpdante_control_choice_clk_src_entries, .entries_values = alpdante_control_choice_clk_src_entries_values, .entries_count = ARRAY_SIZE(alpdante_control_choice_clk_src_entries), }, }, /* Read Measured Frequency Current Value Read Only */ { .type = ALPX_CONTROL_TYPE_AXCMEM_REL_VALUE, .base = 0, .prefix = "Clk Eff", .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .data.axcmem_rel_value = { .base_loc = DEF_ALPDANTE_CLKPR_LOC, .reg_loc = DEF_ALPDANTE_Frequency_Measure_LOC, .mask = 0xFF, .pos = 0, .min = 0, .max = 192, .getter = alpx_axcmem_getRegU8Value_ptr, .setter = NULL, }, }, /* Clock Fail over priority 0 TOP : a constant since no failover yet */ { .type = ALPX_CONTROL_TYPE_CONSTANT, .base = 0, .prefix = "Clk P0", .access = SNDRV_CTL_ELEM_ACCESS_READ, .data.constant = { .value = ALPDANTE_CLK_MANAGER_SOURCE_INTERNAL, }, }, }; /* Alp DANTE Variant */ static struct alpx_variant alpx_dante_variant __attribute__((unused)) = { .shortname = "AlpDANTE", .longname = "Alp DANTE", .model = ALPX_VARIANT_MODEL_ALPDANTE, .mixername = "AlpX-DANTE_Mix", .capture_hw = &alpdante_hardware_specs, .playback_hw = &alpdante_hardware_specs, .gpios = { .base = 0, .inputs_reg_offset = 0, .inputs_qty = 0, .outputs_reg_offset = 0, .outputs_qty = 0, }, .flash_golden_production_base = ALPxxx_FLASH_GOLDEN_PRODUCTION_BASE, .flash_partitions.partitions = NULL, .flash_partitions.qty = 0, .flash_partitions.qty_for_fw_update = 0, .control_descriptors = alpdante_control_descriptors, .control_descriptors_count = ARRAY_SIZE(alpdante_control_descriptors), }; #endif /* _ALPX_VARIANTS_DANTE_H_ */