xref: /openbsd-src/sys/dev/usb/utvfu.h (revision 94e909e9a88cc27a9e972d987cb4d91a18fbcaf7)
1*94e909e9Smglocker /*	$OpenBSD: utvfu.h,v 1.6 2025/01/12 16:39:39 mglocker Exp $ */
2181d57e0Smglocker /*
3181d57e0Smglocker  * Copyright (c) 2013 Lubomir Rintel
4181d57e0Smglocker  * All rights reserved.
5181d57e0Smglocker  *
6181d57e0Smglocker  * Redistribution and use in source and binary forms, with or without
7181d57e0Smglocker  * modification, are permitted provided that the following conditions
8181d57e0Smglocker  * are met:
9181d57e0Smglocker  * 1. Redistributions of source code must retain the above copyright
10181d57e0Smglocker  *    notice, this list of conditions, and the following disclaimer,
11181d57e0Smglocker  *    without modification.
12181d57e0Smglocker  * 2. The name of the author may not be used to endorse or promote products
13181d57e0Smglocker  *    derived from this software without specific prior written permission.
14181d57e0Smglocker  *
15181d57e0Smglocker  * Alternatively, this software may be distributed under the terms of the
16181d57e0Smglocker  * GNU General Public License ("GPL").
17181d57e0Smglocker  *
18181d57e0Smglocker  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19181d57e0Smglocker  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20181d57e0Smglocker  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21181d57e0Smglocker  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22181d57e0Smglocker  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23181d57e0Smglocker  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24181d57e0Smglocker  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25181d57e0Smglocker  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26181d57e0Smglocker  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27181d57e0Smglocker  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28181d57e0Smglocker  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29181d57e0Smglocker  */
30181d57e0Smglocker /*
31181d57e0Smglocker  * Fushicai USBTV007 Audio-Video Grabber Driver
32181d57e0Smglocker  *
33181d57e0Smglocker  * Product web site:
34181d57e0Smglocker  * http://www.fushicai.com/products_detail/&productId=d05449ee-b690-42f9-a661-aa7353894bed.html
35181d57e0Smglocker  *
36181d57e0Smglocker  * No physical hardware was harmed running Windows during the
37181d57e0Smglocker  * reverse-engineering activity
38181d57e0Smglocker  */
39181d57e0Smglocker 
40181d57e0Smglocker #ifndef _UTVFU_H_
41181d57e0Smglocker #define _UTVFU_H_
42181d57e0Smglocker 
43181d57e0Smglocker #include <sys/rwlock.h>
44181d57e0Smglocker #include <sys/queue.h>
45*94e909e9Smglocker #include <sys/audioio.h>
46181d57e0Smglocker #include <sys/videoio.h>
47181d57e0Smglocker 
48181d57e0Smglocker /* Hardware. */
49181d57e0Smglocker #define UTVFU_VIDEO_ENDP	0x81
50181d57e0Smglocker #define UTVFU_AUDIO_ENDP	0x83
51181d57e0Smglocker #define UTVFU_BASE		0xc000
52181d57e0Smglocker #define UTVFU_REQUEST_REG	12
53181d57e0Smglocker 
54181d57e0Smglocker #define UTVFU_DFLT_IFACE_IDX	0
55181d57e0Smglocker #define UTVFU_ALT_IFACE_IDX	1
56181d57e0Smglocker 
57181d57e0Smglocker /*
58181d57e0Smglocker  * Number of concurrent isochronous urbs submitted.
59181d57e0Smglocker  * Higher numbers was seen to overly saturate the USB bus.
60181d57e0Smglocker  */
610712c17eSmglocker #define UTVFU_ISOC_TRANSFERS	3
62181d57e0Smglocker 
63181d57e0Smglocker #define UTVFU_CHUNK_SIZE	256
64181d57e0Smglocker #define UTVFU_CHUNK		240
65181d57e0Smglocker 
66181d57e0Smglocker #define UTVFU_AUDIO_URBSIZE	20480
67181d57e0Smglocker #define UTVFU_AUDIO_HDRSIZE	4
68181d57e0Smglocker #define UTVFU_AUDIO_BUFFER	65536
69181d57e0Smglocker 
70181d57e0Smglocker #define UTVFU_COMPOSITE_INPUT	0
71181d57e0Smglocker #define UTVFU_SVIDEO_INPUT	1
72181d57e0Smglocker 
73181d57e0Smglocker /* Chunk header. */
74181d57e0Smglocker #define UTVFU_MAGIC(hdr)	 (hdr & 0xff000000U)
75181d57e0Smglocker #define UTVFU_MAGIC_OK(hdr)	((hdr & 0xff000000U) == 0x88000000U)
76181d57e0Smglocker #define UTVFU_FRAME_ID(hdr)	((hdr & 0x00ff0000U) >> 16)
77181d57e0Smglocker #define UTVFU_ODD(hdr)		((hdr & 0x0000f000U) >> 15)
78181d57e0Smglocker #define UTVFU_CHUNK_NO(hdr)	 (hdr & 0x00000fffU)
79181d57e0Smglocker 
80181d57e0Smglocker #define UTVFU_TV_STD		(V4L2_STD_525_60 | V4L2_STD_PAL)
81181d57e0Smglocker 
82181d57e0Smglocker /* parameters for supported TV norms */
83181d57e0Smglocker struct utvfu_norm_params {
84181d57e0Smglocker 	v4l2_std_id	norm;
85181d57e0Smglocker 	int		cap_width;
86181d57e0Smglocker 	int		cap_height;
87181d57e0Smglocker 	int		frame_len;
88181d57e0Smglocker };
89181d57e0Smglocker 
90181d57e0Smglocker #define UTVFU_MAX_BUFFERS	32
91181d57e0Smglocker struct utvfu_mmap {
92181d57e0Smglocker 	SIMPLEQ_ENTRY(utvfu_mmap)	q_frames;
93181d57e0Smglocker 	uint8_t				*buf;
94181d57e0Smglocker 	struct v4l2_buffer		v4l2_buf;
95181d57e0Smglocker };
96181d57e0Smglocker typedef SIMPLEQ_HEAD(, utvfu_mmap)	q_mmap;
97181d57e0Smglocker 
98181d57e0Smglocker struct utvfu_frame_buf {
99181d57e0Smglocker 	uint		off;
100181d57e0Smglocker 	uint		size;
101181d57e0Smglocker 	uint16_t	chunks_done;
102181d57e0Smglocker 	uint8_t		fid;
103181d57e0Smglocker 	uint8_t		last_odd;
104181d57e0Smglocker 	uint8_t		*buf;
105181d57e0Smglocker };
106181d57e0Smglocker 
107181d57e0Smglocker #define UTVFU_NFRAMES_MAX	40
108181d57e0Smglocker struct utvfu_isoc_xfer {
109181d57e0Smglocker 	struct utvfu_softc	*sc;
110181d57e0Smglocker 	struct usbd_xfer	*xfer;
111181d57e0Smglocker 	uint16_t		size[UTVFU_NFRAMES_MAX];
112181d57e0Smglocker };
113181d57e0Smglocker 
114181d57e0Smglocker struct utvfu_vs_iface {
115181d57e0Smglocker 	struct usbd_pipe	*pipeh;
116181d57e0Smglocker 	uint32_t		psize;
117181d57e0Smglocker 	struct utvfu_isoc_xfer	ixfer[UTVFU_ISOC_TRANSFERS];
118181d57e0Smglocker };
119181d57e0Smglocker 
120181d57e0Smglocker struct utvfu_as_iface {
121181d57e0Smglocker 	struct usbd_pipe	*pipeh;
122181d57e0Smglocker 	struct usbd_xfer	*xfer;
123181d57e0Smglocker };
124181d57e0Smglocker 
125181d57e0Smglocker struct utvfu_audio_chan {
126181d57e0Smglocker 	uint8_t			*start;
127181d57e0Smglocker 	uint8_t			*end;
128181d57e0Smglocker 	uint8_t			*cur;
129181d57e0Smglocker 	int			blksize;
130181d57e0Smglocker 	void			*intr_arg;
131181d57e0Smglocker 	void			(*intr)(void *);
132181d57e0Smglocker 	struct utvfu_as_iface	iface;
133181d57e0Smglocker 	struct rwlock		rwlock;
134181d57e0Smglocker };
135181d57e0Smglocker 
136181d57e0Smglocker /* Per-device structure. */
137181d57e0Smglocker struct utvfu_softc {
138181d57e0Smglocker 	struct device		sc_dev;
139181d57e0Smglocker 	struct usbd_device	*sc_udev;
140181d57e0Smglocker 	struct usbd_interface	*sc_uifaceh;
141181d57e0Smglocker 
142181d57e0Smglocker 	/* audio & video device */
143181d57e0Smglocker 	struct device		*sc_audiodev;
144181d57e0Smglocker 	struct device		*sc_videodev;
145181d57e0Smglocker 
146181d57e0Smglocker 	int			sc_flags;
147ef70e76aSmglocker #define UTVFU_FLAG_MMAP		0x01
148ef70e76aSmglocker #define UTVFU_FLAG_AS_RUNNING	0x02
149181d57e0Smglocker 
150181d57e0Smglocker 	int			sc_normi;
151181d57e0Smglocker 	int			sc_nchunks;
152181d57e0Smglocker 	int			sc_input;
153181d57e0Smglocker 	int			sc_max_frame_sz;
154181d57e0Smglocker 	int			sc_nframes;
155181d57e0Smglocker 
156181d57e0Smglocker 	struct utvfu_vs_iface	sc_iface;
157181d57e0Smglocker 	struct utvfu_frame_buf	sc_fb;
158181d57e0Smglocker 
159181d57e0Smglocker 	struct utvfu_audio_chan	sc_audio;
160181d57e0Smglocker 
161181d57e0Smglocker 	/* mmap */
162181d57e0Smglocker 	struct utvfu_mmap	sc_mmap[UTVFU_MAX_BUFFERS];
163181d57e0Smglocker 	uint8_t			*sc_mmap_buffer;
164181d57e0Smglocker 	q_mmap			sc_mmap_q;
165181d57e0Smglocker 	int			sc_mmap_bufsz;
166181d57e0Smglocker 	int			sc_mmap_count;
167181d57e0Smglocker 
168181d57e0Smglocker 	/* uplayer */
169181d57e0Smglocker 	void			*sc_uplayer_arg;
170181d57e0Smglocker 	int			*sc_uplayer_fsize;
171181d57e0Smglocker 	uint8_t			*sc_uplayer_fbuffer;
172181d57e0Smglocker 	void			(*sc_uplayer_intr)(void *);
173181d57e0Smglocker };
174181d57e0Smglocker 
175181d57e0Smglocker int	utvfu_max_frame_size(void);
176181d57e0Smglocker int	utvfu_set_regs(struct utvfu_softc *, const uint16_t regs[][2], int);
177181d57e0Smglocker void	utvfu_image_chunk(struct utvfu_softc *, u_char *);
178181d57e0Smglocker int	utvfu_configure_for_norm(struct utvfu_softc *, v4l2_std_id);
179181d57e0Smglocker int	utvfu_start_capture(struct utvfu_softc *);
180181d57e0Smglocker int	utvfu_mmap_queue(struct utvfu_softc *, uint8_t *, int);
181181d57e0Smglocker void	utvfu_read(struct utvfu_softc *, uint8_t *, int);
182181d57e0Smglocker 
183181d57e0Smglocker void	utvfu_audio_decode(struct utvfu_softc *, int);
184181d57e0Smglocker int	utvfu_audio_start(struct utvfu_softc *);
185181d57e0Smglocker int	utvfu_audio_stop(struct utvfu_softc *);
186181d57e0Smglocker int	utvfu_audio_start_chip(struct utvfu_softc *);
187181d57e0Smglocker int	utvfu_audio_stop_chip(struct utvfu_softc *);
188181d57e0Smglocker 
189181d57e0Smglocker #endif
190