hdspe.h revision 330897
1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2012-2016 Ruslan Bukin <br@bsdpad.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 * $FreeBSD: stable/11/sys/dev/sound/pci/hdspe.h 330897 2018-03-14 03:19:51Z eadler $
29 */
30
31#define	PCI_VENDOR_XILINX		0x10ee
32#define	PCI_DEVICE_XILINX_HDSPE		0x3fc6 /* AIO, MADI, AES, RayDAT */
33#define	PCI_CLASS_REVISION		0x08
34#define	PCI_REVISION_AIO		212
35#define	PCI_REVISION_RAYDAT		211
36
37#define	AIO				0
38#define	RAYDAT				1
39
40/* Hardware mixer */
41#define	HDSPE_OUT_ENABLE_BASE		512
42#define	HDSPE_IN_ENABLE_BASE		768
43#define	HDSPE_MIXER_BASE		32768
44#define	HDSPE_MAX_GAIN			32768
45
46/* Buffer */
47#define	HDSPE_PAGE_ADDR_BUF_OUT		8192
48#define	HDSPE_PAGE_ADDR_BUF_IN		(HDSPE_PAGE_ADDR_BUF_OUT + 64 * 16 * 4)
49#define	HDSPE_BUF_POSITION_MASK		0x000FFC0
50
51/* Frequency */
52#define	HDSPE_FREQ_0			(1 << 6)
53#define	HDSPE_FREQ_1			(1 << 7)
54#define	HDSPE_FREQ_DOUBLE		(1 << 8)
55#define	HDSPE_FREQ_QUAD			(1 << 31)
56
57#define	HDSPE_FREQ_32000		HDSPE_FREQ_0
58#define	HDSPE_FREQ_44100		HDSPE_FREQ_1
59#define	HDSPE_FREQ_48000		(HDSPE_FREQ_0 | HDSPE_FREQ_1)
60#define	HDSPE_FREQ_MASK			(HDSPE_FREQ_0 | HDSPE_FREQ_1 |	\
61					HDSPE_FREQ_DOUBLE | HDSPE_FREQ_QUAD)
62#define	HDSPE_FREQ_MASK_DEFAULT		HDSPE_FREQ_48000
63#define	HDSPE_FREQ_REG			256
64#define	HDSPE_FREQ_AIO			104857600000000ULL
65
66#define	HDSPE_SPEED_DEFAULT		48000
67
68/* Latency */
69#define	HDSPE_LAT_0			(1 << 1)
70#define	HDSPE_LAT_1			(1 << 2)
71#define	HDSPE_LAT_2			(1 << 3)
72#define	HDSPE_LAT_MASK			(HDSPE_LAT_0 | HDSPE_LAT_1 | HDSPE_LAT_2)
73#define	HDSPE_LAT_BYTES_MAX		(4096 * 4)
74#define	HDSPE_LAT_BYTES_MIN		(32 * 4)
75#define	hdspe_encode_latency(x)		(((x)<<1) & HDSPE_LAT_MASK)
76
77/* Gain */
78#define	HDSP_ADGain0			(1 << 25)
79#define	HDSP_ADGain1			(1 << 26)
80#define	HDSP_DAGain0			(1 << 27)
81#define	HDSP_DAGain1			(1 << 28)
82#define	HDSP_PhoneGain0			(1 << 29)
83#define	HDSP_PhoneGain1			(1 << 30)
84
85#define	HDSP_ADGainMask			(HDSP_ADGain0 | HDSP_ADGain1)
86#define	HDSP_ADGainMinus10dBV		(HDSP_ADGainMask)
87#define	HDSP_ADGainPlus4dBu		(HDSP_ADGain0)
88#define	HDSP_ADGainLowGain		0
89
90#define	HDSP_DAGainMask			(HDSP_DAGain0 | HDSP_DAGain1)
91#define	HDSP_DAGainHighGain		(HDSP_DAGainMask)
92#define	HDSP_DAGainPlus4dBu		(HDSP_DAGain0)
93#define	HDSP_DAGainMinus10dBV		0
94
95#define	HDSP_PhoneGainMask		(HDSP_PhoneGain0|HDSP_PhoneGain1)
96#define	HDSP_PhoneGain0dB		HDSP_PhoneGainMask
97#define	HDSP_PhoneGainMinus6dB		(HDSP_PhoneGain0)
98#define	HDSP_PhoneGainMinus12dB		0
99
100#define	HDSPM_statusRegister		0
101#define	HDSPM_statusRegister2		192
102
103/* Settings */
104#define	HDSPE_SETTINGS_REG		0
105#define	HDSPE_CONTROL_REG		64
106#define	HDSPE_STATUS_REG		0
107#define	HDSPE_ENABLE			(1 << 0)
108#define	HDSPM_CLOCK_MODE_MASTER		(1 << 4)
109
110/* Interrupts */
111#define	HDSPE_AUDIO_IRQ_PENDING		(1 << 0)
112#define	HDSPE_AUDIO_INT_ENABLE		(1 << 5)
113#define	HDSPE_INTERRUPT_ACK		96
114
115/* Channels */
116#define	HDSPE_MAX_SLOTS			64 /* Mono channels */
117#define	HDSPE_MAX_CHANS			(HDSPE_MAX_SLOTS / 2) /* Stereo pairs */
118
119#define	HDSPE_CHANBUF_SAMPLES		(16 * 1024)
120#define	HDSPE_CHANBUF_SIZE		(4 * HDSPE_CHANBUF_SAMPLES)
121#define	HDSPE_DMASEGSIZE		(HDSPE_CHANBUF_SIZE * HDSPE_MAX_SLOTS)
122
123struct hdspe_channel {
124	uint32_t	left;
125	uint32_t	right;
126	char		*descr;
127	uint32_t	play;
128	uint32_t	rec;
129};
130
131static MALLOC_DEFINE(M_HDSPE, "hdspe", "hdspe audio");
132
133/* Channel registers */
134struct sc_chinfo {
135	struct snd_dbuf		*buffer;
136	struct pcm_channel	*channel;
137	struct sc_pcminfo	*parent;
138
139	/* Channel information */
140	uint32_t	dir;
141	uint32_t	format;
142	uint32_t	lslot;
143	uint32_t	rslot;
144	uint32_t	lvol;
145	uint32_t	rvol;
146
147	/* Buffer */
148	uint32_t	*data;
149	uint32_t	size;
150
151	/* Flags */
152	uint32_t	run;
153};
154
155/* PCM device private data */
156struct sc_pcminfo {
157	device_t		dev;
158	uint32_t		(*ih) (struct sc_pcminfo *scp);
159	uint32_t		chnum;
160	struct sc_chinfo	chan[HDSPE_MAX_CHANS];
161	struct sc_info		*sc;
162	struct hdspe_channel	*hc;
163};
164
165/* HDSPe device private data */
166struct sc_info {
167	device_t		dev;
168	struct mtx		*lock;
169
170	uint32_t		ctrl_register;
171	uint32_t		settings_register;
172	uint32_t		type;
173
174	/* Control/Status register */
175	struct resource		*cs;
176	int			csid;
177	bus_space_tag_t		cst;
178	bus_space_handle_t	csh;
179
180	struct resource		*irq;
181	int			irqid;
182	void			*ih;
183	bus_dma_tag_t		dmat;
184
185	/* Play/Record DMA buffers */
186	uint32_t		*pbuf;
187	uint32_t		*rbuf;
188	uint32_t		bufsize;
189	bus_dmamap_t		pmap;
190	bus_dmamap_t		rmap;
191	uint32_t		period;
192	uint32_t		speed;
193};
194
195#define	hdspe_read_1(sc, regno)						\
196	bus_space_read_1((sc)->cst, (sc)->csh, (regno))
197#define	hdspe_read_2(sc, regno)						\
198	bus_space_read_2((sc)->cst, (sc)->csh, (regno))
199#define	hdspe_read_4(sc, regno)						\
200	bus_space_read_4((sc)->cst, (sc)->csh, (regno))
201
202#define	hdspe_write_1(sc, regno, data)					\
203	bus_space_write_1((sc)->cst, (sc)->csh, (regno), (data))
204#define	hdspe_write_2(sc, regno, data)					\
205	bus_space_write_2((sc)->cst, (sc)->csh, (regno), (data))
206#define	hdspe_write_4(sc, regno, data)					\
207	bus_space_write_4((sc)->cst, (sc)->csh, (regno), (data))
208