| /***************************************************************************** |
| * * |
| * 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/module.h> |
| #include <linux/kref.h> |
| #include <linux/smp_lock.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*/ |