639 lines
22 KiB
C
639 lines
22 KiB
C
/*****************************************************************************
|
|
* *
|
|
* easycap.h *
|
|
* *
|
|
*****************************************************************************/
|
|
/*
|
|
*
|
|
* Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
|
|
*
|
|
*
|
|
* This is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* The software is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this software; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
*/
|
|
/*****************************************************************************/
|
|
/*---------------------------------------------------------------------------*/
|
|
/*
|
|
* THE FOLLOWING PARAMETERS ARE UNDEFINED:
|
|
*
|
|
* EASYCAP_DEBUG
|
|
* EASYCAP_IS_VIDEODEV_CLIENT
|
|
* EASYCAP_NEEDS_USBVIDEO_H
|
|
* EASYCAP_NEEDS_V4L2_DEVICE_H
|
|
* EASYCAP_NEEDS_V4L2_FOPS
|
|
*
|
|
* IF REQUIRED THEY MUST BE EXTERNALLY DEFINED, FOR EXAMPLE AS COMPILER
|
|
* OPTIONS.
|
|
*/
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
#if (!defined(EASYCAP_H))
|
|
#define EASYCAP_H
|
|
|
|
#if defined(EASYCAP_DEBUG)
|
|
#if (9 < EASYCAP_DEBUG)
|
|
#error Debug levels 0 to 9 are okay.\
|
|
To achieve higher levels, remove this trap manually from easycap.h
|
|
#endif
|
|
#endif /*EASYCAP_DEBUG*/
|
|
/*---------------------------------------------------------------------------*/
|
|
/*
|
|
* THESE ARE FOR MAINTENANCE ONLY - NORMALLY UNDEFINED:
|
|
*/
|
|
/*---------------------------------------------------------------------------*/
|
|
#undef PREFER_NTSC
|
|
#undef EASYCAP_TESTCARD
|
|
#undef EASYCAP_TESTTONE
|
|
#undef LOCKFRAME
|
|
#undef NOREADBACK
|
|
#undef AUDIOTIME
|
|
/*---------------------------------------------------------------------------*/
|
|
/*
|
|
*
|
|
* DEFINE BRIDGER TO ACTIVATE THE ROUTINE FOR BRIDGING VIDEOTAPE DROPOUTS.
|
|
*
|
|
* *** UNDER DEVELOPMENT/TESTING - NOT READY YET!***
|
|
*
|
|
*/
|
|
/*---------------------------------------------------------------------------*/
|
|
#undef BRIDGER
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/errno.h>
|
|
#include <linux/init.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/smp_lock.h>
|
|
#include <linux/module.h>
|
|
#include <linux/kref.h>
|
|
#include <linux/usb.h>
|
|
#include <linux/uaccess.h>
|
|
|
|
#include <linux/i2c.h>
|
|
#include <linux/version.h>
|
|
#include <linux/workqueue.h>
|
|
#include <linux/poll.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/fs.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/types.h>
|
|
|
|
/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
|
#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
|
|
#if (!defined(__OLD_VIDIOC_))
|
|
#define __OLD_VIDIOC_
|
|
#endif /* !defined(__OLD_VIDIOC_) */
|
|
|
|
#include <media/v4l2-dev.h>
|
|
|
|
#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H)
|
|
#include <media/v4l2-device.h>
|
|
#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/
|
|
#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
|
|
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
|
|
|
#if (!defined(__OLD_VIDIOC_))
|
|
#define __OLD_VIDIOC_
|
|
#endif /* !defined(__OLD_VIDIOC_) */
|
|
#include <linux/videodev2.h>
|
|
|
|
#include <linux/soundcard.h>
|
|
|
|
#if defined(EASYCAP_NEEDS_USBVIDEO_H)
|
|
#include <config/video/usbvideo.h>
|
|
#endif /*EASYCAP_NEEDS_USBVIDEO_H*/
|
|
|
|
#if (!defined(PAGE_SIZE))
|
|
#error "PAGE_SIZE not defined"
|
|
#endif
|
|
|
|
#define STRINGIZE_AGAIN(x) #x
|
|
#define STRINGIZE(x) STRINGIZE_AGAIN(x)
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* VENDOR, PRODUCT: Syntek Semiconductor Co., Ltd
|
|
*
|
|
* EITHER EasyCAP USB 2.0 Video Adapter with Audio, Model No. DC60
|
|
* with input cabling: AUDIO(L), AUDIO(R), CVBS, S-VIDEO.
|
|
*
|
|
* OR EasyCAP 4CHANNEL USB 2.0 DVR, Model No. EasyCAP002
|
|
* with input cabling: MICROPHONE, CVBS1, CVBS2, CVBS3, CVBS4.
|
|
*/
|
|
/*---------------------------------------------------------------------------*/
|
|
#define USB_EASYCAP_VENDOR_ID 0x05e1
|
|
#define USB_EASYCAP_PRODUCT_ID 0x0408
|
|
|
|
#define EASYCAP_DRIVER_VERSION "0.8.21"
|
|
#define EASYCAP_DRIVER_DESCRIPTION "easycapdc60"
|
|
|
|
#define USB_SKEL_MINOR_BASE 192
|
|
#define VIDEO_DEVICE_MANY 8
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/*
|
|
* DEFAULT LUMINANCE, CONTRAST, SATURATION AND HUE
|
|
*/
|
|
/*---------------------------------------------------------------------------*/
|
|
#define SAA_0A_DEFAULT 0x7F
|
|
#define SAA_0B_DEFAULT 0x3F
|
|
#define SAA_0C_DEFAULT 0x2F
|
|
#define SAA_0D_DEFAULT 0x00
|
|
/*---------------------------------------------------------------------------*/
|
|
/*
|
|
* VIDEO STREAMING PARAMETERS:
|
|
* USB 2.0 PROVIDES FOR HIGH-BANDWIDTH ENDPOINTS WITH AN UPPER LIMIT
|
|
* OF 3072 BYTES PER MICROFRAME for wMaxPacketSize.
|
|
*/
|
|
/*---------------------------------------------------------------------------*/
|
|
#define VIDEO_ISOC_BUFFER_MANY 16
|
|
#define VIDEO_ISOC_ORDER 3
|
|
#define VIDEO_ISOC_FRAMESPERDESC ((unsigned int) 1 << VIDEO_ISOC_ORDER)
|
|
#define USB_2_0_MAXPACKETSIZE 3072
|
|
#if (USB_2_0_MAXPACKETSIZE > PAGE_SIZE)
|
|
#error video_isoc_buffer[.] will not be big enough
|
|
#endif
|
|
/*---------------------------------------------------------------------------*/
|
|
/*
|
|
* VIDEO BUFFERS
|
|
*/
|
|
/*---------------------------------------------------------------------------*/
|
|
#define FIELD_BUFFER_SIZE (203 * PAGE_SIZE)
|
|
#define FRAME_BUFFER_SIZE (405 * PAGE_SIZE)
|
|
#define FIELD_BUFFER_MANY 4
|
|
#define FRAME_BUFFER_MANY 6
|
|
/*---------------------------------------------------------------------------*/
|
|
/*
|
|
* AUDIO STREAMING PARAMETERS
|
|
*/
|
|
/*---------------------------------------------------------------------------*/
|
|
#define AUDIO_ISOC_BUFFER_MANY 16
|
|
#define AUDIO_ISOC_ORDER 3
|
|
#define AUDIO_ISOC_BUFFER_SIZE (PAGE_SIZE << AUDIO_ISOC_ORDER)
|
|
/*---------------------------------------------------------------------------*/
|
|
/*
|
|
* AUDIO BUFFERS
|
|
*/
|
|
/*---------------------------------------------------------------------------*/
|
|
#define AUDIO_FRAGMENT_MANY 32
|
|
/*---------------------------------------------------------------------------*/
|
|
/*
|
|
* IT IS ESSENTIAL THAT EVEN-NUMBERED STANDARDS ARE 25 FRAMES PER SECOND,
|
|
* ODD-NUMBERED STANDARDS ARE 30 FRAMES PER SECOND.
|
|
* THE NUMBERING OF STANDARDS MUST NOT BE CHANGED WITHOUT DUE CARE. NOT
|
|
* ONLY MUST THE PARAMETER
|
|
* STANDARD_MANY
|
|
* BE CHANGED TO CORRESPOND TO THE NEW NUMBER OF STANDARDS, BUT ALSO THE
|
|
* NUMBERING MUST REMAIN AN UNBROKEN ASCENDING SEQUENCE: DUMMY STANDARDS
|
|
* MAY NEED TO BE ADDED. APPROPRIATE CHANGES WILL ALWAYS BE REQUIRED IN
|
|
* ROUTINE fillin_formats() AND POSSIBLY ELSEWHERE. BEWARE.
|
|
*/
|
|
/*---------------------------------------------------------------------------*/
|
|
#define PAL_BGHIN 0
|
|
#define PAL_Nc 2
|
|
#define SECAM 4
|
|
#define NTSC_N 6
|
|
#define NTSC_N_443 8
|
|
#define NTSC_M 1
|
|
#define NTSC_443 3
|
|
#define NTSC_M_JP 5
|
|
#define PAL_60 7
|
|
#define PAL_M 9
|
|
#define STANDARD_MANY 10
|
|
/*---------------------------------------------------------------------------*/
|
|
/*
|
|
* ENUMS
|
|
*/
|
|
/*---------------------------------------------------------------------------*/
|
|
enum {
|
|
AT_720x576,
|
|
AT_704x576,
|
|
AT_640x480,
|
|
AT_720x480,
|
|
AT_360x288,
|
|
AT_320x240,
|
|
AT_360x240,
|
|
RESOLUTION_MANY
|
|
};
|
|
enum {
|
|
FMT_UYVY,
|
|
FMT_YUY2,
|
|
FMT_RGB24,
|
|
FMT_RGB32,
|
|
FMT_BGR24,
|
|
FMT_BGR32,
|
|
PIXELFORMAT_MANY
|
|
};
|
|
enum {
|
|
FIELD_NONE,
|
|
FIELD_INTERLACED,
|
|
FIELD_ALTERNATE,
|
|
INTERLACE_MANY
|
|
};
|
|
#define SETTINGS_MANY (STANDARD_MANY * \
|
|
RESOLUTION_MANY * \
|
|
2 * \
|
|
PIXELFORMAT_MANY * \
|
|
INTERLACE_MANY)
|
|
/*---------------------------------------------------------------------------*/
|
|
/*
|
|
* STRUCTURE DEFINITIONS
|
|
*/
|
|
/*---------------------------------------------------------------------------*/
|
|
struct data_buffer {
|
|
struct list_head list_head;
|
|
void *pgo;
|
|
void *pto;
|
|
__u16 kount;
|
|
};
|
|
/*---------------------------------------------------------------------------*/
|
|
struct data_urb {
|
|
struct list_head list_head;
|
|
struct urb *purb;
|
|
int isbuf;
|
|
int length;
|
|
};
|
|
/*---------------------------------------------------------------------------*/
|
|
struct easycap_standard {
|
|
__u16 mask;
|
|
struct v4l2_standard v4l2_standard;
|
|
};
|
|
struct easycap_format {
|
|
__u16 mask;
|
|
char name[128];
|
|
struct v4l2_format v4l2_format;
|
|
};
|
|
/*---------------------------------------------------------------------------*/
|
|
/*
|
|
* easycap.ilk == 0 => CVBS+S-VIDEO HARDWARE, AUDIO wMaxPacketSize=256
|
|
* easycap.ilk == 2 => CVBS+S-VIDEO HARDWARE, AUDIO wMaxPacketSize=9
|
|
* easycap.ilk == 3 => FOUR-CVBS HARDWARE, AUDIO wMaxPacketSize=9
|
|
*/
|
|
/*---------------------------------------------------------------------------*/
|
|
struct easycap {
|
|
unsigned int audio_pages_per_fragment;
|
|
unsigned int audio_bytes_per_fragment;
|
|
unsigned int audio_buffer_page_many;
|
|
|
|
#define UPSAMPLE
|
|
#if defined(UPSAMPLE)
|
|
__s16 oldaudio;
|
|
#endif /*UPSAMPLE*/
|
|
|
|
struct easycap_format easycap_format[1 + SETTINGS_MANY];
|
|
|
|
int ilk;
|
|
bool microphone;
|
|
|
|
/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
|
#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
|
|
struct video_device *pvideo_device;
|
|
#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
|
|
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
|
|
|
struct usb_device *pusb_device;
|
|
struct usb_interface *pusb_interface;
|
|
|
|
struct kref kref;
|
|
|
|
struct mutex mutex_mmap_video[FRAME_BUFFER_MANY];
|
|
struct mutex mutex_timeval0;
|
|
struct mutex mutex_timeval1;
|
|
|
|
int queued[FRAME_BUFFER_MANY];
|
|
int done[FRAME_BUFFER_MANY];
|
|
|
|
wait_queue_head_t wq_video;
|
|
wait_queue_head_t wq_audio;
|
|
|
|
int input;
|
|
int polled;
|
|
int standard_offset;
|
|
int format_offset;
|
|
|
|
int fps;
|
|
int usec;
|
|
int tolerate;
|
|
int merit[180];
|
|
|
|
struct timeval timeval0;
|
|
struct timeval timeval1;
|
|
struct timeval timeval2;
|
|
struct timeval timeval7;
|
|
long long int dnbydt;
|
|
|
|
int video_interface;
|
|
int video_altsetting_on;
|
|
int video_altsetting_off;
|
|
int video_endpointnumber;
|
|
int video_isoc_maxframesize;
|
|
int video_isoc_buffer_size;
|
|
int video_isoc_framesperdesc;
|
|
|
|
int video_isoc_streaming;
|
|
int video_isoc_sequence;
|
|
int video_idle;
|
|
int video_eof;
|
|
int video_junk;
|
|
|
|
int fudge;
|
|
|
|
struct data_buffer video_isoc_buffer[VIDEO_ISOC_BUFFER_MANY];
|
|
struct data_buffer \
|
|
field_buffer[FIELD_BUFFER_MANY][(FIELD_BUFFER_SIZE/PAGE_SIZE)];
|
|
struct data_buffer \
|
|
frame_buffer[FRAME_BUFFER_MANY][(FRAME_BUFFER_SIZE/PAGE_SIZE)];
|
|
|
|
struct list_head urb_video_head;
|
|
struct list_head *purb_video_head;
|
|
|
|
int vma_many;
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/*
|
|
* BUFFER INDICATORS
|
|
*/
|
|
/*---------------------------------------------------------------------------*/
|
|
int field_fill; /* Field buffer being filled by easycap_complete(). */
|
|
/* Bumped only by easycap_complete(). */
|
|
int field_page; /* Page of field buffer page being filled by */
|
|
/* easycap_complete(). */
|
|
int field_read; /* Field buffer to be read by field2frame(). */
|
|
/* Bumped only by easycap_complete(). */
|
|
int frame_fill; /* Frame buffer being filled by field2frame(). */
|
|
/* Bumped only by easycap_dqbuf() when */
|
|
/* field2frame() has created a complete frame. */
|
|
int frame_read; /* Frame buffer offered to user by DQBUF. */
|
|
/* Set only by easycap_dqbuf() to trail frame_fill.*/
|
|
int frame_lock; /* Flag set to 1 by DQBUF and cleared by QBUF */
|
|
/*---------------------------------------------------------------------------*/
|
|
/*
|
|
* IMAGE PROPERTIES
|
|
*/
|
|
/*---------------------------------------------------------------------------*/
|
|
__u32 pixelformat;
|
|
__u32 field;
|
|
int width;
|
|
int height;
|
|
int bytesperpixel;
|
|
bool byteswaporder;
|
|
bool decimatepixel;
|
|
bool offerfields;
|
|
int frame_buffer_used;
|
|
int frame_buffer_many;
|
|
int videofieldamount;
|
|
|
|
int brightness;
|
|
int contrast;
|
|
int saturation;
|
|
int hue;
|
|
|
|
int allocation_video_urb;
|
|
int allocation_video_page;
|
|
int allocation_video_struct;
|
|
int registered_video;
|
|
/*---------------------------------------------------------------------------*/
|
|
/*
|
|
* SOUND PROPERTIES
|
|
*/
|
|
/*---------------------------------------------------------------------------*/
|
|
int audio_interface;
|
|
int audio_altsetting_on;
|
|
int audio_altsetting_off;
|
|
int audio_endpointnumber;
|
|
int audio_isoc_maxframesize;
|
|
int audio_isoc_buffer_size;
|
|
int audio_isoc_framesperdesc;
|
|
|
|
int audio_isoc_streaming;
|
|
int audio_idle;
|
|
int audio_eof;
|
|
int volume;
|
|
int mute;
|
|
|
|
struct data_buffer audio_isoc_buffer[AUDIO_ISOC_BUFFER_MANY];
|
|
|
|
struct list_head urb_audio_head;
|
|
struct list_head *purb_audio_head;
|
|
/*---------------------------------------------------------------------------*/
|
|
/*
|
|
* BUFFER INDICATORS
|
|
*/
|
|
/*---------------------------------------------------------------------------*/
|
|
int audio_fill; /* Audio buffer being filled by easysnd_complete(). */
|
|
/* Bumped only by easysnd_complete(). */
|
|
int audio_read; /* Audio buffer page being read by easysnd_read(). */
|
|
/* Set by easysnd_read() to trail audio_fill by */
|
|
/* one fragment. */
|
|
/*---------------------------------------------------------------------------*/
|
|
/*
|
|
* SOUND PROPERTIES
|
|
*/
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
int audio_buffer_many;
|
|
|
|
int allocation_audio_urb;
|
|
int allocation_audio_page;
|
|
int allocation_audio_struct;
|
|
int registered_audio;
|
|
|
|
long long int audio_sample;
|
|
long long int audio_niveau;
|
|
long long int audio_square;
|
|
|
|
struct data_buffer audio_buffer[];
|
|
};
|
|
/*---------------------------------------------------------------------------*/
|
|
/*
|
|
* VIDEO FUNCTION PROTOTYPES
|
|
*/
|
|
/*---------------------------------------------------------------------------*/
|
|
void easycap_complete(struct urb *);
|
|
int easycap_open(struct inode *, struct file *);
|
|
int easycap_release(struct inode *, struct file *);
|
|
long easycap_ioctl(struct file *, unsigned int, unsigned long);
|
|
|
|
/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
|
|
#if defined(EASYCAP_IS_VIDEODEV_CLIENT)
|
|
int easycap_open_noinode(struct file *);
|
|
int easycap_release_noinode(struct file *);
|
|
int videodev_release(struct video_device *);
|
|
#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/
|
|
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
|
|
|
|
unsigned int easycap_poll(struct file *, poll_table *);
|
|
int easycap_mmap(struct file *, struct vm_area_struct *);
|
|
int easycap_usb_probe(struct usb_interface *, \
|
|
const struct usb_device_id *);
|
|
void easycap_usb_disconnect(struct usb_interface *);
|
|
void easycap_delete(struct kref *);
|
|
|
|
void easycap_vma_open(struct vm_area_struct *);
|
|
void easycap_vma_close(struct vm_area_struct *);
|
|
int easycap_vma_fault(struct vm_area_struct *, struct vm_fault *);
|
|
int easycap_dqbuf(struct easycap *, int);
|
|
int submit_video_urbs(struct easycap *);
|
|
int kill_video_urbs(struct easycap *);
|
|
int field2frame(struct easycap *);
|
|
int redaub(struct easycap *, void *, void *, \
|
|
int, int, __u8, __u8, bool);
|
|
void debrief(struct easycap *);
|
|
void sayreadonly(struct easycap *);
|
|
void easycap_testcard(struct easycap *, int);
|
|
int explain_ioctl(__u32);
|
|
int explain_cid(__u32);
|
|
int fillin_formats(void);
|
|
int adjust_standard(struct easycap *, v4l2_std_id);
|
|
int adjust_format(struct easycap *, __u32, __u32, __u32, \
|
|
int, bool);
|
|
int adjust_brightness(struct easycap *, int);
|
|
int adjust_contrast(struct easycap *, int);
|
|
int adjust_saturation(struct easycap *, int);
|
|
int adjust_hue(struct easycap *, int);
|
|
int adjust_volume(struct easycap *, int);
|
|
/*---------------------------------------------------------------------------*/
|
|
/*
|
|
* AUDIO FUNCTION PROTOTYPES
|
|
*/
|
|
/*---------------------------------------------------------------------------*/
|
|
void easysnd_complete(struct urb *);
|
|
ssize_t easysnd_read(struct file *, char __user *, size_t, loff_t *);
|
|
int easysnd_open(struct inode *, struct file *);
|
|
int easysnd_release(struct inode *, struct file *);
|
|
long easysnd_ioctl(struct file *, unsigned int, unsigned long);
|
|
unsigned int easysnd_poll(struct file *, poll_table *);
|
|
void easysnd_delete(struct kref *);
|
|
int submit_audio_urbs(struct easycap *);
|
|
int kill_audio_urbs(struct easycap *);
|
|
void easysnd_testtone(struct easycap *, int);
|
|
int audio_setup(struct easycap *);
|
|
/*---------------------------------------------------------------------------*/
|
|
/*
|
|
* LOW-LEVEL FUNCTION PROTOTYPES
|
|
*/
|
|
/*---------------------------------------------------------------------------*/
|
|
int audio_gainget(struct usb_device *);
|
|
int audio_gainset(struct usb_device *, __s8);
|
|
|
|
int set_interface(struct usb_device *, __u16);
|
|
int wakeup_device(struct usb_device *);
|
|
int confirm_resolution(struct usb_device *);
|
|
int confirm_stream(struct usb_device *);
|
|
|
|
int setup_stk(struct usb_device *);
|
|
int setup_saa(struct usb_device *);
|
|
int setup_vt(struct usb_device *);
|
|
int check_stk(struct usb_device *);
|
|
int check_saa(struct usb_device *);
|
|
int ready_saa(struct usb_device *);
|
|
int merit_saa(struct usb_device *);
|
|
int check_vt(struct usb_device *);
|
|
int select_input(struct usb_device *, int, int);
|
|
int set_resolution(struct usb_device *, \
|
|
__u16, __u16, __u16, __u16);
|
|
|
|
int read_saa(struct usb_device *, __u16);
|
|
int read_stk(struct usb_device *, __u32);
|
|
int write_saa(struct usb_device *, __u16, __u16);
|
|
int wait_i2c(struct usb_device *);
|
|
int write_000(struct usb_device *, __u16, __u16);
|
|
int start_100(struct usb_device *);
|
|
int stop_100(struct usb_device *);
|
|
int write_300(struct usb_device *);
|
|
int read_vt(struct usb_device *, __u16);
|
|
int write_vt(struct usb_device *, __u16, __u16);
|
|
|
|
int set2to78(struct usb_device *);
|
|
int set2to93(struct usb_device *);
|
|
|
|
int regset(struct usb_device *, __u16, __u16);
|
|
int regget(struct usb_device *, __u16, void *);
|
|
/*---------------------------------------------------------------------------*/
|
|
struct signed_div_result {
|
|
long long int quotient;
|
|
unsigned long long int remainder;
|
|
} signed_div(long long int, long long int);
|
|
/*---------------------------------------------------------------------------*/
|
|
/*
|
|
* MACROS
|
|
*/
|
|
/*---------------------------------------------------------------------------*/
|
|
#define GET(X, Y, Z) do { \
|
|
int rc; \
|
|
*(Z) = (__u16)0; \
|
|
rc = regget(X, Y, Z); \
|
|
if (0 > rc) { \
|
|
JOT(8, ":-(%i\n", __LINE__); return(rc); \
|
|
} \
|
|
} while (0)
|
|
|
|
#define SET(X, Y, Z) do { \
|
|
int rc; \
|
|
rc = regset(X, Y, Z); \
|
|
if (0 > rc) { \
|
|
JOT(8, ":-(%i\n", __LINE__); return(rc); \
|
|
} \
|
|
} while (0)
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
#define SAY(format, args...) do { \
|
|
printk(KERN_DEBUG "easycap: %s: " format, __func__, ##args); \
|
|
} while (0)
|
|
|
|
|
|
#if defined(EASYCAP_DEBUG)
|
|
#define JOT(n, format, args...) do { \
|
|
if (n <= easycap_debug) { \
|
|
printk(KERN_DEBUG "easycap: %s: " format, __func__, ##args); \
|
|
} \
|
|
} while (0)
|
|
#else
|
|
#define JOT(n, format, args...) do {} while (0)
|
|
#endif /*EASYCAP_DEBUG*/
|
|
|
|
#define POUT JOT(8, ":-(in file %s line %4i\n", __FILE__, __LINE__)
|
|
|
|
#define MICROSECONDS(X, Y) \
|
|
((1000000*((long long int)(X.tv_sec - Y.tv_sec))) + \
|
|
(long long int)(X.tv_usec - Y.tv_usec))
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/*
|
|
* (unsigned char *)P pointer to next byte pair
|
|
* (long int *)X pointer to accumulating count
|
|
* (long int *)Y pointer to accumulating sum
|
|
* (long long int *)Z pointer to accumulating sum of squares
|
|
*/
|
|
/*---------------------------------------------------------------------------*/
|
|
#define SUMMER(P, X, Y, Z) do { \
|
|
unsigned char *p; \
|
|
unsigned int u0, u1, u2; \
|
|
long int s; \
|
|
p = (unsigned char *)(P); \
|
|
u0 = (unsigned int) (*p); \
|
|
u1 = (unsigned int) (*(p + 1)); \
|
|
u2 = (unsigned int) ((u1 << 8) | u0); \
|
|
if (0x8000 & u2) \
|
|
s = -(long int)(0x7FFF & (~u2)); \
|
|
else \
|
|
s = (long int)(0x7FFF & u2); \
|
|
*((X)) += (long int) 1; \
|
|
*((Y)) += (long int) s; \
|
|
*((Z)) += ((long long int)(s) * (long long int)(s)); \
|
|
} while (0)
|
|
/*---------------------------------------------------------------------------*/
|
|
|
|
#endif /*EASYCAP_H*/
|