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