diff options
author | Christian Pointner <equinox@helsinki.at> | 2024-05-10 18:56:00 (GMT) |
---|---|---|
committer | Christian Pointner <equinox@helsinki.at> | 2024-05-10 18:56:00 (GMT) |
commit | af6bfbbd2496b1f5aa02b94caff4e6f988fa32c9 (patch) | |
tree | 45bebb68a0bf3bfc2fff1646f6fa0f4b976fba57 /snd-alpx-dkms/snd-alpx/alpx_proc.c | |
parent | 7035064ca063fdf15669ceb790ecef1e5ed054b0 (diff) |
rename package to snd-alpx-dkms
Diffstat (limited to 'snd-alpx-dkms/snd-alpx/alpx_proc.c')
-rw-r--r-- | snd-alpx-dkms/snd-alpx/alpx_proc.c | 116 |
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; +} |