1/*	$OpenBSD: utvfu.h,v 1.5 2021/11/24 22:03:05 mglocker Exp $ */
2/*
3 * Copyright (c) 2013 Lubomir Rintel
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions, and the following disclaimer,
11 *    without modification.
12 * 2. The name of the author may not be used to endorse or promote products
13 *    derived from this software without specific prior written permission.
14 *
15 * Alternatively, this software may be distributed under the terms of the
16 * GNU General Public License ("GPL").
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30/*
31 * Fushicai USBTV007 Audio-Video Grabber Driver
32 *
33 * Product web site:
34 * http://www.fushicai.com/products_detail/&productId=d05449ee-b690-42f9-a661-aa7353894bed.html
35 *
36 * No physical hardware was harmed running Windows during the
37 * reverse-engineering activity
38 */
39
40#ifndef _UTVFU_H_
41#define _UTVFU_H_
42
43#include <sys/rwlock.h>
44#include <sys/queue.h>
45#include <sys/videoio.h>
46
47/* Hardware. */
48#define UTVFU_VIDEO_ENDP	0x81
49#define UTVFU_AUDIO_ENDP	0x83
50#define UTVFU_BASE		0xc000
51#define UTVFU_REQUEST_REG	12
52
53#define UTVFU_DFLT_IFACE_IDX	0
54#define UTVFU_ALT_IFACE_IDX	1
55
56/*
57 * Number of concurrent isochronous urbs submitted.
58 * Higher numbers was seen to overly saturate the USB bus.
59 */
60#define UTVFU_ISOC_TRANSFERS	3
61
62#define UTVFU_CHUNK_SIZE	256
63#define UTVFU_CHUNK		240
64
65#define UTVFU_AUDIO_URBSIZE	20480
66#define UTVFU_AUDIO_HDRSIZE	4
67#define UTVFU_AUDIO_BUFFER	65536
68
69#define UTVFU_COMPOSITE_INPUT	0
70#define UTVFU_SVIDEO_INPUT	1
71
72/* Chunk header. */
73#define UTVFU_MAGIC(hdr)	 (hdr & 0xff000000U)
74#define UTVFU_MAGIC_OK(hdr)	((hdr & 0xff000000U) == 0x88000000U)
75#define UTVFU_FRAME_ID(hdr)	((hdr & 0x00ff0000U) >> 16)
76#define UTVFU_ODD(hdr)		((hdr & 0x0000f000U) >> 15)
77#define UTVFU_CHUNK_NO(hdr)	 (hdr & 0x00000fffU)
78
79#define UTVFU_TV_STD		(V4L2_STD_525_60 | V4L2_STD_PAL)
80
81/* parameters for supported TV norms */
82struct utvfu_norm_params {
83	v4l2_std_id	norm;
84	int		cap_width;
85	int		cap_height;
86	int		frame_len;
87};
88
89#define UTVFU_MAX_BUFFERS	32
90struct utvfu_mmap {
91	SIMPLEQ_ENTRY(utvfu_mmap)	q_frames;
92	uint8_t				*buf;
93	struct v4l2_buffer		v4l2_buf;
94};
95typedef SIMPLEQ_HEAD(, utvfu_mmap)	q_mmap;
96
97struct utvfu_frame_buf {
98	uint		off;
99	uint		size;
100	uint16_t	chunks_done;
101	uint8_t		fid;
102	uint8_t		last_odd;
103	uint8_t		*buf;
104};
105
106#define UTVFU_NFRAMES_MAX	40
107struct utvfu_isoc_xfer {
108	struct utvfu_softc	*sc;
109	struct usbd_xfer	*xfer;
110	uint16_t		size[UTVFU_NFRAMES_MAX];
111};
112
113struct utvfu_vs_iface {
114	struct usbd_pipe	*pipeh;
115	uint32_t		psize;
116	struct utvfu_isoc_xfer	ixfer[UTVFU_ISOC_TRANSFERS];
117};
118
119struct utvfu_as_iface {
120	struct usbd_pipe	*pipeh;
121	struct usbd_xfer	*xfer;
122};
123
124struct utvfu_audio_chan {
125	uint8_t			*start;
126	uint8_t			*end;
127	uint8_t			*cur;
128	int			blksize;
129	void			*intr_arg;
130	void			(*intr)(void *);
131	struct utvfu_as_iface	iface;
132	struct rwlock		rwlock;
133};
134
135/* Per-device structure. */
136struct utvfu_softc {
137	struct device		sc_dev;
138	struct usbd_device	*sc_udev;
139	struct usbd_interface	*sc_uifaceh;
140
141	/* audio & video device */
142	struct device		*sc_audiodev;
143	struct device		*sc_videodev;
144
145	int			sc_flags;
146#define UTVFU_FLAG_MMAP		0x01
147#define UTVFU_FLAG_AS_RUNNING	0x02
148
149	int			sc_normi;
150	int			sc_nchunks;
151	int			sc_input;
152	int			sc_max_frame_sz;
153	int			sc_nframes;
154
155	struct utvfu_vs_iface	sc_iface;
156	struct utvfu_frame_buf	sc_fb;
157
158	struct utvfu_audio_chan	sc_audio;
159
160	/* mmap */
161	struct utvfu_mmap	sc_mmap[UTVFU_MAX_BUFFERS];
162	uint8_t			*sc_mmap_buffer;
163	q_mmap			sc_mmap_q;
164	int			sc_mmap_bufsz;
165	int			sc_mmap_count;
166
167	/* uplayer */
168	void			*sc_uplayer_arg;
169	int			*sc_uplayer_fsize;
170	uint8_t			*sc_uplayer_fbuffer;
171	void			(*sc_uplayer_intr)(void *);
172};
173
174int	utvfu_max_frame_size(void);
175int	utvfu_set_regs(struct utvfu_softc *, const uint16_t regs[][2], int);
176void	utvfu_image_chunk(struct utvfu_softc *, u_char *);
177int	utvfu_configure_for_norm(struct utvfu_softc *, v4l2_std_id);
178int	utvfu_start_capture(struct utvfu_softc *);
179int	utvfu_mmap_queue(struct utvfu_softc *, uint8_t *, int);
180void	utvfu_read(struct utvfu_softc *, uint8_t *, int);
181
182void	utvfu_audio_decode(struct utvfu_softc *, int);
183int	utvfu_audio_start(struct utvfu_softc *);
184int	utvfu_audio_stop(struct utvfu_softc *);
185int	utvfu_audio_start_chip(struct utvfu_softc *);
186int	utvfu_audio_stop_chip(struct utvfu_softc *);
187
188#endif
189