summaryrefslogtreecommitdiff
path: root/snd-alpx-dkms/snd-alpx/alpx_proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'snd-alpx-dkms/snd-alpx/alpx_proc.c')
-rw-r--r--snd-alpx-dkms/snd-alpx/alpx_proc.c116
1 files changed, 116 insertions, 0 deletions
diff --git a/snd-alpx-dkms/snd-alpx/alpx_proc.c b/snd-alpx-dkms/snd-alpx/alpx_proc.c
new file mode 100644
index 0000000..65d9daa
--- /dev/null
+++ b/snd-alpx-dkms/snd-alpx/alpx_proc.c
@@ -0,0 +1,116 @@
+// 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_proc.h"
+
+#if defined(CONFIG_ALPX_WITH_PROC_LOG)
+int alpx_proc_log_dump(struct alpx_device *alpx_dev)
+{
+ static unsigned char log_buffer[ALP_PROC_LOG_LENGTH];
+ unsigned char logged_word = 0;
+ unsigned int addr = 0;
+ //unsigned int idx = 0;
+ struct alpx_device zero_base;
+ zero_base.base = 0;
+
+
+ dev_dbg( alpx_dev->dev,"%s(): uBlaze Log (%d):", __func__, ALP_PROC_LOG_LENGTH);
+
+ for (addr = 0; addr < ALP_PROC_LOG_LENGTH ; addr += sizeof (u32)) {
+#if 0
+ dev_dbg( alpx_dev->dev,"%s() : log reg: %p + 0x%x => %p\n", __func__,
+ alpx_dev->base,
+ ALP_PROC_LOG_BASE + addr,
+ ALPX_AREA(alpx_dev, ALP, PROC_LOG) + addr);
+#endif
+ logged_word = readl(ALPX_AREA(alpx_dev, ALP, PROC_LOG) + addr);
+ *(unsigned int*)&log_buffer[addr] = logged_word;
+#if 0
+ dev_dbg( alpx_dev->dev,"%s() : [0x%x] =>%d\n", __func__,
+ ALP_PROC_LOG_BASE + addr,
+ logged_word);
+#endif
+
+#if 0
+ for (idx = 0 ; idx < sizeof(u32) ; ++idx) {
+ printk("%c",(unsigned char)logged_word);
+ logged_word >>= 8;
+ }
+#endif
+print_hex_dump_bytes(alpx_dev->dev,"LOG", DUMP_PREFIX_NONE,
+ log_buffer, ALP_PROC_LOG_LENGTH);
+ }
+
+ return 0;
+}
+#endif
+
+int alpx_proc_cmd(struct alpx_device *alpx_dev, u32 command)
+{
+ u32 status;
+ u32 fails;
+ int ret;
+
+ /* Set status to detect proc register update */
+ writel(0xFFFFFFFF, ALPX_REG(alpx_dev, ALP, PROC, STATUS));
+
+ /* Post command */
+ writel(command, ALPX_REG(alpx_dev, ALP, PROC, COMMAND));
+
+ /* Poll status for first update */
+ ret = readl_poll_timeout(ALPX_REG(alpx_dev, ALP, PROC, STATUS),
+ status, status != 0xFFFFFFFF, 10, 1000000);
+ if (ret) {
+ dev_err(alpx_dev->dev, "cmd 0x%08X timeout (status=%x)\n",
+ command, status);
+ alpx_proc_log_dump(alpx_dev);
+ return ret;
+ }
+
+ /* Continue polling for end of processing */
+ ret = readl_poll_timeout(ALPX_REG(alpx_dev, ALP, PROC, STATUS),
+ status, !(status & ALP_PROC_STATUS_PENDING),
+ 10, 1000000);
+ if (ret) {
+ dev_err(alpx_dev->dev, "cmd 0x%08X timeout (status=%x)\n",
+ command, status);
+ alpx_proc_log_dump(alpx_dev);
+ return ret;
+ }
+
+ mdelay(1);
+
+ /* Command processing is done -> check results */
+ status = readl(ALPX_REG(alpx_dev, ALP, PROC, STATUS));
+ fails = readl(ALPX_REG(alpx_dev, ALP, PROC, FAILS));
+
+ dev_dbg(alpx_dev->dev,"cmd 0x%08X => status: 0x%x, fail:0x%x\n", command, status, fails);
+
+ if ((status & ALP_PROC_STATUS_FAIL) &&
+ (fails != ALP_PROC_FAILS_FAIL_NONE)) {
+ dev_err(alpx_dev->dev, "cmd 0x%08X failed (status=%x, fails=%x)\n",
+ command, status, fails);
+ alpx_proc_log_dump(alpx_dev);
+ return -EIO;
+ }
+
+ alpx_proc_log_dump(alpx_dev);
+
+ return 0;
+}
+
+int alpx_proc_probe(struct alpx_device *alpx_dev)
+{
+ mutex_init(&alpx_dev->proc_mutex);
+ return 0;
+}
+
+int alpx_proc_remove(struct alpx_device *alpx_dev)
+{
+ mutex_destroy(&alpx_dev->proc_mutex);
+ return 0;
+}