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