summaryrefslogtreecommitdiff
path: root/snd-alpx/alpx_core.c
diff options
context:
space:
mode:
authorChristian Pointner <equinox@helsinki.at>2024-05-10 18:52:23 (GMT)
committerChristian Pointner <equinox@helsinki.at>2024-05-10 18:52:23 (GMT)
commita641800acf13b5fb1463d4280c3ee7fc267143fb (patch)
tree248b647a682f71d9eb90d14d24081368ea905a42 /snd-alpx/alpx_core.c
parentcc4badffe0e02d159c21eb90ea080a6a2f90cb4b (diff)
import whole driver package
Diffstat (limited to 'snd-alpx/alpx_core.c')
-rw-r--r--snd-alpx/alpx_core.c901
1 files changed, 0 insertions, 901 deletions
diff --git a/snd-alpx/alpx_core.c b/snd-alpx/alpx_core.c
deleted file mode 100644
index 0fb4d82..0000000
--- a/snd-alpx/alpx_core.c
+++ /dev/null
@@ -1,901 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
-* Support for Digigram AlpX PCI-e boards
-*
-* Copyright (c) 2024 Digigram Digital (info@digigram.com)
-*/
-
-#include "alpx.h"
-#include "alpx_reg.h"
-#include "alpx_mtd.h"
-#include "alpx_led.h"
-#include "alpx_controls.h"
-#include "alpx_streams.h"
-#include "alpx_version.h"
-#include "alpx_variants_stereo.h"
-#include "alpx_variants_stereo_apps_preFW283.h"
-#include "alpx_variants_mc.h"
-#include "alpx_variants_882_apps_preFW240.h"
-#include "alpx_variants_dead.h"
-#include "alpx_variants_madi.h"
-#include "alpx_variants_dante.h"
-#include "alpx_cards.h"
-#include "alpx_xdma.h"
-#include "snd_alpx_xdma.h"
-
-
-#include <linux/version.h>
-#include <linux/kmod.h>
-
-#if !defined (CONFIG_WITHOUT_GPIO)
-#define ALPX_WITH_GPIO
-#include <linux/gpio.h>
-#include <linux/gpio/driver.h>
-#include "alpx_gpio.h"
-#define ALPX_GPIO_OPTION_STRING ""
-#else
-#warning !! GPIOs are DISABLED !!
-#define ALPX_GPIO_OPTION_STRING "(without GPIO)"
-#endif
-
-
-#include <linux/mtd/partitions.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/version.h>
-#include <sound/control.h>
-#include <sound/core.h>
-#include <sound/initval.h>
-#include <sound/pcm.h>
-#include <linux/string.h>
-
-
-#if KERNEL_VERSION(6, 7, 0) > LINUX_VERSION_CODE
-#include "core/generic/6.3/amd_xdma.h"
-#include "include/6.3/amd_xdma.h"
-#else
-#include <linux/platform_data/amd_xdma.h>
-#include <linux/dma/amd_xdma.h>
-#endif
-
-#ifdef WITH_REG_DEBUG
-#include <linux/device.h>
-#endif
-
-/* Constants */
-
-/* Structures */
-
-/* Parameters */
-
-#define ALPX_DEFAULT_CARD_NAME "Digigram AlpX"
-
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-module_param_array(index, int, NULL, 0444);
-MODULE_PARM_DESC(index, "Index value for " ALPX_DEFAULT_CARD_NAME " soundcard.");
-
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-module_param_array(id, charp, NULL, 0444);
-MODULE_PARM_DESC(id, "ID string for " ALPX_DEFAULT_CARD_NAME " soundcard.");
-
-static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-module_param_array(enable, bool, NULL, 0444);
-MODULE_PARM_DESC(enable, "Enable " ALPX_DEFAULT_CARD_NAME " soundcard.");
-
-unsigned int log_transfers = 0;
-module_param(log_transfers, uint, 0644);
-MODULE_PARM_DESC(log_transfers, "0: no transfer logged(default), 1 : transfers logged");
-
-static bool with_board_in_prod_mode = false;
-module_param(with_board_in_prod_mode, bool, 0644);
-MODULE_PARM_DESC(with_board_in_prod_mode, "0: board in USER mode(default) ; 1: board in PRODUCTION mode ");
-
-static bool with_board_in_dead_mode = false;
-module_param(with_board_in_dead_mode, bool, 0644);
-MODULE_PARM_DESC(with_board_in_dead_mode, "0: board in NORMAL mode(default) ; 1: board in DEAD mode ");
-
-static unsigned int dante_configured_fs = ALPDANTE_DEFAULT_FS;
-module_param(dante_configured_fs, uint, 0644);
-MODULE_PARM_DESC(dante_configured_fs, "Configured FS for Alp DANTE card (value in Hz, default: 48000)");
-
-static bool dante_loopback_enabled = false;
-module_param(dante_loopback_enabled, bool, 0644);
-MODULE_PARM_DESC(dante_loopback_enabled, "Enable the Loopback for Alp DANTE card (default: FALSE)");
-
-static bool alp222_pre_FW283_apps_support = false;
-module_param(alp222_pre_FW283_apps_support, bool, 0644);
-MODULE_PARM_DESC(alp222_pre_FW283_apps_support, "For ALp222e cards ONLY, Enable the compatibility mode for applications written for PRE V283 Firmwares (default: FALSE)");
-
-static bool alp882_pre_FW240_apps_support = false;
-module_param(alp882_pre_FW240_apps_support, bool, 0644);
-MODULE_PARM_DESC(alp882_pre_FW240_apps_support, "For ALp882e cards ONLY, Enable the compatibility mode for applications written for PRE V240 Firmwares (default: FALSE)");
-
-
-/* Below, this is significant only if WITH_REG_DEBUG is defined */
-#ifdef WITH_REG_DEBUG
-#warning BUILD with Registers Debug enabled
-
-static ssize_t reg_offset_show(struct device* dev, struct device_attribute* attr, char* buf )
-{
-
- //HOWTO struct dev TO struct alpx_device :
- struct snd_card* const card = dev_get_drvdata(dev);
- struct alpx_device* const alpx_dev = card->private_data;
-
- dev_dbg( dev,"%s(): CALLED for card: 0x%p : REG OFFSET: 0x%08x\n", __func__,
- alpx_dev,
- alpx_dev->dbg_reg_offset);
-
-
- return scnprintf(buf, PAGE_SIZE, "0x%08x\n", alpx_dev->dbg_reg_offset);
-}
-
-static ssize_t reg_offset_store(struct device* dev, struct device_attribute* attr, const char* buf , size_t count)
-{
- //HOWTO struct dev TO struct alpx_device :
- struct snd_card* const card = dev_get_drvdata(dev);
- struct alpx_device* const alpx_dev = card->private_data;
-
- unsigned int reg_offset = 0;
- if (kstrtou32(buf, 0, &reg_offset) < 0)
- return -EINVAL;
-
- //Check offset range
- if ((reg_offset < ALP222_MIN_REG_OFFSET) &&
- (reg_offset > ALP222_MAX_REG_OFFSET))
- return -EINVAL;
-
- alpx_dev->dbg_reg_offset = reg_offset;
- dev_dbg( dev,"%s(): CALLED for alpx: %p, reg_offset: 0x%08x\n", __func__, alpx_dev, alpx_dev->dbg_reg_offset);
-
- return count;
-}
-
-//static struct device_attribute dev_reg_addr = __ATTR_RW(reg_addr);
-static struct device_attribute dev_reg_offset = __ATTR_RW(reg_offset);
-
-/******************************/
-static ssize_t reg_value_show(struct device* dev, struct device_attribute* attr, char* buf )
-{
-
- //HOWTO struct dev TO struct alpx_device :
- struct snd_card* const card = dev_get_drvdata(dev);
- struct alpx_device* const alpx_dev = card->private_data;
- /* Read the register once to cope with 'clear on read' registers */
- const uint32_t reg_value = readl(alpx_dev->base+ alpx_dev->dbg_reg_offset);
-
- dev_dbg( dev,"%s(): CALLED for %p, (dev:%p): [0x%08x] => 0x%08x\n", __func__,
- alpx_dev, dev,
- alpx_dev->dbg_reg_offset,
- reg_value);
-
- return scnprintf(buf, PAGE_SIZE, "0x%08x\n", reg_value);
-}
-
-static ssize_t reg_value_store(struct device* dev, struct device_attribute* attr, const char* buf , size_t count)
-{
- //HOWTO struct dev TO struct alpx_device :
- struct snd_card* const card = dev_get_drvdata(dev);
- struct alpx_device* const alpx_dev = card->private_data;
-
- uint32_t reg_value = 0;
- if (kstrtou32(buf, 0, &reg_value) < 0)
- return -EINVAL;
-
-
- writel(reg_value, alpx_dev->base + alpx_dev->dbg_reg_offset);
-
- dev_dbg( dev,"%s(): CALLED for alpx: %p, [0x%08x] <= 0x%08x, Check:0x%08x\n", __func__,
- alpx_dev,
- alpx_dev->dbg_reg_offset,
- reg_value,
- readl(alpx_dev->base+ alpx_dev->dbg_reg_offset));
-
- return count;
-}
-
-static struct device_attribute dev_reg_value = __ATTR_RW(reg_value);
-
-#endif
-
-/******************************/
-static ssize_t serial_number_show(struct device* dev, struct device_attribute* attr, char* buf )
-{
-
- struct snd_card* const card = dev_get_drvdata(dev);
- struct alpx_device* alpx_dev = card->private_data;
-
- dev_dbg(alpx_dev->dev, " %s() : AFTER shift %llu / 0x%llx\n", __func__, alpx_dev->identity.serial_number, alpx_dev->identity.serial_number);
-
- return scnprintf(buf, PAGE_SIZE, "%llu\n", alpx_dev->identity.serial_number);
-}
-
-static struct device_attribute dev_serial_number = __ATTR_RO(serial_number);
-/***************************************/
-
-static ssize_t ver_fpga_show(struct device* dev, struct device_attribute* attr, char* buf )
-{
-
- struct snd_card* const card = dev_get_drvdata(dev);
- struct alpx_device* alpx_dev = card->private_data;
-
- return scnprintf(buf, PAGE_SIZE, "%u\n", alpx_dev->identity.ver_fpga);
-}
-
-static struct device_attribute dev_ver_fpga = __ATTR_RO(ver_fpga);
-
-/***************************************/
-static ssize_t ver_mcu_show(struct device* dev, struct device_attribute* attr, char* buf )
-{
-
- struct snd_card* const card = dev_get_drvdata(dev);
- struct alpx_device* alpx_dev = card->private_data;
-
- return scnprintf(buf, PAGE_SIZE, "%u.%lu\n",
- ALPX_COMMON_VERSION_VERSION(alpx_dev->identity.ver_mcu),
- ALPX_COMMON_VERSION_REVISION(alpx_dev->identity.ver_mcu) );
-}
-
-static struct device_attribute dev_ver_mcu = __ATTR_RO(ver_mcu);
-/***************************************/
-static ssize_t dante_card_name_show(struct device* dev, struct device_attribute* attr, char* buf )
-{
-
- struct snd_card* const card = dev_get_drvdata(dev);
- struct alpx_device* alpx_dev = card->private_data;
-
- int result = alpdante_get_dante_name(alpx_dev, buf, ALPDANTE_NETWORK_NAME_LENGTH);
- return (!result) ? strlcat(buf, "\n", PAGE_SIZE) : 0;
-}
-
-static struct device_attribute dev_dante_card_name = __ATTR_RO(dante_card_name);
-/***************************************/
-
-/* PCI */
-
-static void alpx_card_private_free(struct snd_card *card)
-{
- struct alpx_device *alpx_dev = card->private_data;
-
-#if defined (ALPX_WITH_GPIO)
- if (alpx_dev->variant->features & ALPX_VARIANT_FEATURE_GPIOS)
- alpx_gpio_unregister(alpx_dev);
-#endif
-
- if (alpx_dev->controls)
- kfree(alpx_dev->controls);
-
- /* dirty crash avoid when dma fails and frees card before pipes are init. */
-}
-
-static inline unsigned int is_alp222_with_mic_option(struct alpx_device* alpx_dev)
-{
- const u32 reg_mic = readl(alpx_dev->base + ALP222_CONTROL_BASE + ALP222_MIC_CONTROL_REG);
- dev_dbg(alpx_dev->dev, "Daughter_Control[0x%08x:%x] = 0x%08x\n",
- ALP222_CONTROL_BASE,
- ALP222_MIC_CONTROL_REG,
- reg_mic);
- return reg_mic & (1<<ALP222_MIC_HERE_POS);
-}
-
-static int alpx_core_set_pci_bus(struct alpx_device* alpx_dev)
-{
- int ret = pci_enable_device(alpx_dev->pci_dev);
- if (ret) {
- dev_err(alpx_dev->dev, "failed to enable PCI device\n");
- return ret;
- }
-
- /* Enable PCI relaxed ordering. */
- pcie_capability_set_word(alpx_dev->pci_dev, PCI_EXP_DEVCTL,
- PCI_EXP_DEVCTL_RELAX_EN);
-
- /* Enable extended tagging. */
- pcie_capability_set_word(alpx_dev->pci_dev, PCI_EXP_DEVCTL,
- PCI_EXP_DEVCTL_EXT_TAG);
-
- /* Set maximum memory read request. */
- pcie_set_readrq(alpx_dev->pci_dev, 512);
-
- pci_set_master(alpx_dev->pci_dev);
-
- return ret;
-}
-
-
-/****************************************************************/
-/*
-* This function will HANDLE the XMA module dependency either from kernel or
-* from the package according to the kernel's version.
-* Return an error the kernel's module is in bad version (kernel <6.7) as no CYLLIC DMA
-* was yet supported.
-* MUST be CALLED after alpx_xdma_register() to get the xdma_dev
-*/
-static int alpx_core_handle_xdma_dep (struct device *dev, struct platform_device* xdma_dev)
-{
-
- dev_info(dev, "Handling XDMA support for Linux : %d.\n", LINUX_VERSION_CODE);
-
-#if KERNEL_VERSION(6, 3, 0) > LINUX_VERSION_CODE
- dev_info(dev, "OLD Kernel, USE snd-alpx-xdma.\n");
- //NO XDMA in the kernel Force the dependency to package's xdma module already done before call by
- // SND_ALPX_XDMA_DEP();
-
-#elif KERNEL_VERSION(6, 7, 0) <= LINUX_VERSION_CODE
- #if IS_ENABLED(CONFIG_XILINX_XDMA)
- dev_info(dev, "Kernel XDMA Ok, USE xdma.\n");
- //NO XDMA in the kernel Force the dependency to package's xdma module.
- xdma_get_user_irq(xdma_dev, 256); //Dumb irq to for an error : no way
- #else
- dev_info(dev, "Kernel XDMA NOT enabled, USE snd-alpx-xdma.\n");
- //Dependency already handled by SND_ALPX_XDMA_DEP() call defined accordingly !!
- #endif
-#elif (KERNEL_VERSION(6, 3, 0) <= LINUX_VERSION_CODE) && \
- (KERNEL_VERSION(6, 7, 0) > LINUX_VERSION_CODE)
- //FORCE snd-alpx-xdma use as kernel's one w/o cyclic support
- #if IS_ENABLED(CONFIG_XILINX_XDMA)
- #if IS_MODULE(CONFIG_XILINX_XDMA)
- #warning "Xilinx XDMA module must be unloaded before use : NOT COMPLIANT !!"
- #else
- #error "Xilinx XDMA moule in Kernel is not COMPLIANT, Kernel must be Reconfigured/Rebuild without it !!!!"
- #endif
- #endif
-#endif
- return 0;
-}
-/****************************************************************************/
-static int alpx_probe(struct pci_dev *pci_dev,
- const struct pci_device_id *pci_device_id)
-{
- static int card_idx = 0;
- struct device *dev = &pci_dev->dev;
- struct alpx_device *alpx_dev;
- struct snd_card *card;
- struct snd_pcm *pcm;
- int ret;
- int is_update_required = 0;
-
- /* Module identity */
-
- dev_info(dev,"version %s %s build date: %s, time: %s. %s, %s\n",
- ALPX_MODULE_VERSION,
- ALPX_GPIO_OPTION_STRING,
- __DATE__ ,
- __TIME__,
- SND_ALPX_XDMA_DEP(),
- log_transfers ? "Transfers Logged":"");
-
- /* Ensure dependency on AlpX XDMA support if needed*/
- SND_ALPX_XDMA_DEP();
-
- /* Card */
-
- if (card_idx >= SNDRV_CARDS)
- return -ENODEV;
-
- if (!enable[card_idx]) {
- card_idx++;
- return -ENOENT;
- }
-
- dev_dbg(dev,"%s() : PCI Id : Vendor: 0x04%x, Device: 0x%04x, subvendor: 0x%04x, subdevice: 0x%04x\n", __func__,
- pci_device_id->vendor,
- pci_device_id->device,
- pci_device_id->subvendor,
- pci_device_id->subdevice);
-
- dev_dbg(dev,"%s() : PCI dev: Vendor: 0x04%x, Device: 0x%04x, subvendor: 0x%04x, subdevice: 0x%04x\n", __func__,
- pci_dev->vendor,
- pci_dev->device,
- pci_dev->subsystem_vendor,
- pci_dev->subsystem_device);
-
-
- ret = snd_card_new(dev, index[card_idx], id[card_idx], THIS_MODULE,
- sizeof(*alpx_dev), &card);
- if (ret) {
- dev_err(dev," snd_card_new() => %d\n", ret);
- return ret;
- }
-
- card->private_free = alpx_card_private_free;
-
- /* PCI */
-
- pci_set_drvdata(pci_dev, card);
-
- alpx_dev = card->private_data;
- alpx_dev->dev = dev;
- alpx_dev->pci_dev = pci_dev;
-
- ret = alpx_core_set_pci_bus(alpx_dev);
- if (ret){
- dev_err(dev," alpx_core_set_pci_bus(alpx_dev) => %d\n", ret);
- goto error_card;
- }
-
- //Map USER BAR now to get access to all card's resources
- alpx_dev->base = pci_ioremap_bar(pci_dev, 0);
-
- /* PCI */
-
- ret = pci_enable_device(pci_dev);
- if (ret) {
- dev_err(dev, "failed to enable PCI device\n");
- goto error_card;
- }
-
- /* Enable PCI relaxed ordering. */
- pcie_capability_set_word(pci_dev, PCI_EXP_DEVCTL,
- PCI_EXP_DEVCTL_RELAX_EN);
-
- /* Enable extended tagging. */
- pcie_capability_set_word(pci_dev, PCI_EXP_DEVCTL,
- PCI_EXP_DEVCTL_EXT_TAG);
-
- /* Set maximum memory read request. */
- pcie_set_readrq(pci_dev, 512);
-
- pci_set_master(pci_dev);
-
- /* XDMA */
-
- alpx_dev->xdma_pdev = alpx_xdma_register(pci_dev);
- if (!alpx_dev->xdma_pdev) {
- dev_err(dev," alpx_xdma_register(alpx_dev) => %d\n", ret);
- goto disable_pci_dev;
- }
-
- /* XDMA dependency handling*/
- ret = alpx_core_handle_xdma_dep(dev, alpx_dev->xdma_pdev);
- if (ret) {
- dev_err(dev, "Error %d when handling xdma dependency !\n", ret);
- goto disable_pci_dev;
- }
-
- /* Variant */
-
- //Use PCI Id to select the actual variant : WARNING, MIC option is checked with user's registers !!
- switch (pci_dev->subsystem_device){
- case ALPX_PCI_ID_SUBSYSTEM_ALP222:
- /* HANDLE Alp222_MIC with LINE PCI Id : firmwares ante V272*/
- if (alp222_pre_FW283_apps_support) {
- dev_warn(alpx_dev->dev, "!!! Alp2220 Pre FW283 Application compatibility mode ACTIVATED !!!");
- }
- if (!is_alp222_with_mic_option(alpx_dev)) {
- alpx_dev->variant = (!alp222_pre_FW283_apps_support) ? &alp222_variant : &alp222_app_preFW283_variant;
- }
- else {
- alpx_dev->variant = (!alp222_pre_FW283_apps_support) ? &alp222_mic_variant : &alp222_app_preFW283_mic_variant;
- alp222_mic_controls_default_config(alpx_dev);
- }
- break;
- case ALPX_PCI_ID_SUBSYSTEM_ALP222_MIC:
- if (alp222_pre_FW283_apps_support) {
- dev_warn(alpx_dev->dev, "!!! Alp222 Pre FW283 Application compatibility mode ACTIVATED !!!");
- }
- alpx_dev->variant = (!alp222_pre_FW283_apps_support) ? &alp222_mic_variant : &alp222_app_preFW283_mic_variant;
- alp222_mic_controls_default_config(alpx_dev);
- break;
- case ALPX_PCI_ID_SUBSYSTEM_MADI:
- alpx_dev->variant = &alpx_madi_variant;
- break;
- case ALPX_PCI_ID_SUBSYSTEM_ALP882:
- if (alp882_pre_FW240_apps_support)
- dev_warn(alpx_dev->dev, "!!! Alp882 LINE with Pre FW240 Application compatibility mode ACTIVATED !!!");
- alpx_dev->variant = (!alp882_pre_FW240_apps_support) ? &alp882_line_variant : &alp882_app_preFW240_line_variant;
- break;
- case ALPX_PCI_ID_SUBSYSTEM_ALP882_MIC:
- if (alp882_pre_FW240_apps_support)
- dev_warn(alpx_dev->dev, "!!! Alp882 MIC with Pre FW240 Application compatibility mode ACTIVATED !!!");
- alpx_dev->variant = (!alp882_pre_FW240_apps_support) ? &alp882_mic_variant : &alp882_app_preFW240_mic_variant;
- break;
- case ALPX_PCI_ID_SUBSYSTEM_ALP442:
- alpx_dev->variant = &alp442_line_variant;
- break;
- case ALPX_PCI_ID_SUBSYSTEM_ALP442_MIC:
- alpx_dev->variant = &alp442_mic_variant;
- break;
- case ALPX_PCI_ID_SUBSYSTEM_MADI_ALP_DEAD:
- alpx_dev->variant = &alpx_dead_variant;
- break;
- case ALPX_PCI_ID_SUBSYSTEM_ALPDANTE:
- alpx_dev->variant = &alpx_dante_variant;
- break;
- default:
- dev_warn(alpx_dev->dev,"ALPX Driver: Model Id 0x%04x is not supported => DEAD by default Here !\n",
- pci_dev->subsystem_device);
- alpx_dev->variant = &alpx_dead_variant;
- }
-
- /* FORCED DEAD mode, not for DANTE card */
- if (with_board_in_dead_mode)
- {
- /* Check DEAD mode for supported variants*/
- if (alpx_dev->variant->model != ALPX_VARIANT_MODEL_ALPDANTE) {
- alpx_dev->variant = &alpx_dead_variant;
- dev_warn(alpx_dev->dev, " !!! Board forced in DEAD mode !!\n");
- }
- else {
- dev_err(alpx_dev->dev, " NO DEAD mode supported for this board : %s\n", alpx_dev->variant->shortname);
- ret = -EINVAL;
- goto unregister_xdma;
- }
- }
-
- /* MTD */
- if (alpx_dev->variant->flash_partitions.qty != 0) {
-// /* mtd Handle the PRODUCTION access or DEAD card, BUT not for DANTE cards*/
- with_board_in_prod_mode &= (alpx_dev->variant->model != ALPX_VARIANT_MODEL_ALPDANTE);
-
- if ( with_board_in_prod_mode ||
- (alpx_dev->variant->model == ALPX_VARIANT_DEAD)) {
- dev_warn( alpx_dev->dev," Flash in PRODUCTION mode or DEAD card: full access !\n");
- ret = alpx_mtd_probe(alpx_dev, alpx_dev->variant->flash_partitions.partitions ,alpx_dev->variant->flash_partitions.qty);
- }
- else {
- dev_dbg( alpx_dev->dev," Flash in USER mode: firmware update access only.\n");
- ret = alpx_mtd_probe(alpx_dev,
- &alpx_dev->variant->flash_partitions.partitions[ALPX_FLASH_PARTITION_FW_ID] ,
- alpx_dev->variant->flash_partitions.qty_for_fw_update);
- }
-
- if (ret)
- goto unregister_xdma;
- }
-
- if (alpx_dev->variant->model == ALPX_VARIANT_DEAD) {
- dev_warn(alpx_dev->dev," !!!! DEAD card found : Flash in PROD mode and nothing else !!\n");
- return 0;
- }
-
- /* finalize identity */
- switch (alpx_dev->variant->model) {
- case ALPX_VARIANT_MODEL_ALP882:
- case ALPX_VARIANT_MODEL_ALP882_MIC:
- case ALPX_VARIANT_MODEL_ALP442:
- case ALPX_VARIANT_MODEL_ALP442_MIC:
- alpmultichan_finalize_identity(alpx_dev);
- /* Check FW compatibility */
- if (alpx_dev->identity.ver_fpga < ALPMC_SUPPORTED_BASE_FW_VERSION) {
- dev_warn(alpx_dev->dev, "UNSUPPORTED MultiChannels firmware version %d (supported started at %d), UPDATE required !!\n",
- alpx_dev->identity.ver_fpga,
- ALPMC_SUPPORTED_BASE_FW_VERSION);
- is_update_required = 1;
- }
-
- break;
- case ALPX_VARIANT_MODEL_ALP222:
- case ALPX_VARIANT_MODEL_ALP222_MIC:
- alpstereo_finalize_identity(alpx_dev);
- /* Check FW compatibility */
- if (alpx_dev->identity.ver_fpga < ALP222_SUPPORTED_BASE_FW_VERSION) {
- dev_warn(alpx_dev->dev, "UNSUPPORTED Stereo firmware version %d (supported started at %d), UPDATE required !!\n",
- alpx_dev->identity.ver_fpga,
- ALP222_SUPPORTED_BASE_FW_VERSION);
-// is_update_required = 1;
- }
- break;
- case ALPX_VARIANT_MODEL_ALPDANTE:
- alpdante_finalize_identity(alpx_dev);
- /* Check FW compatibility */
- if (alpx_dev->identity.ver_fpga < ALPDANTE_SUPPORTED_BASE_FW_VERSION) {
- dev_warn(alpx_dev->dev, "UNSUPPORTED AlpDANTE firmware version %d (supported started at %d), UPDATE required !!\n",
- alpx_dev->identity.ver_fpga,
- ALPDANTE_SUPPORTED_BASE_FW_VERSION);
- is_update_required = 1;
- }
- break;
- default:
- dev_warn(alpx_dev->dev, " identity not finalized for this model : %d\n", alpx_dev->variant->model);
- }
-
-
- /* Remount MTD with SERIAL number added only in USER mod, to clearly identify the cards */
- if (!with_board_in_prod_mode ) {
-
- //Build a special partition table to add the serial number (A COPY) !!
- struct mtd_partition fw_partitions_table[ALPX_FLASH_PARTITION_QTY];
- char part_names[ALPX_FLASH_PARTITION_QTY][128];
- unsigned int part_idx = 0;
-
- for (part_idx = 0 ; part_idx < alpx_dev->variant->flash_partitions.qty_for_fw_update ; ++part_idx) {
-
- fw_partitions_table[part_idx] = alpx_dev->variant->flash_partitions.partitions[ALPX_FLASH_PARTITION_FW_ID + part_idx];
- scnprintf(part_names[part_idx], PAGE_SIZE, "%s-%llu",
- fw_partitions_table[part_idx].name,
- alpx_dev->identity.serial_number);
-
- fw_partitions_table[part_idx].name = part_names[part_idx];
- }
-
- dev_dbg( alpx_dev->dev," Flash in USER mode: firmware partitionS with S/N appened.\n");
- /* Replace the current partitions */
- alpx_mtd_remove(alpx_dev);
- ret = alpx_mtd_probe(alpx_dev,
- fw_partitions_table,
- alpx_dev->variant->flash_partitions.qty_for_fw_update);
- }
-
- if (ret){
- dev_err(alpx_dev->dev," Error %d when re-creating Firmware partition\n", ret);
- goto unregister_xdma;
- }
-
- //Stop here if update required.
- if (is_update_required == 1)
- return 0;
-
- /* Information */
-
- strcpy(card->driver, "Driver AlpX");
-
- //Check if replaced by parameters, default : use the variant names
- dev_dbg( alpx_dev->dev,"%s() : id[%d] = %s\n", __func__,
- card_idx,
- id[card_idx] == NULL ? "NULL" : id[card_idx]);
-
- if (id[card_idx])
- sprintf(card->shortname, id[card_idx]);
- else
- sprintf(card->shortname, alpx_dev->variant->shortname);
-
- strcpy(card->longname, alpx_dev->variant->longname);
- strcpy(card->mixername, alpx_dev->variant->mixername);
-
- /* Pipes */
-
- spin_lock_init(&alpx_dev->config.lock);
-
- alpx_pipe_init(&alpx_dev->playback, true);
- alpx_pipe_init(&alpx_dev->capture, false);
-
- /* PCM */
-
- ret = snd_pcm_new(card, card->shortname, 0, 1, 1, &pcm);
- if (ret) {
- dev_err(dev," snd_pcm_new(card) => %d\n", ret);
- goto unregister_xdma;
- }
-
- pcm->private_data = alpx_dev;
-
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &alpx_playback_ops);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &alpx_capture_ops);
-
- pcm->info_flags = 0;
-
- strcpy(pcm->name, card->longname);
-
- /* Controls */
-
- ret = alpx_controls_register(card);
- if (ret) {
- dev_err(dev," alpx_controls_register(card) => %d\n", ret);
- goto unregister_xdma;
- }
-
- /* Buffer */
-
-#if KERNEL_VERSION(5, 5, 0) <= LINUX_VERSION_CODE
- snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, dev,
- alpx_dev->variant->playback_hw->buffer_bytes_max,
- alpx_dev->variant->playback_hw->buffer_bytes_max);
-#else
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, dev,
- alpx_dev->variant->playback_hw->buffer_bytes_max,
- alpx_dev->variant->playback_hw->buffer_bytes_max);
-#endif
-#if defined (ALPX_WITH_GPIO)
- /* GPIO */
-
- if (alpx_dev->variant->features & ALPX_VARIANT_FEATURE_GPIOS)
- ret = alpx_gpio_register(alpx_dev, card->shortname);
-
- if (ret) {
- dev_err(dev," alpx_gpio_register(alpx_dev) => %d\n", ret);
- goto unregister_xdma;
- }
-#endif
- /* Proc */
- ret = alpx_proc_probe(alpx_dev);
- if (ret) {
- dev_err(dev," alpx_proc_probe(alpx_dev) => %d\n", ret);
- goto unregister_xdma;
- }
-
- /* Card */
-
- ret = snd_card_register(card);
- if (ret){
- dev_err(dev," snd_card_register(card) => %d\n", ret);
- goto error_proc;
- }
-
- /* Sys FS files */
- /* Reg debug */
-#ifdef WITH_REG_DEBUG
- dev_info(dev,"REG_DEBUG activated\n");
- alpx_dev->dbg_reg_offset = ALP222_MIN_REG_OFFSET;
-
- ret = device_create_file(dev, &dev_reg_offset);
- if (ret)
- {
- dev_err(dev," device_create_file(addr) => %d\n", ret);
- }
- else
- {
- dev_err(dev," device_create_file(addr) : Ok\n");
- }
-
- ret = device_create_file(dev, &dev_reg_value);
- if (ret)
- {
- dev_err(dev," device_create_file(value) => %d\n", ret);
- }
-#endif
-
- /* Serial number file */
- ret = device_create_file(dev, &dev_serial_number);
- if (ret)
- {
- dev_err(dev," Serial Number device_create_file() => %d\n", ret);
- }
-
- /* FPGA version file */
- ret = device_create_file(dev, &dev_ver_fpga);
- if (ret)
- {
- dev_err(dev," FPGA Version device_create_file() => %d\n", ret);
- }
-
- /* MCU version file */
- ret = device_create_file(dev, &dev_ver_mcu);
- if (ret)
- {
- dev_err(dev," MCU Version device_create_file() => %d\n", ret);
- }
-
- /* DANTE card's name */
- if (alpx_dev->variant->model == ALPX_VARIANT_MODEL_ALPDANTE) {
- ret = device_create_file(dev, &dev_dante_card_name);
- if (ret)
- {
- dev_err(dev," DANTE card's name device_create_file() => %d\n", ret);
- }
- }
-
- /* Production area replication from USER to GOLDEN if needed*/
- if (((alpx_dev->variant->model == ALPX_VARIANT_MODEL_ALP222) ||
- (alpx_dev->variant->model == ALPX_VARIANT_MODEL_ALP222_MIC)) &&
- alpx_mtd_is_available(alpx_dev) &&
- !alpx_mtd_is_golden_prod_area_valid(alpx_dev)) {
- dev_info(alpx_dev->dev," Production area in GOLDEN must be INITIALIZED\n");
- ret = alpx_mtd_replicate_prod_area(alpx_dev);
- if (!ret) {
- dev_info(alpx_dev->dev," Production area in GOLDEN is INITIALIZED\n");
- }
- else {
- dev_warn(alpx_dev->dev," Production area in GOLDEN NOT CORRECTLY INITIALIZED !!\n");
- }
- }
-
- switch (alpx_dev->variant->model){
- case ALPX_VARIANT_MODEL_ALP222:
- case ALPX_VARIANT_MODEL_ALP222_MIC:
- alpstereo_print_identity(alpx_dev, card, "Created");
- break;
- case ALPX_VARIANT_MODEL_ALP882:
- case ALPX_VARIANT_MODEL_ALP882_MIC:
- case ALPX_VARIANT_MODEL_ALP442:
- case ALPX_VARIANT_MODEL_ALP442_MIC:
- alpmultichan_print_identity(alpx_dev, card, "Created");
- break;
- case ALPX_VARIANT_MODEL_MADI:
- case ALPX_VARIANT_MODEL_MADI_LOOPBACK:
- alpmadi_print_identity(alpx_dev, card, "Created");
- break;
- case ALPX_VARIANT_MODEL_ALPDANTE:
- alpdante_print_identity(alpx_dev, card, "Created");
- alpdante_card_setup(alpx_dev, card, dante_configured_fs, dante_loopback_enabled);
- break;
- default:
- dev_warn(alpx_dev->dev," !!! UNKNOW variant identity: %d !!!!\n", alpx_dev->variant->model);
- };
-
- card_idx++;
-
- return 0;
-
-error_proc:
- dev_err(alpx_dev->dev," %s(): Error : 0x%x when creating proc entry\n", __func__, ret);
- alpx_proc_remove(alpx_dev);
-unregister_xdma:
- alpx_xdma_unregister(pci_dev, alpx_dev->xdma_pdev);
-disable_pci_dev:
- pci_disable_device(pci_dev);
-error_card:
- dev_err(alpx_dev->dev," %s(): Error : 0x%x when creating the card\n", __func__, ret);
- snd_card_free(card);
-
- return ret;
-}
-
-static void alpx_remove(struct pci_dev *pci_dev)
-{
- struct snd_card *card = pci_get_drvdata(pci_dev);
- struct alpx_device *alpx_dev = card->private_data;
-
- switch (alpx_dev->variant->model){
- case ALPX_VARIANT_MODEL_ALP222:
- case ALPX_VARIANT_MODEL_ALP222_MIC:
- alpstereo_print_identity(alpx_dev, card, "Deleted");
- break;
- case ALPX_VARIANT_MODEL_ALP882:
- case ALPX_VARIANT_MODEL_ALP882_MIC:
- case ALPX_VARIANT_MODEL_ALP442:
- case ALPX_VARIANT_MODEL_ALP442_MIC:
- if (card != NULL) {
- alpmultichan_print_identity(alpx_dev, card, "Deleted");
- }
- break;
- case ALPX_VARIANT_MODEL_MADI:
- case ALPX_VARIANT_MODEL_MADI_LOOPBACK:
- alpmadi_print_identity(alpx_dev, card, "Deleted");
- break;
- case ALPX_VARIANT_MODEL_ALPDANTE:
- alpdante_print_identity(alpx_dev, card, "Deleted");
- break;
- default:
- dev_warn(alpx_dev->dev," !!! UNKNOW variant identity: %d !!!!\n", alpx_dev->variant->model);
- }
-
- /* Reg debug */
-#ifdef WITH_REG_DEBUG
- device_remove_file(alpx_dev->dev, &dev_reg_offset);
- device_remove_file(alpx_dev->dev, &dev_reg_value);
-#endif
- device_remove_file(alpx_dev->dev, &dev_serial_number);
- device_remove_file(alpx_dev->dev, &dev_ver_fpga);
- device_remove_file(alpx_dev->dev, &dev_ver_mcu);
-
- if (alpx_dev->variant->model == ALPX_VARIANT_MODEL_ALPDANTE) {
- device_remove_file(alpx_dev->dev, &dev_dante_card_name);
- }
-
- alpx_mtd_remove(alpx_dev);
- alpx_proc_remove(alpx_dev);
-
- if (alpx_dev->xdma_pdev != NULL) {
- alpx_xdma_unregister(pci_dev, alpx_dev->xdma_pdev);
- }
-
- if (card != NULL) {
- snd_card_free(card);
- }
-
- pci_disable_device(alpx_dev->pci_dev);
-}
-
-static const struct pci_device_id alpx_pci_ids[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_DIGIGRAM, ALPX_PCI_ID_DEVICE) },
- { 0 }
-};
-
-MODULE_DEVICE_TABLE(pci, alpx_pci_ids);
-
-static struct pci_driver alpx_driver = {
- .name = KBUILD_MODNAME,
- .id_table = alpx_pci_ids,
- .probe = alpx_probe,
- .remove = alpx_remove,
-};
-
-module_pci_driver(alpx_driver);
-
-MODULE_DESCRIPTION("AlpX audio cards driver");
-MODULE_AUTHOR("Digigram Digital");
-MODULE_VERSION(ALPX_MODULE_VERSION);
-MODULE_LICENSE("GPL");