1232337Smav/*-
2232337Smav * Copyright (c) 2012 Ruslan Bukin <br@bsdpad.com>
3232337Smav * All rights reserved.
4232337Smav *
5232337Smav * Redistribution and use in source and binary forms, with or without
6232337Smav * modification, are permitted provided that the following conditions
7232337Smav * are met:
8232337Smav * 1. Redistributions of source code must retain the above copyright
9232337Smav *    notice, this list of conditions and the following disclaimer.
10232337Smav * 2. Redistributions in binary form must reproduce the above copyright
11232337Smav *    notice, this list of conditions and the following disclaimer in the
12232337Smav *    documentation and/or other materials provided with the distribution.
13232337Smav *
14232337Smav * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15232337Smav * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16232337Smav * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17232337Smav * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18232337Smav * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19232337Smav * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20232337Smav * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21232337Smav * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22232337Smav * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23232337Smav * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24232337Smav * SUCH DAMAGE.
25232337Smav *
26232337Smav * $FreeBSD$
27232337Smav */
28232337Smav
29232337Smav#define PCI_VENDOR_XILINX		0x10ee
30232337Smav#define PCI_DEVICE_XILINX_HDSPE		0x3fc6 /* AIO, MADI, AES, RayDAT */
31232337Smav#define PCI_CLASS_REVISION		0x08
32232337Smav#define PCI_REVISION_AIO		212
33232337Smav#define PCI_REVISION_RAYDAT		211
34232337Smav
35232337Smav#define AIO				0
36232337Smav#define RAYDAT				1
37232337Smav
38232337Smav/* Hardware mixer */
39232337Smav#define HDSPE_OUT_ENABLE_BASE		512
40232337Smav#define HDSPE_IN_ENABLE_BASE		768
41232337Smav#define HDSPE_MIXER_BASE		32768
42232337Smav#define HDSPE_MAX_GAIN			32768
43232337Smav
44232337Smav/* Buffer */
45232337Smav#define HDSPE_PAGE_ADDR_BUF_OUT		8192
46232337Smav#define HDSPE_PAGE_ADDR_BUF_IN		(HDSPE_PAGE_ADDR_BUF_OUT + 64 * 16 * 4)
47232337Smav#define HDSPE_BUF_POSITION_MASK		0x000FFC0
48232337Smav
49232337Smav/* Frequency */
50232337Smav#define HDSPE_FREQ_0			(1<<6)
51232337Smav#define HDSPE_FREQ_1			(1<<7)
52232337Smav#define HDSPE_FREQ_DOUBLE		(1<<8)
53232337Smav#define HDSPE_FREQ_QUAD			(1<<31)
54232337Smav
55232337Smav#define HDSPE_FREQ_32000		HDSPE_FREQ_0
56232337Smav#define HDSPE_FREQ_44100		HDSPE_FREQ_1
57232337Smav#define HDSPE_FREQ_48000		(HDSPE_FREQ_0 | HDSPE_FREQ_1)
58232337Smav#define HDSPE_FREQ_MASK			(HDSPE_FREQ_0 | HDSPE_FREQ_1 |	\
59232337Smav					HDSPE_FREQ_DOUBLE | HDSPE_FREQ_QUAD)
60232337Smav#define HDSPE_FREQ_MASK_DEFAULT		HDSPE_FREQ_48000
61232337Smav#define HDSPE_FREQ_REG			256
62232337Smav#define HDSPE_FREQ_AIO			104857600000000ULL
63232337Smav
64232337Smav#define HDSPE_SPEED_DEFAULT		48000
65232337Smav
66232337Smav/* Latency */
67232337Smav#define HDSPE_LAT_0			(1<<1)
68232337Smav#define HDSPE_LAT_1			(1<<2)
69232337Smav#define HDSPE_LAT_2			(1<<3)
70232337Smav#define HDSPE_LAT_MASK			(HDSPE_LAT_0 | HDSPE_LAT_1 | HDSPE_LAT_2)
71232337Smav#define HDSPE_LAT_BYTES_MAX		(4096 * 4)
72232337Smav#define HDSPE_LAT_BYTES_MIN		(32 * 4)
73232337Smav#define hdspe_encode_latency(x)		(((x)<<1) & HDSPE_LAT_MASK)
74232337Smav
75232337Smav/* Settings */
76232337Smav#define HDSPE_SETTINGS_REG		0
77232337Smav#define HDSPE_CONTROL_REG		64
78232337Smav#define HDSPE_STATUS_REG		0
79232337Smav#define HDSPE_ENABLE			(1<<0)
80232337Smav#define HDSPM_CLOCK_MODE_MASTER		(1<<4)
81232337Smav
82232337Smav/* Interrupts */
83232337Smav#define HDSPE_AUDIO_IRQ_PENDING		(1<<0)
84232337Smav#define HDSPE_AUDIO_INT_ENABLE		(1<<5)
85232337Smav#define HDSPE_INTERRUPT_ACK		96
86232337Smav
87232337Smav/* Channels */
88232337Smav#define HDSPE_MAX_SLOTS			64 /* Mono channels */
89232337Smav#define HDSPE_MAX_CHANS			(HDSPE_MAX_SLOTS / 2) /* Stereo pairs */
90232337Smav
91232337Smav#define HDSPE_CHANBUF_SAMPLES		(16 * 1024)
92232337Smav#define HDSPE_CHANBUF_SIZE		(4 * HDSPE_CHANBUF_SAMPLES)
93232337Smav#define HDSPE_DMASEGSIZE		(HDSPE_CHANBUF_SIZE * HDSPE_MAX_SLOTS)
94232337Smav
95232337Smavstruct hdspe_channel {
96232337Smav	uint32_t	left;
97232337Smav	uint32_t	right;
98232337Smav	char		*descr;
99232337Smav	uint32_t	play;
100232337Smav	uint32_t	rec;
101232337Smav};
102232337Smav
103232337Smavstatic MALLOC_DEFINE(M_HDSPE, "hdspe", "hdspe audio");
104232337Smav
105232337Smav/* Channel registers */
106232337Smavstruct sc_chinfo {
107232337Smav	struct snd_dbuf		*buffer;
108232337Smav	struct pcm_channel	*channel;
109232337Smav	struct sc_pcminfo	*parent;
110232337Smav
111232337Smav	/* Channel information */
112232337Smav	uint32_t	dir;
113232337Smav	uint32_t	format;
114232337Smav	uint32_t	lslot;
115232337Smav	uint32_t	rslot;
116232337Smav	uint32_t	lvol;
117232337Smav	uint32_t	rvol;
118232337Smav
119232337Smav	/* Buffer */
120232337Smav	uint32_t	*data;
121232337Smav	uint32_t	size;
122232337Smav
123232337Smav	/* Flags */
124232337Smav	uint32_t	run;
125232337Smav};
126232337Smav
127232337Smav/* PCM device private data */
128232337Smavstruct sc_pcminfo {
129232337Smav	device_t		dev;
130232337Smav	uint32_t		(*ih) (struct sc_pcminfo *scp);
131232337Smav	uint32_t		chnum;
132232337Smav	struct sc_chinfo	chan[HDSPE_MAX_CHANS];
133232337Smav	struct sc_info		*sc;
134232337Smav	struct hdspe_channel	*hc;
135232337Smav};
136232337Smav
137232337Smav/* HDSPe device private data */
138232337Smavstruct sc_info {
139232337Smav	device_t		dev;
140232337Smav	struct mtx		*lock;
141232337Smav
142232337Smav	uint32_t		ctrl_register;
143232337Smav	uint32_t		settings_register;
144232337Smav	uint32_t		type;
145232337Smav
146232337Smav	/* Control/Status register */
147232337Smav	struct resource		*cs;
148232337Smav	int			csid;
149232337Smav	bus_space_tag_t		cst;
150232337Smav	bus_space_handle_t	csh;
151232337Smav
152232337Smav	struct resource		*irq;
153232337Smav	int			irqid;
154232337Smav	void			*ih;
155232337Smav	bus_dma_tag_t		dmat;
156232337Smav
157232337Smav	/* Play/Record DMA buffers */
158232337Smav	uint32_t		*pbuf;
159232337Smav	uint32_t		*rbuf;
160232337Smav	uint32_t		bufsize;
161232337Smav	bus_dmamap_t		pmap;
162232337Smav	bus_dmamap_t		rmap;
163232337Smav	uint32_t		period;
164232337Smav	uint32_t		speed;
165232337Smav};
166232337Smav
167232337Smav#define hdspe_read_1(sc, regno)						\
168232337Smav	bus_space_read_1((sc)->cst, (sc)->csh, (regno))
169232337Smav#define hdspe_read_2(sc, regno)						\
170232337Smav	bus_space_read_2((sc)->cst, (sc)->csh, (regno))
171232337Smav#define hdspe_read_4(sc, regno)						\
172232337Smav	bus_space_read_4((sc)->cst, (sc)->csh, (regno))
173232337Smav
174232337Smav#define hdspe_write_1(sc, regno, data)					\
175232337Smav	bus_space_write_1((sc)->cst, (sc)->csh, (regno), (data))
176232337Smav#define hdspe_write_2(sc, regno, data)					\
177232337Smav	bus_space_write_2((sc)->cst, (sc)->csh, (regno), (data))
178232337Smav#define hdspe_write_4(sc, regno, data)					\
179232337Smav	bus_space_write_4((sc)->cst, (sc)->csh, (regno), (data))
180