1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun * Copyright (c) 2013 Lubomir Rintel 3*4882a593Smuzhiyun * All rights reserved. 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Redistribution and use in source and binary forms, with or without 6*4882a593Smuzhiyun * modification, are permitted provided that the following conditions 7*4882a593Smuzhiyun * are met: 8*4882a593Smuzhiyun * 1. Redistributions of source code must retain the above copyright 9*4882a593Smuzhiyun * notice, this list of conditions, and the following disclaimer, 10*4882a593Smuzhiyun * without modification. 11*4882a593Smuzhiyun * 2. The name of the author may not be used to endorse or promote products 12*4882a593Smuzhiyun * derived from this software without specific prior written permission. 13*4882a593Smuzhiyun * 14*4882a593Smuzhiyun * Alternatively, this software may be distributed under the terms of the 15*4882a593Smuzhiyun * GNU General Public License ("GPL"). 16*4882a593Smuzhiyun * 17*4882a593Smuzhiyun * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18*4882a593Smuzhiyun * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19*4882a593Smuzhiyun * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20*4882a593Smuzhiyun * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21*4882a593Smuzhiyun * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22*4882a593Smuzhiyun * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23*4882a593Smuzhiyun * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24*4882a593Smuzhiyun * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25*4882a593Smuzhiyun * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26*4882a593Smuzhiyun * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27*4882a593Smuzhiyun * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28*4882a593Smuzhiyun */ 29*4882a593Smuzhiyun /* 30*4882a593Smuzhiyun * Fushicai USBTV007 Audio-Video Grabber Driver 31*4882a593Smuzhiyun * 32*4882a593Smuzhiyun * No physical hardware was harmed running Windows during the 33*4882a593Smuzhiyun * reverse-engineering activity 34*4882a593Smuzhiyun */ 35*4882a593Smuzhiyun 36*4882a593Smuzhiyun #include <linux/module.h> 37*4882a593Smuzhiyun #include <linux/slab.h> 38*4882a593Smuzhiyun #include <linux/usb.h> 39*4882a593Smuzhiyun 40*4882a593Smuzhiyun #include <media/v4l2-device.h> 41*4882a593Smuzhiyun #include <media/v4l2-ctrls.h> 42*4882a593Smuzhiyun #include <media/videobuf2-v4l2.h> 43*4882a593Smuzhiyun #include <media/videobuf2-vmalloc.h> 44*4882a593Smuzhiyun 45*4882a593Smuzhiyun /* Hardware. */ 46*4882a593Smuzhiyun #define USBTV_VIDEO_ENDP 0x81 47*4882a593Smuzhiyun #define USBTV_AUDIO_ENDP 0x83 48*4882a593Smuzhiyun #define USBTV_BASE 0xc000 49*4882a593Smuzhiyun #define USBTV_CONTROL_REG 11 50*4882a593Smuzhiyun #define USBTV_REQUEST_REG 12 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun /* Number of concurrent isochronous urbs submitted. 53*4882a593Smuzhiyun * Higher numbers was seen to overly saturate the USB bus. */ 54*4882a593Smuzhiyun #define USBTV_ISOC_TRANSFERS 16 55*4882a593Smuzhiyun #define USBTV_ISOC_PACKETS 8 56*4882a593Smuzhiyun 57*4882a593Smuzhiyun #define USBTV_CHUNK_SIZE 256 58*4882a593Smuzhiyun #define USBTV_CHUNK 240 59*4882a593Smuzhiyun 60*4882a593Smuzhiyun #define USBTV_AUDIO_URBSIZE 20480 61*4882a593Smuzhiyun #define USBTV_AUDIO_HDRSIZE 4 62*4882a593Smuzhiyun #define USBTV_AUDIO_BUFFER 65536 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun /* Chunk header. */ 65*4882a593Smuzhiyun #define USBTV_MAGIC_OK(chunk) ((be32_to_cpu(chunk[0]) & 0xff000000) \ 66*4882a593Smuzhiyun == 0x88000000) 67*4882a593Smuzhiyun #define USBTV_FRAME_ID(chunk) ((be32_to_cpu(chunk[0]) & 0x00ff0000) >> 16) 68*4882a593Smuzhiyun #define USBTV_ODD(chunk) ((be32_to_cpu(chunk[0]) & 0x0000f000) >> 15) 69*4882a593Smuzhiyun #define USBTV_CHUNK_NO(chunk) (be32_to_cpu(chunk[0]) & 0x00000fff) 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun #define USBTV_TV_STD (V4L2_STD_525_60 | V4L2_STD_PAL | V4L2_STD_SECAM) 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun /* parameters for supported TV norms */ 74*4882a593Smuzhiyun struct usbtv_norm_params { 75*4882a593Smuzhiyun v4l2_std_id norm; 76*4882a593Smuzhiyun int cap_width, cap_height; 77*4882a593Smuzhiyun }; 78*4882a593Smuzhiyun 79*4882a593Smuzhiyun /* A single videobuf2 frame buffer. */ 80*4882a593Smuzhiyun struct usbtv_buf { 81*4882a593Smuzhiyun struct vb2_v4l2_buffer vb; 82*4882a593Smuzhiyun struct list_head list; 83*4882a593Smuzhiyun }; 84*4882a593Smuzhiyun 85*4882a593Smuzhiyun /* Per-device structure. */ 86*4882a593Smuzhiyun struct usbtv { 87*4882a593Smuzhiyun struct device *dev; 88*4882a593Smuzhiyun struct usb_device *udev; 89*4882a593Smuzhiyun 90*4882a593Smuzhiyun /* video */ 91*4882a593Smuzhiyun struct v4l2_device v4l2_dev; 92*4882a593Smuzhiyun struct v4l2_ctrl_handler ctrl; 93*4882a593Smuzhiyun struct video_device vdev; 94*4882a593Smuzhiyun struct vb2_queue vb2q; 95*4882a593Smuzhiyun struct mutex v4l2_lock; 96*4882a593Smuzhiyun struct mutex vb2q_lock; 97*4882a593Smuzhiyun 98*4882a593Smuzhiyun /* List of videobuf2 buffers protected by a lock. */ 99*4882a593Smuzhiyun spinlock_t buflock; 100*4882a593Smuzhiyun struct list_head bufs; 101*4882a593Smuzhiyun 102*4882a593Smuzhiyun /* Number of currently processed frame, useful find 103*4882a593Smuzhiyun * out when a new one begins. */ 104*4882a593Smuzhiyun u32 frame_id; 105*4882a593Smuzhiyun int chunks_done; 106*4882a593Smuzhiyun 107*4882a593Smuzhiyun enum { 108*4882a593Smuzhiyun USBTV_COMPOSITE_INPUT, 109*4882a593Smuzhiyun USBTV_SVIDEO_INPUT, 110*4882a593Smuzhiyun } input; 111*4882a593Smuzhiyun v4l2_std_id norm; 112*4882a593Smuzhiyun int width, height; 113*4882a593Smuzhiyun int n_chunks; 114*4882a593Smuzhiyun int iso_size; 115*4882a593Smuzhiyun int last_odd; 116*4882a593Smuzhiyun unsigned int sequence; 117*4882a593Smuzhiyun struct urb *isoc_urbs[USBTV_ISOC_TRANSFERS]; 118*4882a593Smuzhiyun 119*4882a593Smuzhiyun /* audio */ 120*4882a593Smuzhiyun struct snd_card *snd; 121*4882a593Smuzhiyun struct snd_pcm_substream *snd_substream; 122*4882a593Smuzhiyun atomic_t snd_stream; 123*4882a593Smuzhiyun struct work_struct snd_trigger; 124*4882a593Smuzhiyun struct urb *snd_bulk_urb; 125*4882a593Smuzhiyun size_t snd_buffer_pos; 126*4882a593Smuzhiyun size_t snd_period_pos; 127*4882a593Smuzhiyun }; 128*4882a593Smuzhiyun 129*4882a593Smuzhiyun int usbtv_set_regs(struct usbtv *usbtv, const u16 regs[][2], int size); 130*4882a593Smuzhiyun 131*4882a593Smuzhiyun int usbtv_video_init(struct usbtv *usbtv); 132*4882a593Smuzhiyun void usbtv_video_free(struct usbtv *usbtv); 133*4882a593Smuzhiyun 134*4882a593Smuzhiyun int usbtv_audio_init(struct usbtv *usbtv); 135*4882a593Smuzhiyun void usbtv_audio_free(struct usbtv *usbtv); 136*4882a593Smuzhiyun void usbtv_audio_suspend(struct usbtv *usbtv); 137*4882a593Smuzhiyun void usbtv_audio_resume(struct usbtv *usbtv); 138