summaryrefslogtreecommitdiff
path: root/snd-alpx/alpx_proc.c
blob: 65d9daaf5a2ca542a226c4bc628c1cbab08fa5b4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
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;
}