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