123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652 |
- /*****************************************************************************
- * *
- * 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
- *
- * IF REQUIRED THEY MUST BE EXTERNALLY DEFINED, FOR EXAMPLE AS COMPILER
- * OPTIONS.
- */
- /*---------------------------------------------------------------------------*/
- #ifndef __EASYCAP_H__
- #define __EASYCAP_H__
- /*---------------------------------------------------------------------------*/
- /*
- * THESE ARE NORMALLY DEFINED
- */
- /*---------------------------------------------------------------------------*/
- #define PATIENCE 500
- #define PERSEVERE
- /*---------------------------------------------------------------------------*/
- /*
- * THESE ARE FOR MAINTENANCE ONLY - NORMALLY UNDEFINED:
- */
- /*---------------------------------------------------------------------------*/
- #undef EASYCAP_TESTCARD
- /*---------------------------------------------------------------------------*/
- #include <linux/kernel.h>
- #include <linux/errno.h>
- #include <linux/init.h>
- #include <linux/slab.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>
- #ifndef CONFIG_EASYCAP_OSS
- #include <linux/vmalloc.h>
- #include <linux/sound.h>
- #include <sound/core.h>
- #include <sound/pcm.h>
- #include <sound/pcm_params.h>
- #include <sound/info.h>
- #include <sound/initval.h>
- #include <sound/control.h>
- #endif /* !CONFIG_EASYCAP_OSS */
- #include <media/v4l2-dev.h>
- #include <media/v4l2-device.h>
- #include <linux/videodev2.h>
- #include <linux/soundcard.h>
- #ifndef PAGE_SIZE
- #error "PAGE_SIZE not defined"
- #endif /* PAGE_SIZE */
- /*---------------------------------------------------------------------------*/
- /* 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.9.01"
- #define EASYCAP_DRIVER_DESCRIPTION "easycapdc60"
- #define USB_SKEL_MINOR_BASE 192
- #define DONGLE_MANY 8
- #define INPUT_MANY 6
- /*---------------------------------------------------------------------------*/
- /*
- * 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
- #define VIDEO_JUNK_TOLERATE VIDEO_ISOC_BUFFER_MANY
- #define VIDEO_LOST_TOLERATE 50
- /*---------------------------------------------------------------------------*/
- /*
- * 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 1
- #define AUDIO_ISOC_FRAMESPERDESC 32
- #define AUDIO_ISOC_BUFFER_SIZE (PAGE_SIZE << AUDIO_ISOC_ORDER)
- /*---------------------------------------------------------------------------*/
- /*
- * AUDIO BUFFERS
- */
- /*---------------------------------------------------------------------------*/
- #define AUDIO_FRAGMENT_MANY 32
- #define PAGES_PER_AUDIO_FRAGMENT 4
- /*---------------------------------------------------------------------------*/
- /*
- * 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 PAL_BGHIN_SLOW 10
- #define PAL_Nc_SLOW 12
- #define SECAM_SLOW 14
- #define NTSC_N_SLOW 16
- #define NTSC_N_443_SLOW 18
- #define NTSC_M_SLOW 11
- #define NTSC_443_SLOW 13
- #define NTSC_M_JP_SLOW 15
- #define PAL_60_SLOW 17
- #define PAL_M_SLOW 19
- #define STANDARD_MANY 20
- /*---------------------------------------------------------------------------*/
- /*
- * 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,
- INTERLACE_MANY
- };
- #define SETTINGS_MANY (STANDARD_MANY * \
- RESOLUTION_MANY * \
- 2 * \
- PIXELFORMAT_MANY * \
- INTERLACE_MANY)
- /*---------------------------------------------------------------------------*/
- /*
- * STRUCTURE DEFINITIONS
- */
- /*---------------------------------------------------------------------------*/
- struct easycap_dongle {
- struct easycap *peasycap;
- struct mutex mutex_video;
- struct mutex mutex_audio;
- };
- /*---------------------------------------------------------------------------*/
- struct data_buffer {
- struct list_head list_head;
- void *pgo;
- void *pto;
- u16 kount;
- u16 input;
- };
- /*---------------------------------------------------------------------------*/
- 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;
- };
- struct inputset {
- int input;
- int input_ok;
- int standard_offset;
- int standard_offset_ok;
- int format_offset;
- int format_offset_ok;
- int brightness;
- int brightness_ok;
- int contrast;
- int contrast_ok;
- int saturation;
- int saturation_ok;
- int hue;
- int hue_ok;
- };
- /*---------------------------------------------------------------------------*/
- /*
- * 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 {
- #define TELLTALE "expectedstring"
- char telltale[16];
- int isdongle;
- int minor;
- struct video_device video_device;
- struct v4l2_device v4l2_device;
- int status;
- unsigned int audio_pages_per_fragment;
- unsigned int audio_bytes_per_fragment;
- unsigned int audio_buffer_page_many;
- #define UPSAMPLE
- #ifdef UPSAMPLE
- s16 oldaudio;
- #endif /*UPSAMPLE*/
- int ilk;
- bool microphone;
- struct usb_device *pusb_device;
- struct usb_interface *pusb_interface;
- struct kref kref;
- int queued[FRAME_BUFFER_MANY];
- int done[FRAME_BUFFER_MANY];
- wait_queue_head_t wq_video;
- wait_queue_head_t wq_audio;
- wait_queue_head_t wq_trigger;
- int input;
- int polled;
- int standard_offset;
- int format_offset;
- struct inputset inputset[INPUT_MANY];
- bool ntsc;
- int fps;
- int usec;
- int tolerate;
- int skip;
- int skipped;
- int lost[INPUT_MANY];
- int merit[180];
- struct timeval timeval0;
- struct timeval timeval1;
- struct timeval timeval2;
- struct timeval timeval3;
- struct timeval timeval6;
- struct timeval timeval7;
- struct timeval timeval8;
- 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;
- 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;
- u8 cache[8];
- u8 *pcache;
- int video_mt;
- int audio_mt;
- long long audio_bytes;
- u32 isequence;
- 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;
- 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;
- /*---------------------------------------------------------------------------*/
- /*
- * ALSA
- */
- /*---------------------------------------------------------------------------*/
- #ifndef CONFIG_EASYCAP_OSS
- struct snd_pcm_hardware alsa_hardware;
- struct snd_card *psnd_card;
- struct snd_pcm *psnd_pcm;
- struct snd_pcm_substream *psubstream;
- int dma_fill;
- int dma_next;
- int dma_read;
- #endif /* !CONFIG_EASYCAP_OSS */
- /*---------------------------------------------------------------------------*/
- /*
- * 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;
- s8 gain;
- 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 easycap_complete(). */
- /* Bumped only by easycap_complete(). */
- int audio_read; /* Audio buffer page being read by easycap_read(). */
- /* Set by easycap_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
- */
- /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
- long easycap_unlocked_ioctl(struct file *, unsigned int, unsigned long);
- 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 easycap_testcard(struct easycap *, int);
- int fillin_formats(void);
- int newinput(struct easycap *, int);
- 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
- */
- /*---------------------------------------------------------------------------*/
- #ifndef CONFIG_EASYCAP_OSS
- int easycap_alsa_probe(struct easycap *);
- void easycap_alsa_complete(struct urb *);
- #else /* CONFIG_EASYCAP_OSS */
- void easyoss_complete(struct urb *);
- #endif /* !CONFIG_EASYCAP_OSS */
- int easycap_sound_setup(struct easycap *);
- int submit_audio_urbs(struct easycap *);
- int kill_audio_urbs(struct easycap *);
- void easyoss_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 *, bool);
- int setup_saa(struct usb_device *, bool);
- int setup_vt(struct usb_device *);
- int check_stk(struct usb_device *, bool);
- int check_saa(struct usb_device *, bool);
- 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 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 isdongle(struct easycap *);
- /*---------------------------------------------------------------------------*/
- struct signed_div_result {
- long long int quotient;
- unsigned long long int remainder;
- } signed_div(long long int, long long int);
- /*---------------------------------------------------------------------------*/
- /*
- * MACROS SAM(...) AND JOM(...) ALLOW DIAGNOSTIC OUTPUT TO BE TAGGED WITH
- * THE IDENTITY OF THE DONGLE TO WHICH IT APPLIES, BUT IF INVOKED WHEN THE
- * POINTER peasycap IS INVALID AN Oops IS LIKELY, AND ITS CAUSE MAY NOT BE
- * IMMEDIATELY OBVIOUS FROM A CASUAL READING OF THE SOURCE CODE. BEWARE.
- */
- /*---------------------------------------------------------------------------*/
- const char *strerror(int err);
- #define SAY(format, args...) do { \
- printk(KERN_DEBUG "easycap:: %s: " \
- format, __func__, ##args); \
- } while (0)
- #define SAM(format, args...) do { \
- printk(KERN_DEBUG "easycap::%i%s: " \
- format, peasycap->isdongle, __func__, ##args);\
- } while (0)
- #ifdef CONFIG_EASYCAP_DEBUG
- extern int easycap_debug;
- #define JOT(n, format, args...) do { \
- if (n <= easycap_debug) { \
- printk(KERN_DEBUG "easycap:: %s: " \
- format, __func__, ##args);\
- } \
- } while (0)
- #define JOM(n, format, args...) do { \
- if (n <= easycap_debug) { \
- printk(KERN_DEBUG "easycap::%i%s: " \
- format, peasycap->isdongle, __func__, ##args);\
- } \
- } while (0)
- #else
- #define JOT(n, format, args...) do {} while (0)
- #define JOM(n, format, args...) do {} while (0)
- #endif /* CONFIG_EASYCAP_DEBUG */
- #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)
- /*---------------------------------------------------------------------------*/
- /*---------------------------------------------------------------------------*/
- /* globals
- */
- /*---------------------------------------------------------------------------*/
- extern bool easycap_readback;
- extern const struct easycap_standard easycap_standard[];
- extern struct easycap_format easycap_format[];
- extern struct v4l2_queryctrl easycap_control[];
- extern struct usb_driver easycap_usb_driver;
- extern struct easycap_dongle easycapdc60_dongle[];
- #ifdef CONFIG_EASYCAP_OSS
- extern struct usb_class_driver easyoss_class;
- #endif /* !CONFIG_EASYCAP_OSS */
- #endif /* !__EASYCAP_H__ */
|