diff options
author | Grant Likely <grant.likely@secretlab.ca> | 2011-03-17 13:46:58 -0600 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2011-03-17 13:48:06 -0600 |
commit | 2dd22997679a88874c131f6e6ffb963e6d43b3a6 (patch) | |
tree | bfe1707dda7e755b8b550c6796e2649813bcfbb9 /drivers/staging/easycap | |
parent | 36885ff0e6563687e6152da6d311abbf83c0198f (diff) | |
parent | 7b7adc4a016a1decb806eb71ecab98721fa7f146 (diff) |
Merge remote-tracking branch 'origin' into spi/next
Pull in Linus' tree to pick up changes required for the langwell gpio fixes
Diffstat (limited to 'drivers/staging/easycap')
-rw-r--r-- | drivers/staging/easycap/Kconfig | 43 | ||||
-rw-r--r-- | drivers/staging/easycap/Makefile | 18 | ||||
-rw-r--r-- | drivers/staging/easycap/easycap.h | 559 | ||||
-rw-r--r-- | drivers/staging/easycap/easycap_debug.h | 29 | ||||
-rw-r--r-- | drivers/staging/easycap/easycap_ioctl.c | 4379 | ||||
-rw-r--r-- | drivers/staging/easycap/easycap_ioctl.h | 28 | ||||
-rw-r--r-- | drivers/staging/easycap/easycap_low.c | 1459 | ||||
-rw-r--r-- | drivers/staging/easycap/easycap_main.c | 7508 | ||||
-rw-r--r-- | drivers/staging/easycap/easycap_settings.c | 1123 | ||||
-rw-r--r-- | drivers/staging/easycap/easycap_sound.c | 1717 | ||||
-rw-r--r-- | drivers/staging/easycap/easycap_sound.h | 28 | ||||
-rw-r--r-- | drivers/staging/easycap/easycap_sound_oss.c | 954 | ||||
-rw-r--r-- | drivers/staging/easycap/easycap_standard.h | 27 | ||||
-rw-r--r-- | drivers/staging/easycap/easycap_testcard.c | 495 |
14 files changed, 8804 insertions, 9563 deletions
diff --git a/drivers/staging/easycap/Kconfig b/drivers/staging/easycap/Kconfig index bd96f39f273..6ed208c6185 100644 --- a/drivers/staging/easycap/Kconfig +++ b/drivers/staging/easycap/Kconfig @@ -1,6 +1,6 @@ config EASYCAP tristate "EasyCAP USB ID 05e1:0408 support" - depends on USB && VIDEO_DEV + depends on USB && VIDEO_DEV && (SND || SOUND_OSS_CORE) ---help--- This is an integrated audio/video driver for EasyCAP cards with @@ -15,3 +15,44 @@ config EASYCAP To compile this driver as a module, choose M here: the module will be called easycap +choice + prompt "Sound Interface" + depends on EASYCAP + default EASYCAP_SND + ---help--- + +config EASYCAP_SND + bool "ALSA" + depends on SND + select SND_PCM + + ---help--- + Say 'Y' if you want to use ALSA interface + + This will disable Open Sound System (OSS) binding. + +config EASYCAP_OSS + bool "OSS (DEPRECATED)" + depends on SOUND_OSS_CORE + + ---help--- + Say 'Y' if you prefer Open Sound System (OSS) interface + + This will disable Advanced Linux Sound Architecture (ALSA) binding. + + Once binding to ALSA interface will be stable this option will be + removed. +endchoice + +config EASYCAP_DEBUG + bool "Enable EasyCAP driver debugging" + depends on EASYCAP + + ---help--- + This option enables debug printouts + + To enable debug, pass the debug level to the debug module + parameter: + + modprobe easycap debug=[0..9] + diff --git a/drivers/staging/easycap/Makefile b/drivers/staging/easycap/Makefile index f1f2fbebf8f..b13e9ac473b 100644 --- a/drivers/staging/easycap/Makefile +++ b/drivers/staging/easycap/Makefile @@ -1,14 +1,12 @@ +easycap-objs := easycap_main.o +easycap-objs += easycap_low.o +easycap-objs += easycap_ioctl.o +easycap-objs += easycap_settings.o +easycap-objs += easycap_testcard.o +easycap-objs += easycap_sound.o +easycap-$(CONFIG_EASYCAP_OSS) += easycap_sound_oss.o -obj-$(CONFIG_EASYCAP) += easycap.o - -easycap-y := easycap_main.o easycap_low.o easycap_sound.o -easycap-y += easycap_ioctl.o easycap_settings.o -easycap-y += easycap_testcard.o +obj-$(CONFIG_EASYCAP) += easycap.o ccflags-y := -Wall -# Impose all or none of the following: -ccflags-y += -DEASYCAP_IS_VIDEODEV_CLIENT -ccflags-y += -DEASYCAP_NEEDS_V4L2_DEVICE_H -ccflags-y += -DEASYCAP_NEEDS_V4L2_FOPS -ccflags-y += -DEASYCAP_NEEDS_UNLOCKED_IOCTL diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 8ebf96f8a24..1f94e2389ef 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -29,19 +29,14 @@ * THE FOLLOWING PARAMETERS ARE UNDEFINED: * * EASYCAP_DEBUG - * EASYCAP_IS_VIDEODEV_CLIENT - * EASYCAP_NEEDS_USBVIDEO_H - * EASYCAP_NEEDS_V4L2_DEVICE_H - * EASYCAP_NEEDS_V4L2_FOPS - * EASYCAP_NEEDS_UNLOCKED_IOCTL * * IF REQUIRED THEY MUST BE EXTERNALLY DEFINED, FOR EXAMPLE AS COMPILER * OPTIONS. */ /*---------------------------------------------------------------------------*/ -#if (!defined(EASYCAP_H)) -#define EASYCAP_H +#ifndef __EASYCAP_H__ +#define __EASYCAP_H__ /*---------------------------------------------------------------------------*/ /* @@ -49,7 +44,6 @@ */ /*---------------------------------------------------------------------------*/ #define PATIENCE 500 -#undef PREFER_NTSC #define PERSEVERE /*---------------------------------------------------------------------------*/ /* @@ -57,15 +51,11 @@ */ /*---------------------------------------------------------------------------*/ #undef EASYCAP_TESTCARD -#undef EASYCAP_TESTTONE -#undef NOREADBACK -#undef AUDIOTIME /*---------------------------------------------------------------------------*/ #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> @@ -80,26 +70,25 @@ #include <linux/delay.h> #include <linux/types.h> -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if defined(EASYCAP_IS_VIDEODEV_CLIENT) +#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> -#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) #include <media/v4l2-device.h> -#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ #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)) +#ifndef PAGE_SIZE #error "PAGE_SIZE not defined" -#endif +#endif /* PAGE_SIZE */ -#define STRINGIZE_AGAIN(x) #x -#define STRINGIZE(x) STRINGIZE_AGAIN(x) /*---------------------------------------------------------------------------*/ /* VENDOR, PRODUCT: Syntek Semiconductor Co., Ltd * @@ -113,7 +102,7 @@ #define USB_EASYCAP_VENDOR_ID 0x05e1 #define USB_EASYCAP_PRODUCT_ID 0x0408 -#define EASYCAP_DRIVER_VERSION "0.8.41" +#define EASYCAP_DRIVER_VERSION "0.9.01" #define EASYCAP_DRIVER_DESCRIPTION "easycapdc60" #define USB_SKEL_MINOR_BASE 192 @@ -159,7 +148,8 @@ */ /*---------------------------------------------------------------------------*/ #define AUDIO_ISOC_BUFFER_MANY 16 -#define AUDIO_ISOC_ORDER 3 +#define AUDIO_ISOC_ORDER 1 +#define AUDIO_ISOC_FRAMESPERDESC 32 #define AUDIO_ISOC_BUFFER_SIZE (PAGE_SIZE << AUDIO_ISOC_ORDER) /*---------------------------------------------------------------------------*/ /* @@ -167,6 +157,7 @@ */ /*---------------------------------------------------------------------------*/ #define AUDIO_FRAGMENT_MANY 32 +#define PAGES_PER_AUDIO_FRAGMENT 4 /*---------------------------------------------------------------------------*/ /* * IT IS ESSENTIAL THAT EVEN-NUMBERED STANDARDS ARE 25 FRAMES PER SECOND, @@ -207,28 +198,28 @@ */ /*---------------------------------------------------------------------------*/ enum { -AT_720x576, -AT_704x576, -AT_640x480, -AT_720x480, -AT_360x288, -AT_320x240, -AT_360x240, -RESOLUTION_MANY + 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 + FMT_UYVY, + FMT_YUY2, + FMT_RGB24, + FMT_RGB32, + FMT_BGR24, + FMT_BGR32, + PIXELFORMAT_MANY }; enum { -FIELD_NONE, -FIELD_INTERLACED, -INTERLACE_MANY + FIELD_NONE, + FIELD_INTERLACED, + INTERLACE_MANY }; #define SETTINGS_MANY (STANDARD_MANY * \ RESOLUTION_MANY * \ @@ -241,50 +232,50 @@ INTERLACE_MANY */ /*---------------------------------------------------------------------------*/ struct easycap_dongle { -struct easycap *peasycap; -struct mutex mutex_video; -struct mutex mutex_audio; + 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 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 list_head list_head; + struct urb *purb; + int isbuf; + int length; }; /*---------------------------------------------------------------------------*/ struct easycap_standard { -__u16 mask; + u16 mask; struct v4l2_standard v4l2_standard; }; struct easycap_format { -__u16 mask; -char name[128]; + 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; + 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; }; /*---------------------------------------------------------------------------*/ /* @@ -295,171 +286,182 @@ int hue_ok; /*---------------------------------------------------------------------------*/ struct easycap { #define TELLTALE "expectedstring" -char telltale[16]; -int isdongle; - -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if defined(EASYCAP_IS_VIDEODEV_CLIENT) -struct video_device video_device; -#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) -struct v4l2_device v4l2_device; -#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -int status; -unsigned int audio_pages_per_fragment; -unsigned int audio_bytes_per_fragment; -unsigned int audio_buffer_page_many; + 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 -#if defined(UPSAMPLE) -__s16 oldaudio; +#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; - -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; - + 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(). */ + 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 */ + int field_page; /* Page of field buffer page being filled by */ /* easycap_complete(). */ -int field_read; /* Field buffer to be read by field2frame(). */ + int field_read; /* Field buffer to be read by field2frame(). */ /* Bumped only by easycap_complete(). */ -int frame_fill; /* Frame buffer being filled by field2frame(). */ + 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. */ + 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 */ + 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; + 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_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; + 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 data_buffer audio_isoc_buffer[AUDIO_ISOC_BUFFER_MANY]; -struct list_head urb_audio_head; -struct list_head *purb_audio_head; + 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 */ + 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. */ /*---------------------------------------------------------------------------*/ /* @@ -467,61 +469,36 @@ int audio_read; /* Audio buffer page being read by easysnd_read(). */ */ /*---------------------------------------------------------------------------*/ -int audio_buffer_many; + int audio_buffer_many; -int allocation_audio_urb; -int allocation_audio_page; -int allocation_audio_struct; -int registered_audio; + 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; + long long int audio_sample; + long long int audio_niveau; + long long int audio_square; -struct data_buffer audio_buffer[]; + 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_noinode(struct file *, unsigned int, \ - unsigned long); -int easycap_ioctl(struct inode *, 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 *); +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); +int redaub(struct easycap *, void *, void *, + int, int, u8, u8, bool); void easycap_testcard(struct easycap *, int); int fillin_formats(void); -int reset(struct easycap *); int newinput(struct easycap *, int); int adjust_standard(struct easycap *, v4l2_std_id); -int adjust_format(struct easycap *, __u32, __u32, __u32, \ +int adjust_format(struct easycap *, u32, u32, u32, int, bool); int adjust_brightness(struct easycap *, int); int adjust_contrast(struct easycap *, int); @@ -533,19 +510,17 @@ 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_noinode(struct file *, unsigned int, \ - unsigned long); -int easysnd_ioctl(struct inode *, struct file *, unsigned int, \ - unsigned long); -unsigned int easysnd_poll(struct file *, poll_table *); -void easysnd_delete(struct kref *); +#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 easysnd_testtone(struct easycap *, int); +void easyoss_testtone(struct easycap *, int); int audio_setup(struct easycap *); /*---------------------------------------------------------------------------*/ /* @@ -553,9 +528,9 @@ int audio_setup(struct easycap *); */ /*---------------------------------------------------------------------------*/ int audio_gainget(struct usb_device *); -int audio_gainset(struct usb_device *, __s8); +int audio_gainset(struct usb_device *, s8); -int set_interface(struct usb_device *, __u16); +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 *); @@ -569,48 +544,26 @@ 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 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 regset(struct usb_device *, __u16, __u16); -int regget(struct usb_device *, __u16, void *); +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; + 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) + /*---------------------------------------------------------------------------*/ /* * MACROS SAM(...) AND JOM(...) ALLOW DIAGNOSTIC OUTPUT TO BE TAGGED WITH @@ -619,6 +572,8 @@ unsigned long long int remainder; * 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); \ @@ -628,7 +583,8 @@ unsigned long long int remainder; format, peasycap->isdongle, __func__, ##args);\ } while (0) -#if defined(EASYCAP_DEBUG) +#ifdef CONFIG_EASYCAP_DEBUG +extern int easycap_debug; #define JOT(n, format, args...) do { \ if (n <= easycap_debug) { \ printk(KERN_DEBUG "easycap:: %s: " \ @@ -645,7 +601,7 @@ unsigned long long int remainder; #else #define JOT(n, format, args...) do {} while (0) #define JOM(n, format, args...) do {} while (0) -#endif /*EASYCAP_DEBUG*/ +#endif /* CONFIG_EASYCAP_DEBUG */ #define MICROSECONDS(X, Y) \ ((1000000*((long long int)(X.tv_sec - Y.tv_sec))) + \ @@ -677,4 +633,19 @@ unsigned long long int remainder; } while (0) /*---------------------------------------------------------------------------*/ -#endif /*EASYCAP_H*/ +/*---------------------------------------------------------------------------*/ +/* 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__ */ diff --git a/drivers/staging/easycap/easycap_debug.h b/drivers/staging/easycap/easycap_debug.h deleted file mode 100644 index b6b57184312..00000000000 --- a/drivers/staging/easycap/easycap_debug.h +++ /dev/null @@ -1,29 +0,0 @@ -/***************************************************************************** -* * -* easycap_debug.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 - * -*/ -/*****************************************************************************/ -extern int easycap_debug; -extern int easycap_gain; -extern struct easycap_dongle easycap_dongle[]; diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index 447953a4e80..28a28e02c9c 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -25,11 +25,7 @@ */ /*****************************************************************************/ -#include <linux/smp_lock.h> #include "easycap.h" -#include "easycap_debug.h" -#include "easycap_standard.h" -#include "easycap_ioctl.h" /*--------------------------------------------------------------------------*/ /* @@ -45,277 +41,297 @@ /*---------------------------------------------------------------------------*/ int adjust_standard(struct easycap *peasycap, v4l2_std_id std_id) { -struct easycap_standard const *peasycap_standard; -__u16 reg, set; -int ir, rc, need, k; -unsigned int itwas, isnow; -bool resubmit; - -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -peasycap_standard = &easycap_standard[0]; -while (0xFFFF != peasycap_standard->mask) { - if (std_id == peasycap_standard->v4l2_standard.id) - break; - peasycap_standard++; -} -if (0xFFFF == peasycap_standard->mask) { + struct easycap_standard const *peasycap_standard; + u16 reg, set; + int ir, rc, need, k; + unsigned int itwas, isnow; + bool resubmit; + + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (!peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; + } peasycap_standard = &easycap_standard[0]; while (0xFFFF != peasycap_standard->mask) { - if (std_id & peasycap_standard->v4l2_standard.id) + if (std_id == peasycap_standard->v4l2_standard.id) break; peasycap_standard++; } -} -if (0xFFFF == peasycap_standard->mask) { - SAM("ERROR: 0x%08X=std_id: standard not found\n", \ - (unsigned int)std_id); - return -EINVAL; -} -SAM("selected standard: %s\n", \ - &(peasycap_standard->v4l2_standard.name[0])); -if (peasycap->standard_offset == \ - (int)(peasycap_standard - &easycap_standard[0])) { - SAM("requested standard already in effect\n"); - return 0; -} -peasycap->standard_offset = (int)(peasycap_standard - &easycap_standard[0]); -for (k = 0; k < INPUT_MANY; k++) { - if (!peasycap->inputset[k].standard_offset_ok) { - peasycap->inputset[k].standard_offset = \ - peasycap->standard_offset; + if (0xFFFF == peasycap_standard->mask) { + peasycap_standard = &easycap_standard[0]; + while (0xFFFF != peasycap_standard->mask) { + if (std_id & peasycap_standard->v4l2_standard.id) + break; + peasycap_standard++; + } } -} -if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { - peasycap->inputset[peasycap->input].standard_offset = \ - peasycap->standard_offset; - peasycap->inputset[peasycap->input].standard_offset_ok = 1; -} else - JOM(8, "%i=peasycap->input\n", peasycap->input); -peasycap->fps = peasycap_standard->v4l2_standard.frameperiod.denominator / \ - peasycap_standard->v4l2_standard.frameperiod.numerator; -switch (peasycap->fps) { -case 6: -case 30: { - peasycap->ntsc = true; - break; -} -case 5: -case 25: { - peasycap->ntsc = false; - break; -} -default: { - SAM("MISTAKE: %i=frames-per-second\n", peasycap->fps); - return -ENOENT; -} -} -JOM(8, "%i frames-per-second\n", peasycap->fps); -if (0x8000 & peasycap_standard->mask) { - peasycap->skip = 5; - peasycap->usec = 1000000 / (2 * (5 * peasycap->fps)); - peasycap->tolerate = 1000 * (25 / (5 * peasycap->fps)); -} else { - peasycap->skip = 0; - peasycap->usec = 1000000 / (2 * peasycap->fps); - peasycap->tolerate = 1000 * (25 / peasycap->fps); -} -if (peasycap->video_isoc_streaming) { - resubmit = true; - kill_video_urbs(peasycap); -} else - resubmit = false; + if (0xFFFF == peasycap_standard->mask) { + SAM("ERROR: 0x%08X=std_id: standard not found\n", + (unsigned int)std_id); + return -EINVAL; + } + SAM("selected standard: %s\n", + &(peasycap_standard->v4l2_standard.name[0])); + if (peasycap->standard_offset == peasycap_standard - easycap_standard) { + SAM("requested standard already in effect\n"); + return 0; + } + peasycap->standard_offset = peasycap_standard - easycap_standard; + for (k = 0; k < INPUT_MANY; k++) { + if (!peasycap->inputset[k].standard_offset_ok) { + peasycap->inputset[k].standard_offset = + peasycap->standard_offset; + } + } + if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { + peasycap->inputset[peasycap->input].standard_offset = + peasycap->standard_offset; + peasycap->inputset[peasycap->input].standard_offset_ok = 1; + } else + JOM(8, "%i=peasycap->input\n", peasycap->input); + + peasycap->fps = peasycap_standard->v4l2_standard.frameperiod.denominator / + peasycap_standard->v4l2_standard.frameperiod.numerator; + switch (peasycap->fps) { + case 6: + case 30: { + peasycap->ntsc = true; + break; + } + case 5: + case 25: { + peasycap->ntsc = false; + break; + } + default: { + SAM("MISTAKE: %i=frames-per-second\n", peasycap->fps); + return -ENOENT; + } + } + JOM(8, "%i frames-per-second\n", peasycap->fps); + if (0x8000 & peasycap_standard->mask) { + peasycap->skip = 5; + peasycap->usec = 1000000 / (2 * (5 * peasycap->fps)); + peasycap->tolerate = 1000 * (25 / (5 * peasycap->fps)); + } else { + peasycap->skip = 0; + peasycap->usec = 1000000 / (2 * peasycap->fps); + peasycap->tolerate = 1000 * (25 / peasycap->fps); + } + if (peasycap->video_isoc_streaming) { + resubmit = true; + kill_video_urbs(peasycap); + } else + resubmit = false; /*--------------------------------------------------------------------------*/ /* * SAA7113H DATASHEET PAGE 44, TABLE 42 */ /*--------------------------------------------------------------------------*/ -need = 0; itwas = 0; reg = 0x00; set = 0x00; -switch (peasycap_standard->mask & 0x000F) { -case NTSC_M_JP: { - reg = 0x0A; set = 0x95; - ir = read_saa(peasycap->pusb_device, reg); - if (0 > ir) - SAM("ERROR: cannot read SAA register 0x%02X\n", reg); - else - itwas = (unsigned int)ir; - rc = write_saa(peasycap->pusb_device, reg, set); - if (0 != rc) - SAM("ERROR: failed to set SAA register " \ - "0x%02X to 0x%02X for JP standard\n", reg, set); - else { - isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); + need = 0; + itwas = 0; + reg = 0x00; + set = 0x00; + switch (peasycap_standard->mask & 0x000F) { + case NTSC_M_JP: { + reg = 0x0A; + set = 0x95; + ir = read_saa(peasycap->pusb_device, reg); if (0 > ir) - JOM(8, "SAA register 0x%02X changed " \ - "to 0x%02X\n", reg, isnow); + SAM("ERROR: cannot read SAA register 0x%02X\n", reg); else - JOM(8, "SAA register 0x%02X changed " \ - "from 0x%02X to 0x%02X\n", reg, itwas, isnow); - } + itwas = (unsigned int)ir; + rc = write_saa(peasycap->pusb_device, reg, set); + if (rc) + SAM("ERROR: failed to set SAA register " + "0x%02X to 0x%02X for JP standard\n", reg, set); + else { + isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); + if (0 > ir) + JOM(8, "SAA register 0x%02X changed " + "to 0x%02X\n", reg, isnow); + else + JOM(8, "SAA register 0x%02X changed " + "from 0x%02X to 0x%02X\n", reg, itwas, isnow); + } - reg = 0x0B; set = 0x48; - ir = read_saa(peasycap->pusb_device, reg); - if (0 > ir) - SAM("ERROR: cannot read SAA register 0x%02X\n", reg); - else - itwas = (unsigned int)ir; - rc = write_saa(peasycap->pusb_device, reg, set); - if (0 != rc) - SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X " \ - "for JP standard\n", reg, set); - else { - isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); + reg = 0x0B; + set = 0x48; + ir = read_saa(peasycap->pusb_device, reg); if (0 > ir) - JOM(8, "SAA register 0x%02X changed " \ - "to 0x%02X\n", reg, isnow); + SAM("ERROR: cannot read SAA register 0x%02X\n", reg); else - JOM(8, "SAA register 0x%02X changed " \ - "from 0x%02X to 0x%02X\n", reg, itwas, isnow); - } + itwas = (unsigned int)ir; + rc = write_saa(peasycap->pusb_device, reg, set); + if (rc) + SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X " + "for JP standard\n", reg, set); + else { + isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); + if (0 > ir) + JOM(8, "SAA register 0x%02X changed " + "to 0x%02X\n", reg, isnow); + else + JOM(8, "SAA register 0x%02X changed " + "from 0x%02X to 0x%02X\n", reg, itwas, isnow); + } /*--------------------------------------------------------------------------*/ /* * NOTE: NO break HERE: RUN ON TO NEXT CASE */ /*--------------------------------------------------------------------------*/ -} -case NTSC_M: -case PAL_BGHIN: { - reg = 0x0E; set = 0x01; need = 1; break; -} -case NTSC_N_443: -case PAL_60: { - reg = 0x0E; set = 0x11; need = 1; break; -} -case NTSC_443: -case PAL_Nc: { - reg = 0x0E; set = 0x21; need = 1; break; -} -case NTSC_N: -case PAL_M: { - reg = 0x0E; set = 0x31; need = 1; break; -} -case SECAM: { - reg = 0x0E; set = 0x51; need = 1; break; -} -default: - break; -} + } + case NTSC_M: + case PAL_BGHIN: { + reg = 0x0E; + set = 0x01; + need = 1; + break; + } + case NTSC_N_443: + case PAL_60: { + reg = 0x0E; + set = 0x11; + need = 1; + break; + } + case NTSC_443: + case PAL_Nc: { + reg = 0x0E; + set = 0x21; + need = 1; + break; + } + case NTSC_N: + case PAL_M: { + reg = 0x0E; + set = 0x31; + need = 1; + break; + } + case SECAM: { + reg = 0x0E; + set = 0x51; + need = 1; + break; + } + default: + break; + } /*--------------------------------------------------------------------------*/ -if (need) { - ir = read_saa(peasycap->pusb_device, reg); - if (0 > ir) - SAM("ERROR: failed to read SAA register 0x%02X\n", reg); - else - itwas = (unsigned int)ir; - rc = write_saa(peasycap->pusb_device, reg, set); - if (0 != write_saa(peasycap->pusb_device, reg, set)) { - SAM("ERROR: failed to set SAA register " \ - "0x%02X to 0x%02X for table 42\n", reg, set); - } else { - isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); + if (need) { + ir = read_saa(peasycap->pusb_device, reg); if (0 > ir) - JOM(8, "SAA register 0x%02X changed " \ - "to 0x%02X\n", reg, isnow); + SAM("ERROR: failed to read SAA register 0x%02X\n", reg); else - JOM(8, "SAA register 0x%02X changed " \ - "from 0x%02X to 0x%02X\n", reg, itwas, isnow); + itwas = (unsigned int)ir; + rc = write_saa(peasycap->pusb_device, reg, set); + if (0 != write_saa(peasycap->pusb_device, reg, set)) { + SAM("ERROR: failed to set SAA register " + "0x%02X to 0x%02X for table 42\n", reg, set); + } else { + isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); + if (0 > ir) + JOM(8, "SAA register 0x%02X changed " + "to 0x%02X\n", reg, isnow); + else + JOM(8, "SAA register 0x%02X changed " + "from 0x%02X to 0x%02X\n", reg, itwas, isnow); + } } -} /*--------------------------------------------------------------------------*/ /* - * SAA7113H DATASHEET PAGE 41 - */ + * SAA7113H DATASHEET PAGE 41 + */ /*--------------------------------------------------------------------------*/ -reg = 0x08; -ir = read_saa(peasycap->pusb_device, reg); -if (0 > ir) - SAM("ERROR: failed to read SAA register 0x%02X " \ - "so cannot reset\n", reg); -else { - itwas = (unsigned int)ir; - if (peasycap_standard->mask & 0x0001) - set = itwas | 0x40 ; - else - set = itwas & ~0x40 ; - rc = write_saa(peasycap->pusb_device, reg, set); - if (0 != rc) - SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", \ - reg, set); + reg = 0x08; + ir = read_saa(peasycap->pusb_device, reg); + if (0 > ir) + SAM("ERROR: failed to read SAA register 0x%02X " + "so cannot reset\n", reg); else { - isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); - if (0 > ir) - JOM(8, "SAA register 0x%02X changed to 0x%02X\n", \ - reg, isnow); + itwas = (unsigned int)ir; + if (peasycap_standard->mask & 0x0001) + set = itwas | 0x40 ; else - JOM(8, "SAA register 0x%02X changed " \ - "from 0x%02X to 0x%02X\n", reg, itwas, isnow); + set = itwas & ~0x40 ; + rc = write_saa(peasycap->pusb_device, reg, set); + if (rc) + SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", + reg, set); + else { + isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); + if (0 > ir) + JOM(8, "SAA register 0x%02X changed to 0x%02X\n", + reg, isnow); + else + JOM(8, "SAA register 0x%02X changed " + "from 0x%02X to 0x%02X\n", reg, itwas, isnow); + } } -} /*--------------------------------------------------------------------------*/ /* * SAA7113H DATASHEET PAGE 51, TABLE 57 */ /*---------------------------------------------------------------------------*/ -reg = 0x40; -ir = read_saa(peasycap->pusb_device, reg); -if (0 > ir) - SAM("ERROR: failed to read SAA register 0x%02X " \ - "so cannot reset\n", reg); -else { - itwas = (unsigned int)ir; - if (peasycap_standard->mask & 0x0001) - set = itwas | 0x80 ; - else - set = itwas & ~0x80 ; - rc = write_saa(peasycap->pusb_device, reg, set); - if (0 != rc) - SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", \ - reg, set); + reg = 0x40; + ir = read_saa(peasycap->pusb_device, reg); + if (0 > ir) + SAM("ERROR: failed to read SAA register 0x%02X " + "so cannot reset\n", reg); else { - isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); - if (0 > ir) - JOM(8, "SAA register 0x%02X changed to 0x%02X\n", \ - reg, isnow); + itwas = (unsigned int)ir; + if (peasycap_standard->mask & 0x0001) + set = itwas | 0x80 ; else - JOM(8, "SAA register 0x%02X changed " \ - "from 0x%02X to 0x%02X\n", reg, itwas, isnow); + set = itwas & ~0x80 ; + rc = write_saa(peasycap->pusb_device, reg, set); + if (rc) + SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", + reg, set); + else { + isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); + if (0 > ir) + JOM(8, "SAA register 0x%02X changed to 0x%02X\n", + reg, isnow); + else + JOM(8, "SAA register 0x%02X changed " + "from 0x%02X to 0x%02X\n", reg, itwas, isnow); + } } -} /*--------------------------------------------------------------------------*/ /* - * SAA7113H DATASHEET PAGE 53, TABLE 66 - */ + * SAA7113H DATASHEET PAGE 53, TABLE 66 + */ /*--------------------------------------------------------------------------*/ -reg = 0x5A; -ir = read_saa(peasycap->pusb_device, reg); -if (0 > ir) - SAM("ERROR: failed to read SAA register 0x%02X but continuing\n", reg); + reg = 0x5A; + ir = read_saa(peasycap->pusb_device, reg); + if (0 > ir) + SAM("ERROR: failed to read SAA register 0x%02X but continuing\n", reg); itwas = (unsigned int)ir; if (peasycap_standard->mask & 0x0001) set = 0x0A ; else set = 0x07 ; if (0 != write_saa(peasycap->pusb_device, reg, set)) - SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", \ - reg, set); + SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", + reg, set); else { isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); if (0 > ir) JOM(8, "SAA register 0x%02X changed " - "to 0x%02X\n", reg, isnow); + "to 0x%02X\n", reg, isnow); else JOM(8, "SAA register 0x%02X changed " - "from 0x%02X to 0x%02X\n", reg, itwas, isnow); + "from 0x%02X to 0x%02X\n", reg, itwas, isnow); } -if (true == resubmit) - submit_video_urbs(peasycap); -return 0; + if (resubmit) + submit_video_urbs(peasycap); + return 0; } /*****************************************************************************/ /*--------------------------------------------------------------------------*/ @@ -342,2478 +358,2121 @@ return 0; * ERRORS RETURN A NEGATIVE NUMBER. */ /*--------------------------------------------------------------------------*/ -int adjust_format(struct easycap *peasycap, \ - __u32 width, __u32 height, __u32 pixelformat, int field, bool try) +int adjust_format(struct easycap *peasycap, + u32 width, u32 height, u32 pixelformat, int field, bool try) { -struct easycap_format *peasycap_format, *peasycap_best_format; -__u16 mask; -struct usb_device *p; -int miss, multiplier, best, k; -char bf[5], fo[32], *pc; -__u32 uc; -bool resubmit; - -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if (0 > peasycap->standard_offset) { - JOM(8, "%i=peasycap->standard_offset\n", peasycap->standard_offset); - return -EBUSY; -} -p = peasycap->pusb_device; -if ((struct usb_device *)NULL == p) { - SAM("ERROR: peaycap->pusb_device is NULL\n"); - return -EFAULT; -} -pc = &bf[0]; -uc = pixelformat; -memcpy((void *)pc, (void *)(&uc), 4); -bf[4] = 0; -mask = 0xFF & easycap_standard[peasycap->standard_offset].mask; -SAM("sought: %ix%i,%s(0x%08X),%i=field,0x%02X=std mask\n", \ - width, height, pc, pixelformat, field, mask); -switch (field) { -case V4L2_FIELD_ANY: { - strcpy(&fo[0], "V4L2_FIELD_ANY "); - break; -} -case V4L2_FIELD_NONE: { - strcpy(&fo[0], "V4L2_FIELD_NONE"); - break; -} -case V4L2_FIELD_TOP: { - strcpy(&fo[0], "V4L2_FIELD_TOP"); - break; -} -case V4L2_FIELD_BOTTOM: { - strcpy(&fo[0], "V4L2_FIELD_BOTTOM"); - break; -} -case V4L2_FIELD_INTERLACED: { - strcpy(&fo[0], "V4L2_FIELD_INTERLACED"); - break; -} -case V4L2_FIELD_SEQ_TB: { - strcpy(&fo[0], "V4L2_FIELD_SEQ_TB"); - break; -} -case V4L2_FIELD_SEQ_BT: { - strcpy(&fo[0], "V4L2_FIELD_SEQ_BT"); - break; -} -case V4L2_FIELD_ALTERNATE: { - strcpy(&fo[0], "V4L2_FIELD_ALTERNATE"); - break; -} -case V4L2_FIELD_INTERLACED_TB: { - strcpy(&fo[0], "V4L2_FIELD_INTERLACED_TB"); - break; -} -case V4L2_FIELD_INTERLACED_BT: { - strcpy(&fo[0], "V4L2_FIELD_INTERLACED_BT"); - break; -} -default: { - strcpy(&fo[0], "V4L2_FIELD_... UNKNOWN "); - break; -} -} -SAM("sought: %s\n", &fo[0]); -if (V4L2_FIELD_ANY == field) { - field = V4L2_FIELD_NONE; - SAM("prefer: V4L2_FIELD_NONE=field, was V4L2_FIELD_ANY\n"); -} -peasycap_best_format = (struct easycap_format *)NULL; -peasycap_format = &easycap_format[0]; -while (0 != peasycap_format->v4l2_format.fmt.pix.width) { - JOM(16, ".> %i %i 0x%08X %ix%i\n", \ - peasycap_format->mask & 0x01, - peasycap_format->v4l2_format.fmt.pix.field, - peasycap_format->v4l2_format.fmt.pix.pixelformat, - peasycap_format->v4l2_format.fmt.pix.width, - peasycap_format->v4l2_format.fmt.pix.height); - - if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) && \ - (peasycap_format->v4l2_format.fmt.pix.field == field) && \ - (peasycap_format->v4l2_format.fmt.pix.pixelformat == \ - pixelformat) && \ - (peasycap_format->v4l2_format.fmt.pix.width == width) && \ - (peasycap_format->v4l2_format.fmt.pix.height == height)) { + struct easycap_format *peasycap_format, *peasycap_best_format; + u16 mask; + struct usb_device *p; + int miss, multiplier, best, k; + char bf[5], fo[32], *pc; + u32 uc; + bool resubmit; + + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (0 > peasycap->standard_offset) { + JOM(8, "%i=peasycap->standard_offset\n", peasycap->standard_offset); + return -EBUSY; + } + p = peasycap->pusb_device; + if (!p) { + SAM("ERROR: peaycap->pusb_device is NULL\n"); + return -EFAULT; + } + pc = &bf[0]; + uc = pixelformat; + memcpy((void *)pc, (void *)(&uc), 4); + bf[4] = 0; + mask = 0xFF & easycap_standard[peasycap->standard_offset].mask; + SAM("sought: %ix%i,%s(0x%08X),%i=field,0x%02X=std mask\n", + width, height, pc, pixelformat, field, mask); + switch (field) { + case V4L2_FIELD_ANY: { + strcpy(&fo[0], "V4L2_FIELD_ANY "); + break; + } + case V4L2_FIELD_NONE: { + strcpy(&fo[0], "V4L2_FIELD_NONE"); + break; + } + case V4L2_FIELD_TOP: { + strcpy(&fo[0], "V4L2_FIELD_TOP"); + break; + } + case V4L2_FIELD_BOTTOM: { + strcpy(&fo[0], "V4L2_FIELD_BOTTOM"); + break; + } + case V4L2_FIELD_INTERLACED: { + strcpy(&fo[0], "V4L2_FIELD_INTERLACED"); + break; + } + case V4L2_FIELD_SEQ_TB: { + strcpy(&fo[0], "V4L2_FIELD_SEQ_TB"); + break; + } + case V4L2_FIELD_SEQ_BT: { + strcpy(&fo[0], "V4L2_FIELD_SEQ_BT"); + break; + } + case V4L2_FIELD_ALTERNATE: { + strcpy(&fo[0], "V4L2_FIELD_ALTERNATE"); + break; + } + case V4L2_FIELD_INTERLACED_TB: { + strcpy(&fo[0], "V4L2_FIELD_INTERLACED_TB"); + break; + } + case V4L2_FIELD_INTERLACED_BT: { + strcpy(&fo[0], "V4L2_FIELD_INTERLACED_BT"); + break; + } + default: { + strcpy(&fo[0], "V4L2_FIELD_... UNKNOWN "); + break; + } + } + SAM("sought: %s\n", &fo[0]); + if (V4L2_FIELD_ANY == field) { + field = V4L2_FIELD_NONE; + SAM("prefer: V4L2_FIELD_NONE=field, was V4L2_FIELD_ANY\n"); + } + peasycap_best_format = NULL; + peasycap_format = &easycap_format[0]; + while (0 != peasycap_format->v4l2_format.fmt.pix.width) { + JOM(16, ".> %i %i 0x%08X %ix%i\n", + peasycap_format->mask & 0x01, + peasycap_format->v4l2_format.fmt.pix.field, + peasycap_format->v4l2_format.fmt.pix.pixelformat, + peasycap_format->v4l2_format.fmt.pix.width, + peasycap_format->v4l2_format.fmt.pix.height); + + if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) && + (peasycap_format->v4l2_format.fmt.pix.field == field) && + (peasycap_format->v4l2_format.fmt.pix.pixelformat == pixelformat) && + (peasycap_format->v4l2_format.fmt.pix.width == width) && + (peasycap_format->v4l2_format.fmt.pix.height == height)) { + peasycap_best_format = peasycap_format; break; } - peasycap_format++; -} -if (0 == peasycap_format->v4l2_format.fmt.pix.width) { - SAM("cannot do: %ix%i with standard mask 0x%02X\n", \ - width, height, mask); - peasycap_format = &easycap_format[0]; best = -1; - while (0 != peasycap_format->v4l2_format.fmt.pix.width) { - if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) && \ - (peasycap_format->v4l2_format.fmt.pix\ - .field == field) && \ - (peasycap_format->v4l2_format.fmt.pix\ - .pixelformat == pixelformat)) { - miss = abs(peasycap_format->\ - v4l2_format.fmt.pix.width - width); - if ((best > miss) || (best < 0)) { - best = miss; - peasycap_best_format = peasycap_format; - if (!miss) - break; + peasycap_format++; + } + if (0 == peasycap_format->v4l2_format.fmt.pix.width) { + SAM("cannot do: %ix%i with standard mask 0x%02X\n", + width, height, mask); + peasycap_format = &easycap_format[0]; + best = -1; + while (0 != peasycap_format->v4l2_format.fmt.pix.width) { + if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) && + (peasycap_format->v4l2_format.fmt.pix.field == field) && + (peasycap_format->v4l2_format.fmt.pix.pixelformat == pixelformat)) { + + miss = abs(peasycap_format->v4l2_format.fmt.pix.width - width); + if ((best > miss) || (best < 0)) { + best = miss; + peasycap_best_format = peasycap_format; + if (!miss) + break; + } } + peasycap_format++; + } + if (-1 == best) { + SAM("cannot do %ix... with standard mask 0x%02X\n", + width, mask); + SAM("cannot do ...x%i with standard mask 0x%02X\n", + height, mask); + SAM(" %ix%i unmatched\n", width, height); + return peasycap->format_offset; } - peasycap_format++; } - if (-1 == best) { - SAM("cannot do %ix... with standard mask 0x%02X\n", \ - width, mask); - SAM("cannot do ...x%i with standard mask 0x%02X\n", \ - height, mask); - SAM(" %ix%i unmatched\n", width, height); - return peasycap->format_offset; + if (!peasycap_best_format) { + SAM("MISTAKE: peasycap_best_format is NULL"); + return -EINVAL; } -} -if ((struct easycap_format *)NULL == peasycap_best_format) { - SAM("MISTAKE: peasycap_best_format is NULL"); - return -EINVAL; -} -peasycap_format = peasycap_best_format; + peasycap_format = peasycap_best_format; /*...........................................................................*/ -if (true == try) - return (int)(peasycap_best_format - &easycap_format[0]); + if (try) + return peasycap_best_format - easycap_format; /*...........................................................................*/ -if (false != try) { - SAM("MISTAKE: true==try where is should be false\n"); - return -EINVAL; -} -SAM("actioning: %ix%i %s\n", \ - peasycap_format->v4l2_format.fmt.pix.width, \ - peasycap_format->v4l2_format.fmt.pix.height, - &peasycap_format->name[0]); -peasycap->height = peasycap_format->v4l2_format.fmt.pix.height; -peasycap->width = peasycap_format->v4l2_format.fmt.pix.width; -peasycap->pixelformat = peasycap_format->v4l2_format.fmt.pix.pixelformat; -peasycap->format_offset = (int)(peasycap_format - &easycap_format[0]); + if (false != try) { + SAM("MISTAKE: true==try where is should be false\n"); + return -EINVAL; + } + SAM("actioning: %ix%i %s\n", + peasycap_format->v4l2_format.fmt.pix.width, + peasycap_format->v4l2_format.fmt.pix.height, + &peasycap_format->name[0]); + peasycap->height = peasycap_format->v4l2_format.fmt.pix.height; + peasycap->width = peasycap_format->v4l2_format.fmt.pix.width; + peasycap->pixelformat = peasycap_format->v4l2_format.fmt.pix.pixelformat; + peasycap->format_offset = peasycap_format - easycap_format; -for (k = 0; k < INPUT_MANY; k++) { - if (!peasycap->inputset[k].format_offset_ok) { - peasycap->inputset[k].format_offset = \ - peasycap->format_offset; + for (k = 0; k < INPUT_MANY; k++) { + if (!peasycap->inputset[k].format_offset_ok) { + peasycap->inputset[k].format_offset = + peasycap->format_offset; + } } -} -if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { - peasycap->inputset[peasycap->input].format_offset = \ - peasycap->format_offset; - peasycap->inputset[peasycap->input].format_offset_ok = 1; -} else - JOM(8, "%i=peasycap->input\n", peasycap->input); - - - -peasycap->bytesperpixel = (0x00E0 & peasycap_format->mask) >> 5 ; -if (0x0100 & peasycap_format->mask) - peasycap->byteswaporder = true; -else - peasycap->byteswaporder = false; -if (0x0200 & peasycap_format->mask) - peasycap->skip = 5; -else - peasycap->skip = 0; -if (0x0800 & peasycap_format->mask) - peasycap->decimatepixel = true; -else - peasycap->decimatepixel = false; -if (0x1000 & peasycap_format->mask) - peasycap->offerfields = true; -else - peasycap->offerfields = false; -if (true == peasycap->decimatepixel) - multiplier = 2; -else - multiplier = 1; -peasycap->videofieldamount = multiplier * peasycap->width * \ - multiplier * peasycap->height; -peasycap->frame_buffer_used = peasycap->bytesperpixel * \ - peasycap->width * peasycap->height; -if (peasycap->video_isoc_streaming) { - resubmit = true; - kill_video_urbs(peasycap); -} else - resubmit = false; + if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { + peasycap->inputset[peasycap->input].format_offset = + peasycap->format_offset; + peasycap->inputset[peasycap->input].format_offset_ok = 1; + } else + JOM(8, "%i=peasycap->input\n", peasycap->input); + + + + peasycap->bytesperpixel = (0x00E0 & peasycap_format->mask) >> 5 ; + if (0x0100 & peasycap_format->mask) + peasycap->byteswaporder = true; + else + peasycap->byteswaporder = false; + if (0x0200 & peasycap_format->mask) + peasycap->skip = 5; + else + peasycap->skip = 0; + if (0x0800 & peasycap_format->mask) + peasycap->decimatepixel = true; + else + peasycap->decimatepixel = false; + if (0x1000 & peasycap_format->mask) + peasycap->offerfields = true; + else + peasycap->offerfields = false; + if (peasycap->decimatepixel) + multiplier = 2; + else + multiplier = 1; + peasycap->videofieldamount = + multiplier * peasycap->width * multiplier * peasycap->height; + peasycap->frame_buffer_used = + peasycap->bytesperpixel * peasycap->width * peasycap->height; + if (peasycap->video_isoc_streaming) { + resubmit = true; + kill_video_urbs(peasycap); + } else + resubmit = false; /*---------------------------------------------------------------------------*/ /* - * PAL - */ + * PAL + */ /*---------------------------------------------------------------------------*/ -if (0 == (0x01 & peasycap_format->mask)) { - if (((720 == peasycap_format->v4l2_format.fmt.pix.width) && \ - (576 == \ - peasycap_format->v4l2_format.fmt.pix.height)) || \ - ((360 == \ - peasycap_format->v4l2_format.fmt.pix.width) && \ - (288 == \ - peasycap_format->v4l2_format.fmt.pix.height))) { - if (0 != set_resolution(p, 0x0000, 0x0001, 0x05A0, 0x0121)) { - SAM("ERROR: set_resolution() failed\n"); - return -EINVAL; - } - } else if ((704 == peasycap_format->v4l2_format.fmt.pix.width) && \ - (576 == peasycap_format->v4l2_format.fmt.pix.height)) { - if (0 != set_resolution(p, 0x0004, 0x0001, 0x0584, 0x0121)) { - SAM("ERROR: set_resolution() failed\n"); - return -EINVAL; - } - } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) && \ - (480 == \ - peasycap_format->v4l2_format.fmt.pix.height)) || \ - ((320 == \ - peasycap_format->v4l2_format.fmt.pix.width) && \ - (240 == \ - peasycap_format->v4l2_format.fmt.pix.height))) { - if (0 != set_resolution(p, 0x0014, 0x0020, 0x0514, 0x0110)) { - SAM("ERROR: set_resolution() failed\n"); + if (0 == (0x01 & peasycap_format->mask)) { + if (((720 == peasycap_format->v4l2_format.fmt.pix.width) && + (576 == peasycap_format->v4l2_format.fmt.pix.height)) || + ((360 == peasycap_format->v4l2_format.fmt.pix.width) && + (288 == peasycap_format->v4l2_format.fmt.pix.height))) { + if (set_resolution(p, 0x0000, 0x0001, 0x05A0, 0x0121)) { + SAM("ERROR: set_resolution() failed\n"); + return -EINVAL; + } + } else if ((704 == peasycap_format->v4l2_format.fmt.pix.width) && + (576 == peasycap_format->v4l2_format.fmt.pix.height)) { + if (set_resolution(p, 0x0004, 0x0001, 0x0584, 0x0121)) { + SAM("ERROR: set_resolution() failed\n"); + return -EINVAL; + } + } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) && + (480 == peasycap_format->v4l2_format.fmt.pix.height)) || + ((320 == peasycap_format->v4l2_format.fmt.pix.width) && + (240 == peasycap_format->v4l2_format.fmt.pix.height))) { + if (set_resolution(p, 0x0014, 0x0020, 0x0514, 0x0110)) { + SAM("ERROR: set_resolution() failed\n"); + return -EINVAL; + } + } else { + SAM("MISTAKE: bad format, cannot set resolution\n"); return -EINVAL; } - } else { - SAM("MISTAKE: bad format, cannot set resolution\n"); - return -EINVAL; - } /*---------------------------------------------------------------------------*/ /* * NTSC */ /*---------------------------------------------------------------------------*/ -} else { - if (((720 == peasycap_format->v4l2_format.fmt.pix.width) && \ - (480 == \ - peasycap_format->v4l2_format.fmt.pix.height)) || \ - ((360 == \ - peasycap_format->v4l2_format.fmt.pix.width) && \ - (240 == \ - peasycap_format->v4l2_format.fmt.pix.height))) { - if (0 != set_resolution(p, 0x0000, 0x0003, 0x05A0, 0x00F3)) { - SAM("ERROR: set_resolution() failed\n"); - return -EINVAL; - } - } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) && \ - (480 == \ - peasycap_format->v4l2_format.fmt.pix.height)) || \ - ((320 == \ - peasycap_format->v4l2_format.fmt.pix.width) && \ - (240 == \ - peasycap_format->v4l2_format.fmt.pix.height))) { - if (0 != set_resolution(p, 0x0014, 0x0003, 0x0514, 0x00F3)) { - SAM("ERROR: set_resolution() failed\n"); + } else { + if (((720 == peasycap_format->v4l2_format.fmt.pix.width) && + (480 == peasycap_format->v4l2_format.fmt.pix.height)) || + ((360 == peasycap_format->v4l2_format.fmt.pix.width) && + (240 == peasycap_format->v4l2_format.fmt.pix.height))) { + if (set_resolution(p, 0x0000, 0x0003, 0x05A0, 0x00F3)) { + SAM("ERROR: set_resolution() failed\n"); + return -EINVAL; + } + } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) && + (480 == peasycap_format->v4l2_format.fmt.pix.height)) || + ((320 == peasycap_format->v4l2_format.fmt.pix.width) && + (240 == peasycap_format->v4l2_format.fmt.pix.height))) { + if (set_resolution(p, 0x0014, 0x0003, 0x0514, 0x00F3)) { + SAM("ERROR: set_resolution() failed\n"); + return -EINVAL; + } + } else { + SAM("MISTAKE: bad format, cannot set resolution\n"); return -EINVAL; } - } else { - SAM("MISTAKE: bad format, cannot set resolution\n"); - return -EINVAL; } -} /*---------------------------------------------------------------------------*/ -if (true == resubmit) - submit_video_urbs(peasycap); -return (int)(peasycap_best_format - &easycap_format[0]); + if (resubmit) + submit_video_urbs(peasycap); + + return peasycap_best_format - easycap_format; } /*****************************************************************************/ int adjust_brightness(struct easycap *peasycap, int value) { -unsigned int mood; -int i1, k; + unsigned int mood; + int i1, k; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -i1 = 0; -while (0xFFFFFFFF != easycap_control[i1].id) { - if (V4L2_CID_BRIGHTNESS == easycap_control[i1].id) { - if ((easycap_control[i1].minimum > value) || \ - (easycap_control[i1].maximum < value)) - value = easycap_control[i1].default_value; - - if ((easycap_control[i1].minimum <= peasycap->brightness) && \ - (easycap_control[i1].maximum >= \ - peasycap->brightness)) { - if (peasycap->brightness == value) { - SAM("unchanged brightness at 0x%02X\n", \ - value); + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (!peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; + } + i1 = 0; + while (0xFFFFFFFF != easycap_control[i1].id) { + if (V4L2_CID_BRIGHTNESS == easycap_control[i1].id) { + if ((easycap_control[i1].minimum > value) || + (easycap_control[i1].maximum < value)) + value = easycap_control[i1].default_value; + + if ((easycap_control[i1].minimum <= peasycap->brightness) && + (easycap_control[i1].maximum >= peasycap->brightness)) { + if (peasycap->brightness == value) { + SAM("unchanged brightness at 0x%02X\n", + value); + return 0; + } + } + peasycap->brightness = value; + for (k = 0; k < INPUT_MANY; k++) { + if (!peasycap->inputset[k].brightness_ok) + peasycap->inputset[k].brightness = + peasycap->brightness; + } + if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { + peasycap->inputset[peasycap->input].brightness = + peasycap->brightness; + peasycap->inputset[peasycap->input].brightness_ok = 1; + } else + JOM(8, "%i=peasycap->input\n", peasycap->input); + mood = 0x00FF & (unsigned int)peasycap->brightness; + if (!write_saa(peasycap->pusb_device, 0x0A, mood)) { + SAM("adjusting brightness to 0x%02X\n", mood); return 0; + } else { + SAM("WARNING: failed to adjust brightness " + "to 0x%02X\n", mood); + return -ENOENT; } + break; } - peasycap->brightness = value; - for (k = 0; k < INPUT_MANY; k++) { - if (!peasycap->inputset[k].brightness_ok) - peasycap->inputset[k].brightness = \ - peasycap->brightness; - } - if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { - peasycap->inputset[peasycap->input].brightness = \ - peasycap->brightness; - peasycap->inputset[peasycap->input].brightness_ok = 1; - } else - JOM(8, "%i=peasycap->input\n", peasycap->input); - mood = 0x00FF & (unsigned int)peasycap->brightness; - if (!write_saa(peasycap->pusb_device, 0x0A, mood)) { - SAM("adjusting brightness to 0x%02X\n", mood); - return 0; - } else { - SAM("WARNING: failed to adjust brightness " \ - "to 0x%02X\n", mood); - return -ENOENT; - } - break; + i1++; } - i1++; -} -SAM("WARNING: failed to adjust brightness: control not found\n"); -return -ENOENT; + SAM("WARNING: failed to adjust brightness: control not found\n"); + return -ENOENT; } /*****************************************************************************/ int adjust_contrast(struct easycap *peasycap, int value) { -unsigned int mood; -int i1, k; - -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -i1 = 0; -while (0xFFFFFFFF != easycap_control[i1].id) { - if (V4L2_CID_CONTRAST == easycap_control[i1].id) { - if ((easycap_control[i1].minimum > value) || \ - (easycap_control[i1].maximum < value)) - value = easycap_control[i1].default_value; + unsigned int mood; + int i1, k; + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (!peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; + } + i1 = 0; + while (0xFFFFFFFF != easycap_control[i1].id) { + if (V4L2_CID_CONTRAST == easycap_control[i1].id) { + if ((easycap_control[i1].minimum > value) || + (easycap_control[i1].maximum < value)) + value = easycap_control[i1].default_value; + + + if ((easycap_control[i1].minimum <= peasycap->contrast) && + (easycap_control[i1].maximum >= peasycap->contrast)) { + if (peasycap->contrast == value) { + SAM("unchanged contrast at 0x%02X\n", value); + return 0; + } + } + peasycap->contrast = value; + for (k = 0; k < INPUT_MANY; k++) { + if (!peasycap->inputset[k].contrast_ok) + peasycap->inputset[k].contrast = peasycap->contrast; + } + if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { + peasycap->inputset[peasycap->input].contrast = + peasycap->contrast; + peasycap->inputset[peasycap->input].contrast_ok = 1; + } else + JOM(8, "%i=peasycap->input\n", peasycap->input); - if ((easycap_control[i1].minimum <= peasycap->contrast) && \ - (easycap_control[i1].maximum >= \ - peasycap->contrast)) { - if (peasycap->contrast == value) { - SAM("unchanged contrast at 0x%02X\n", value); + mood = 0x00FF & (unsigned int) (peasycap->contrast - 128); + if (!write_saa(peasycap->pusb_device, 0x0B, mood)) { + SAM("adjusting contrast to 0x%02X\n", mood); return 0; + } else { + SAM("WARNING: failed to adjust contrast to " + "0x%02X\n", mood); + return -ENOENT; } + break; } - peasycap->contrast = value; - for (k = 0; k < INPUT_MANY; k++) { - if (!peasycap->inputset[k].contrast_ok) { - peasycap->inputset[k].contrast = \ - peasycap->contrast; - } - } - if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { - peasycap->inputset[peasycap->input].contrast = \ - peasycap->contrast; - peasycap->inputset[peasycap->input].contrast_ok = 1; - } else - JOM(8, "%i=peasycap->input\n", peasycap->input); - mood = 0x00FF & (unsigned int) (peasycap->contrast - 128); - if (!write_saa(peasycap->pusb_device, 0x0B, mood)) { - SAM("adjusting contrast to 0x%02X\n", mood); - return 0; - } else { - SAM("WARNING: failed to adjust contrast to " \ - "0x%02X\n", mood); - return -ENOENT; - } - break; + i1++; } - i1++; -} -SAM("WARNING: failed to adjust contrast: control not found\n"); -return -ENOENT; + SAM("WARNING: failed to adjust contrast: control not found\n"); + return -ENOENT; } /*****************************************************************************/ int adjust_saturation(struct easycap *peasycap, int value) { -unsigned int mood; -int i1, k; + unsigned int mood; + int i1, k; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -i1 = 0; -while (0xFFFFFFFF != easycap_control[i1].id) { - if (V4L2_CID_SATURATION == easycap_control[i1].id) { - if ((easycap_control[i1].minimum > value) || \ - (easycap_control[i1].maximum < value)) - value = easycap_control[i1].default_value; - - - if ((easycap_control[i1].minimum <= peasycap->saturation) && \ - (easycap_control[i1].maximum >= \ - peasycap->saturation)) { - if (peasycap->saturation == value) { - SAM("unchanged saturation at 0x%02X\n", \ - value); - return 0; + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (!peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; + } + i1 = 0; + while (0xFFFFFFFF != easycap_control[i1].id) { + if (V4L2_CID_SATURATION == easycap_control[i1].id) { + if ((easycap_control[i1].minimum > value) || + (easycap_control[i1].maximum < value)) + value = easycap_control[i1].default_value; + + + if ((easycap_control[i1].minimum <= peasycap->saturation) && + (easycap_control[i1].maximum >= peasycap->saturation)) { + if (peasycap->saturation == value) { + SAM("unchanged saturation at 0x%02X\n", + value); + return 0; + } } - } - peasycap->saturation = value; - for (k = 0; k < INPUT_MANY; k++) { - if (!peasycap->inputset[k].saturation_ok) { - peasycap->inputset[k].saturation = \ - peasycap->saturation; + peasycap->saturation = value; + for (k = 0; k < INPUT_MANY; k++) { + if (!peasycap->inputset[k].saturation_ok) + peasycap->inputset[k].saturation = + peasycap->saturation; } + if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { + peasycap->inputset[peasycap->input].saturation = + peasycap->saturation; + peasycap->inputset[peasycap->input].saturation_ok = 1; + } else + JOM(8, "%i=peasycap->input\n", peasycap->input); + mood = 0x00FF & (unsigned int) (peasycap->saturation - 128); + if (!write_saa(peasycap->pusb_device, 0x0C, mood)) { + SAM("adjusting saturation to 0x%02X\n", mood); + return 0; + } else { + SAM("WARNING: failed to adjust saturation to " + "0x%02X\n", mood); + return -ENOENT; + } + break; } - if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { - peasycap->inputset[peasycap->input].saturation = \ - peasycap->saturation; - peasycap->inputset[peasycap->input].saturation_ok = 1; - } else - JOM(8, "%i=peasycap->input\n", peasycap->input); - mood = 0x00FF & (unsigned int) (peasycap->saturation - 128); - if (!write_saa(peasycap->pusb_device, 0x0C, mood)) { - SAM("adjusting saturation to 0x%02X\n", mood); - return 0; - } else { - SAM("WARNING: failed to adjust saturation to " \ - "0x%02X\n", mood); - return -ENOENT; - } - break; + i1++; } - i1++; -} -SAM("WARNING: failed to adjust saturation: control not found\n"); -return -ENOENT; + SAM("WARNING: failed to adjust saturation: control not found\n"); + return -ENOENT; } /*****************************************************************************/ int adjust_hue(struct easycap *peasycap, int value) { -unsigned int mood; -int i1, i2, k; + unsigned int mood; + int i1, i2, k; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -i1 = 0; -while (0xFFFFFFFF != easycap_control[i1].id) { - if (V4L2_CID_HUE == easycap_control[i1].id) { - if ((easycap_control[i1].minimum > value) || \ - (easycap_control[i1].maximum < value)) - value = easycap_control[i1].default_value; - - if ((easycap_control[i1].minimum <= peasycap->hue) && \ - (easycap_control[i1].maximum >= \ - peasycap->hue)) { - if (peasycap->hue == value) { - SAM("unchanged hue at 0x%02X\n", value); + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (!peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; + } + i1 = 0; + while (0xFFFFFFFF != easycap_control[i1].id) { + if (V4L2_CID_HUE == easycap_control[i1].id) { + if ((easycap_control[i1].minimum > value) || + (easycap_control[i1].maximum < value)) + value = easycap_control[i1].default_value; + + if ((easycap_control[i1].minimum <= peasycap->hue) && + (easycap_control[i1].maximum >= peasycap->hue)) { + if (peasycap->hue == value) { + SAM("unchanged hue at 0x%02X\n", value); + return 0; + } + } + peasycap->hue = value; + for (k = 0; k < INPUT_MANY; k++) { + if (!peasycap->inputset[k].hue_ok) + peasycap->inputset[k].hue = peasycap->hue; + } + if (0 <= peasycap->input && INPUT_MANY > peasycap->input) { + peasycap->inputset[peasycap->input].hue = peasycap->hue; + peasycap->inputset[peasycap->input].hue_ok = 1; + } else + JOM(8, "%i=peasycap->input\n", peasycap->input); + i2 = peasycap->hue - 128; + mood = 0x00FF & ((int) i2); + if (!write_saa(peasycap->pusb_device, 0x0D, mood)) { + SAM("adjusting hue to 0x%02X\n", mood); return 0; + } else { + SAM("WARNING: failed to adjust hue to 0x%02X\n", mood); + return -ENOENT; } + break; } - peasycap->hue = value; - for (k = 0; k < INPUT_MANY; k++) { - if (!peasycap->inputset[k].hue_ok) - peasycap->inputset[k].hue = peasycap->hue; - } - if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { - peasycap->inputset[peasycap->input].hue = \ - peasycap->hue; - peasycap->inputset[peasycap->input].hue_ok = 1; - } else - JOM(8, "%i=peasycap->input\n", peasycap->input); - i2 = peasycap->hue - 128; - mood = 0x00FF & ((int) i2); - if (!write_saa(peasycap->pusb_device, 0x0D, mood)) { - SAM("adjusting hue to 0x%02X\n", mood); - return 0; - } else { - SAM("WARNING: failed to adjust hue to 0x%02X\n", mood); - return -ENOENT; - } - break; + i1++; } - i1++; -} -SAM("WARNING: failed to adjust hue: control not found\n"); -return -ENOENT; + SAM("WARNING: failed to adjust hue: control not found\n"); + return -ENOENT; } /*****************************************************************************/ int adjust_volume(struct easycap *peasycap, int value) { -__s8 mood; -int i1; + s8 mood; + int i1; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -i1 = 0; -while (0xFFFFFFFF != easycap_control[i1].id) { - if (V4L2_CID_AUDIO_VOLUME == easycap_control[i1].id) { - if ((easycap_control[i1].minimum > value) || \ - (easycap_control[i1].maximum < value)) - value = easycap_control[i1].default_value; - if ((easycap_control[i1].minimum <= peasycap->volume) && \ - (easycap_control[i1].maximum >= \ - peasycap->volume)) { - if (peasycap->volume == value) { - SAM("unchanged volume at 0x%02X\n", value); + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (!peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; + } + i1 = 0; + while (0xFFFFFFFF != easycap_control[i1].id) { + if (V4L2_CID_AUDIO_VOLUME == easycap_control[i1].id) { + if ((easycap_control[i1].minimum > value) || + (easycap_control[i1].maximum < value)) + value = easycap_control[i1].default_value; + + if ((easycap_control[i1].minimum <= peasycap->volume) && + (easycap_control[i1].maximum >= peasycap->volume)) { + if (peasycap->volume == value) { + SAM("unchanged volume at 0x%02X\n", value); + return 0; + } + } + peasycap->volume = value; + mood = (16 > peasycap->volume) ? 16 : + ((31 < peasycap->volume) ? 31 : + (s8) peasycap->volume); + if (!audio_gainset(peasycap->pusb_device, mood)) { + SAM("adjusting volume to 0x%02X\n", mood); return 0; + } else { + SAM("WARNING: failed to adjust volume to " + "0x%2X\n", mood); + return -ENOENT; } + break; } - peasycap->volume = value; - mood = (16 > peasycap->volume) ? 16 : \ - ((31 < peasycap->volume) ? 31 : \ - (__s8) peasycap->volume); - if (!audio_gainset(peasycap->pusb_device, mood)) { - SAM("adjusting volume to 0x%02X\n", mood); - return 0; - } else { - SAM("WARNING: failed to adjust volume to " \ - "0x%2X\n", mood); - return -ENOENT; - } - break; + i1++; } -i1++; -} -SAM("WARNING: failed to adjust volume: control not found\n"); -return -ENOENT; + SAM("WARNING: failed to adjust volume: control not found\n"); + return -ENOENT; } /*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* * AN ALTERNATIVE METHOD OF MUTING MIGHT SEEM TO BE: - * usb_set_interface(peasycap->pusb_device, \ - * peasycap->audio_interface, \ + * usb_set_interface(peasycap->pusb_device, + * peasycap->audio_interface, * peasycap->audio_altsetting_off); * HOWEVER, AFTER THIS COMMAND IS ISSUED ALL SUBSEQUENT URBS RECEIVE STATUS - * -ESHUTDOWN. THE HANDLER ROUTINE easysnd_complete() DECLINES TO RESUBMIT + * -ESHUTDOWN. THE HANDLER ROUTINE easyxxx_complete() DECLINES TO RESUBMIT * THE URB AND THE PIPELINE COLLAPSES IRRETRIEVABLY. BEWARE. */ /*---------------------------------------------------------------------------*/ -int adjust_mute(struct easycap *peasycap, int value) +static int adjust_mute(struct easycap *peasycap, int value) { -int i1; + int i1; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -i1 = 0; -while (0xFFFFFFFF != easycap_control[i1].id) { - if (V4L2_CID_AUDIO_MUTE == easycap_control[i1].id) { - peasycap->mute = value; - switch (peasycap->mute) { - case 1: { - peasycap->audio_idle = 1; - peasycap->timeval0.tv_sec = 0; - SAM("adjusting mute: %i=peasycap->audio_idle\n", \ - peasycap->audio_idle); - return 0; - } - default: { - peasycap->audio_idle = 0; - SAM("adjusting mute: %i=peasycap->audio_idle\n", \ - peasycap->audio_idle); - return 0; - } + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (!peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; + } + i1 = 0; + while (0xFFFFFFFF != easycap_control[i1].id) { + if (V4L2_CID_AUDIO_MUTE == easycap_control[i1].id) { + peasycap->mute = value; + switch (peasycap->mute) { + case 1: { + peasycap->audio_idle = 1; + peasycap->timeval0.tv_sec = 0; + SAM("adjusting mute: %i=peasycap->audio_idle\n", + peasycap->audio_idle); + return 0; + } + default: { + peasycap->audio_idle = 0; + SAM("adjusting mute: %i=peasycap->audio_idle\n", + peasycap->audio_idle); + return 0; + } + } + break; } - break; + i1++; } - i1++; -} -SAM("WARNING: failed to adjust mute: control not found\n"); -return -ENOENT; -} -/*****************************************************************************/ -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if ((defined(EASYCAP_IS_VIDEODEV_CLIENT)) || \ - (defined(EASYCAP_NEEDS_UNLOCKED_IOCTL))) -long -easycap_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg) { - return (long)easycap_ioctl((struct inode *)NULL, file, cmd, arg); + SAM("WARNING: failed to adjust mute: control not found\n"); + return -ENOENT; } -#endif /*EASYCAP_IS_VIDEODEV_CLIENT||EASYCAP_NEEDS_UNLOCKED_IOCTL*/ -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*---------------------------------------------------------------------------*/ -int -easycap_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +long easycap_unlocked_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) { -struct easycap *peasycap; -struct usb_device *p; -int kd; + struct easycap *peasycap; + struct usb_device *p; + int kd; -if (NULL == file) { - SAY("ERROR: file is NULL\n"); - return -ERESTARTSYS; -} -peasycap = file->private_data; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -1; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - return -EFAULT; -} -p = peasycap->pusb_device; -if (NULL == p) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -kd = isdongle(peasycap); -if (0 <= kd && DONGLE_MANY > kd) { - if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_video)) { - SAY("ERROR: cannot lock easycap_dongle[%i].mutex_video\n", kd); - return -ERESTARTSYS; - } - JOM(4, "locked easycap_dongle[%i].mutex_video\n", kd); -/*---------------------------------------------------------------------------*/ -/* - * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap, - * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. - * IF NECESSARY, BAIL OUT. -*/ -/*---------------------------------------------------------------------------*/ - if (kd != isdongle(peasycap)) - return -ERESTARTSYS; - if (NULL == file) { + if (!file) { SAY("ERROR: file is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); return -ERESTARTSYS; } peasycap = file->private_data; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -ERESTARTSYS; + return -1; } if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { SAY("ERROR: bad peasycap\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; } p = peasycap->pusb_device; - if (NULL == peasycap->pusb_device) { + if (!p) { SAM("ERROR: peasycap->pusb_device is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -ERESTARTSYS; + return -EFAULT; } -} else { + kd = isdongle(peasycap); + if (0 <= kd && DONGLE_MANY > kd) { + if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) { + SAY("ERROR: cannot lock " + "easycapdc60_dongle[%i].mutex_video\n", kd); + return -ERESTARTSYS; + } + JOM(4, "locked easycapdc60_dongle[%i].mutex_video\n", kd); +/*---------------------------------------------------------------------------*/ +/* + * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap, + * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. + * IF NECESSARY, BAIL OUT. + */ +/*---------------------------------------------------------------------------*/ + if (kd != isdongle(peasycap)) + return -ERESTARTSYS; + if (!file) { + SAY("ERROR: file is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -ERESTARTSYS; + } + peasycap = file->private_data; + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -ERESTARTSYS; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + p = peasycap->pusb_device; + if (!peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -ERESTARTSYS; + } + } else { /*---------------------------------------------------------------------------*/ /* * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE * ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED. BAIL OUT. -*/ -/*---------------------------------------------------------------------------*/ - return -ERESTARTSYS; -} + */ /*---------------------------------------------------------------------------*/ -switch (cmd) { -case VIDIOC_QUERYCAP: { - struct v4l2_capability v4l2_capability; - char version[16], *p1, *p2; - int i, rc, k[3]; - long lng; - - JOM(8, "VIDIOC_QUERYCAP\n"); - - if (16 <= strlen(EASYCAP_DRIVER_VERSION)) { - SAM("ERROR: bad driver version string\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; + return -ERESTARTSYS; } - strcpy(&version[0], EASYCAP_DRIVER_VERSION); - for (i = 0; i < 3; i++) - k[i] = 0; - p2 = &version[0]; i = 0; - while (*p2) { - p1 = p2; - while (*p2 && ('.' != *p2)) - p2++; - if (*p2) - *p2++ = 0; - if (3 > i) { - rc = (int) strict_strtol(p1, 10, &lng); - if (0 != rc) { - SAM("ERROR: %i=strict_strtol(%s,.,,)\n", \ - rc, p1); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; +/*---------------------------------------------------------------------------*/ + switch (cmd) { + case VIDIOC_QUERYCAP: { + struct v4l2_capability v4l2_capability; + char version[16], *p1, *p2; + int i, rc, k[3]; + long lng; + + JOM(8, "VIDIOC_QUERYCAP\n"); + + if (16 <= strlen(EASYCAP_DRIVER_VERSION)) { + SAM("ERROR: bad driver version string\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + strcpy(&version[0], EASYCAP_DRIVER_VERSION); + for (i = 0; i < 3; i++) + k[i] = 0; + p2 = &version[0]; + i = 0; + while (*p2) { + p1 = p2; + while (*p2 && ('.' != *p2)) + p2++; + if (*p2) + *p2++ = 0; + if (3 > i) { + rc = (int) strict_strtol(p1, 10, &lng); + if (rc) { + SAM("ERROR: %i=strict_strtol(%s,.,,)\n", + rc, p1); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + k[i] = (int)lng; } - k[i] = (int)lng; + i++; } - i++; - } - memset(&v4l2_capability, 0, sizeof(struct v4l2_capability)); - strlcpy(&v4l2_capability.driver[0], "easycap", \ - sizeof(v4l2_capability.driver)); + memset(&v4l2_capability, 0, sizeof(struct v4l2_capability)); + strlcpy(&v4l2_capability.driver[0], + "easycap", sizeof(v4l2_capability.driver)); - v4l2_capability.capabilities = \ - V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | \ - V4L2_CAP_AUDIO | V4L2_CAP_READWRITE; + v4l2_capability.capabilities = V4L2_CAP_VIDEO_CAPTURE | + V4L2_CAP_STREAMING | + V4L2_CAP_AUDIO | + V4L2_CAP_READWRITE; - v4l2_capability.version = KERNEL_VERSION(k[0], k[1], k[2]); - JOM(8, "v4l2_capability.version=(%i,%i,%i)\n", k[0], k[1], k[2]); + v4l2_capability.version = KERNEL_VERSION(k[0], k[1], k[2]); + JOM(8, "v4l2_capability.version=(%i,%i,%i)\n", k[0], k[1], k[2]); - strlcpy(&v4l2_capability.card[0], "EasyCAP DC60", \ - sizeof(v4l2_capability.card)); + strlcpy(&v4l2_capability.card[0], + "EasyCAP DC60", sizeof(v4l2_capability.card)); - if (usb_make_path(peasycap->pusb_device, &v4l2_capability.bus_info[0],\ + if (usb_make_path(peasycap->pusb_device, + &v4l2_capability.bus_info[0], sizeof(v4l2_capability.bus_info)) < 0) { - strlcpy(&v4l2_capability.bus_info[0], "EasyCAP bus_info", \ - sizeof(v4l2_capability.bus_info)); - JOM(8, "%s=v4l2_capability.bus_info\n", \ - &v4l2_capability.bus_info[0]); - } - if (0 != copy_to_user((void __user *)arg, &v4l2_capability, \ - sizeof(struct v4l2_capability))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; + + strlcpy(&v4l2_capability.bus_info[0], "EasyCAP bus_info", + sizeof(v4l2_capability.bus_info)); + JOM(8, "%s=v4l2_capability.bus_info\n", + &v4l2_capability.bus_info[0]); + } + if (copy_to_user((void __user *)arg, &v4l2_capability, + sizeof(struct v4l2_capability))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + break; } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_ENUMINPUT: { - struct v4l2_input v4l2_input; - __u32 index; + case VIDIOC_ENUMINPUT: { + struct v4l2_input v4l2_input; + u32 index; - JOM(8, "VIDIOC_ENUMINPUT\n"); + JOM(8, "VIDIOC_ENUMINPUT\n"); - if (0 != copy_from_user(&v4l2_input, (void __user *)arg, \ + if (copy_from_user(&v4l2_input, (void __user *)arg, sizeof(struct v4l2_input))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; - } + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - index = v4l2_input.index; - memset(&v4l2_input, 0, sizeof(struct v4l2_input)); - - switch (index) { - case 0: { - v4l2_input.index = index; - strcpy(&v4l2_input.name[0], "CVBS0"); - v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; - v4l2_input.audioset = 0x01; - v4l2_input.tuner = 0; - v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \ - V4L2_STD_NTSC ; - v4l2_input.status = 0; - JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); - break; - } - case 1: { - v4l2_input.index = index; - strcpy(&v4l2_input.name[0], "CVBS1"); - v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; - v4l2_input.audioset = 0x01; - v4l2_input.tuner = 0; - v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \ - V4L2_STD_NTSC ; - v4l2_input.status = 0; - JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); - break; - } - case 2: { - v4l2_input.index = index; - strcpy(&v4l2_input.name[0], "CVBS2"); - v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; - v4l2_input.audioset = 0x01; - v4l2_input.tuner = 0; - v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \ - V4L2_STD_NTSC ; - v4l2_input.status = 0; - JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); - break; - } - case 3: { - v4l2_input.index = index; - strcpy(&v4l2_input.name[0], "CVBS3"); - v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; - v4l2_input.audioset = 0x01; - v4l2_input.tuner = 0; - v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \ - V4L2_STD_NTSC ; - v4l2_input.status = 0; - JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); - break; - } - case 4: { - v4l2_input.index = index; - strcpy(&v4l2_input.name[0], "CVBS4"); - v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; - v4l2_input.audioset = 0x01; - v4l2_input.tuner = 0; - v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \ - V4L2_STD_NTSC ; - v4l2_input.status = 0; - JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); - break; - } - case 5: { - v4l2_input.index = index; - strcpy(&v4l2_input.name[0], "S-VIDEO"); - v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; - v4l2_input.audioset = 0x01; - v4l2_input.tuner = 0; - v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \ - V4L2_STD_NTSC ; - v4l2_input.status = 0; - JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); - break; - } - default: { - JOM(8, "%i=index: exhausts inputs\n", index); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; - } - } + index = v4l2_input.index; + memset(&v4l2_input, 0, sizeof(struct v4l2_input)); - if (0 != copy_to_user((void __user *)arg, &v4l2_input, \ - sizeof(struct v4l2_input))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; + switch (index) { + case 0: { + v4l2_input.index = index; + strcpy(&v4l2_input.name[0], "CVBS0"); + v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; + v4l2_input.audioset = 0x01; + v4l2_input.tuner = 0; + v4l2_input.std = V4L2_STD_PAL | + V4L2_STD_SECAM | + V4L2_STD_NTSC ; + v4l2_input.status = 0; + JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); + break; + } + case 1: { + v4l2_input.index = index; + strcpy(&v4l2_input.name[0], "CVBS1"); + v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; + v4l2_input.audioset = 0x01; + v4l2_input.tuner = 0; + v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | + V4L2_STD_NTSC; + v4l2_input.status = 0; + JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); + break; + } + case 2: { + v4l2_input.index = index; + strcpy(&v4l2_input.name[0], "CVBS2"); + v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; + v4l2_input.audioset = 0x01; + v4l2_input.tuner = 0; + v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | + V4L2_STD_NTSC ; + v4l2_input.status = 0; + JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); + break; + } + case 3: { + v4l2_input.index = index; + strcpy(&v4l2_input.name[0], "CVBS3"); + v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; + v4l2_input.audioset = 0x01; + v4l2_input.tuner = 0; + v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | + V4L2_STD_NTSC ; + v4l2_input.status = 0; + JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); + break; + } + case 4: { + v4l2_input.index = index; + strcpy(&v4l2_input.name[0], "CVBS4"); + v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; + v4l2_input.audioset = 0x01; + v4l2_input.tuner = 0; + v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | + V4L2_STD_NTSC ; + v4l2_input.status = 0; + JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); + break; + } + case 5: { + v4l2_input.index = index; + strcpy(&v4l2_input.name[0], "S-VIDEO"); + v4l2_input.type = V4L2_INPUT_TYPE_CAMERA; + v4l2_input.audioset = 0x01; + v4l2_input.tuner = 0; + v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | + V4L2_STD_NTSC ; + v4l2_input.status = 0; + JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); + break; + } + default: { + JOM(8, "%i=index: exhausts inputs\n", index); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + } + + if (copy_to_user((void __user *)arg, &v4l2_input, + sizeof(struct v4l2_input))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + break; } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_G_INPUT: { - __u32 index; - - JOM(8, "VIDIOC_G_INPUT\n"); - index = (__u32)peasycap->input; - JOM(8, "user is told: %i\n", index); - if (0 != copy_to_user((void __user *)arg, &index, sizeof(__u32))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; + case VIDIOC_G_INPUT: { + u32 index; + + JOM(8, "VIDIOC_G_INPUT\n"); + index = (u32)peasycap->input; + JOM(8, "user is told: %i\n", index); + if (copy_to_user((void __user *)arg, &index, sizeof(u32))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + break; } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_S_INPUT: + case VIDIOC_S_INPUT: { - __u32 index; - int rc; + u32 index; + int rc; - JOM(8, "VIDIOC_S_INPUT\n"); + JOM(8, "VIDIOC_S_INPUT\n"); - if (0 != copy_from_user(&index, (void __user *)arg, sizeof(__u32))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; - } + if (0 != copy_from_user(&index, (void __user *)arg, sizeof(u32))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - JOM(8, "user requests input %i\n", index); + JOM(8, "user requests input %i\n", index); - if ((int)index == peasycap->input) { - SAM("requested input already in effect\n"); - break; - } + if ((int)index == peasycap->input) { + SAM("requested input already in effect\n"); + break; + } - if ((0 > index) || (INPUT_MANY <= index)) { - JOM(8, "ERROR: bad requested input: %i\n", index); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; - } + if ((0 > index) || (INPUT_MANY <= index)) { + JOM(8, "ERROR: bad requested input: %i\n", index); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } - rc = newinput(peasycap, (int)index); - if (0 == rc) { - JOM(8, "newinput(.,%i) OK\n", (int)index); - } else { - SAM("ERROR: newinput(.,%i) returned %i\n", (int)index, rc); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; + rc = newinput(peasycap, (int)index); + if (0 == rc) { + JOM(8, "newinput(.,%i) OK\n", (int)index); + } else { + SAM("ERROR: newinput(.,%i) returned %i\n", (int)index, rc); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + break; } - break; -} -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_ENUMAUDIO: { - JOM(8, "VIDIOC_ENUMAUDIO\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_ENUMAUDOUT: { - struct v4l2_audioout v4l2_audioout; - - JOM(8, "VIDIOC_ENUMAUDOUT\n"); - - if (0 != copy_from_user(&v4l2_audioout, (void __user *)arg, \ - sizeof(struct v4l2_audioout))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; - } - - if (0 != v4l2_audioout.index) { - mutex_unlock(&easycap_dongle[kd].mutex_video); + case VIDIOC_ENUMAUDIO: { + JOM(8, "VIDIOC_ENUMAUDIO\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } - memset(&v4l2_audioout, 0, sizeof(struct v4l2_audioout)); - v4l2_audioout.index = 0; - strcpy(&v4l2_audioout.name[0], "Soundtrack"); - - if (0 != copy_to_user((void __user *)arg, &v4l2_audioout, \ - sizeof(struct v4l2_audioout))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; - } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_QUERYCTRL: { - int i1; - struct v4l2_queryctrl v4l2_queryctrl; + case VIDIOC_ENUMAUDOUT: { + struct v4l2_audioout v4l2_audioout; - JOM(8, "VIDIOC_QUERYCTRL\n"); + JOM(8, "VIDIOC_ENUMAUDOUT\n"); - if (0 != copy_from_user(&v4l2_queryctrl, (void __user *)arg, \ - sizeof(struct v4l2_queryctrl))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; - } + if (copy_from_user(&v4l2_audioout, (void __user *)arg, + sizeof(struct v4l2_audioout))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - i1 = 0; - while (0xFFFFFFFF != easycap_control[i1].id) { - if (easycap_control[i1].id == v4l2_queryctrl.id) { - JOM(8, "VIDIOC_QUERYCTRL %s=easycap_control[%i]" \ - ".name\n", &easycap_control[i1].name[0], i1); - memcpy(&v4l2_queryctrl, &easycap_control[i1], \ - sizeof(struct v4l2_queryctrl)); - break; + if (0 != v4l2_audioout.index) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; } - i1++; - } - if (0xFFFFFFFF == easycap_control[i1].id) { - JOM(8, "%i=index: exhausts controls\n", i1); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; - } - if (0 != copy_to_user((void __user *)arg, &v4l2_queryctrl, \ - sizeof(struct v4l2_queryctrl))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; - } - break; -} -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_QUERYMENU: { - JOM(8, "VIDIOC_QUERYMENU unsupported\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; -} -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_G_CTRL: { - struct v4l2_control *pv4l2_control; - - JOM(8, "VIDIOC_G_CTRL\n"); - pv4l2_control = kzalloc(sizeof(struct v4l2_control), GFP_KERNEL); - if (!pv4l2_control) { - SAM("ERROR: out of memory\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -ENOMEM; - } - if (0 != copy_from_user(pv4l2_control, (void __user *)arg, \ - sizeof(struct v4l2_control))) { - kfree(pv4l2_control); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; - } + memset(&v4l2_audioout, 0, sizeof(struct v4l2_audioout)); + v4l2_audioout.index = 0; + strcpy(&v4l2_audioout.name[0], "Soundtrack"); - switch (pv4l2_control->id) { - case V4L2_CID_BRIGHTNESS: { - pv4l2_control->value = peasycap->brightness; - JOM(8, "user enquires brightness: %i\n", pv4l2_control->value); - break; - } - case V4L2_CID_CONTRAST: { - pv4l2_control->value = peasycap->contrast; - JOM(8, "user enquires contrast: %i\n", pv4l2_control->value); - break; - } - case V4L2_CID_SATURATION: { - pv4l2_control->value = peasycap->saturation; - JOM(8, "user enquires saturation: %i\n", pv4l2_control->value); - break; - } - case V4L2_CID_HUE: { - pv4l2_control->value = peasycap->hue; - JOM(8, "user enquires hue: %i\n", pv4l2_control->value); - break; - } - case V4L2_CID_AUDIO_VOLUME: { - pv4l2_control->value = peasycap->volume; - JOM(8, "user enquires volume: %i\n", pv4l2_control->value); - break; - } - case V4L2_CID_AUDIO_MUTE: { - if (1 == peasycap->mute) - pv4l2_control->value = true; - else - pv4l2_control->value = false; - JOM(8, "user enquires mute: %i\n", pv4l2_control->value); + if (copy_to_user((void __user *)arg, &v4l2_audioout, + sizeof(struct v4l2_audioout))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } break; } - default: { - SAM("ERROR: unknown V4L2 control: 0x%08X=id\n", \ - pv4l2_control->id); - kfree(pv4l2_control); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; - } - } - if (0 != copy_to_user((void __user *)arg, pv4l2_control, \ - sizeof(struct v4l2_control))) { - kfree(pv4l2_control); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; - } - kfree(pv4l2_control); - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -#if defined(VIDIOC_S_CTRL_OLD) -case VIDIOC_S_CTRL_OLD: { - JOM(8, "VIDIOC_S_CTRL_OLD required at least for xawtv\n"); -} -#endif /*VIDIOC_S_CTRL_OLD*/ -case VIDIOC_S_CTRL: - { - struct v4l2_control v4l2_control; - - JOM(8, "VIDIOC_S_CTRL\n"); + case VIDIOC_QUERYCTRL: { + int i1; + struct v4l2_queryctrl v4l2_queryctrl; - if (0 != copy_from_user(&v4l2_control, (void __user *)arg, \ - sizeof(struct v4l2_control))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; - } - - switch (v4l2_control.id) { - case V4L2_CID_BRIGHTNESS: { - JOM(8, "user requests brightness %i\n", v4l2_control.value); - if (0 != adjust_brightness(peasycap, v4l2_control.value)) - ; - break; - } - case V4L2_CID_CONTRAST: { - JOM(8, "user requests contrast %i\n", v4l2_control.value); - if (0 != adjust_contrast(peasycap, v4l2_control.value)) - ; - break; - } - case V4L2_CID_SATURATION: { - JOM(8, "user requests saturation %i\n", v4l2_control.value); - if (0 != adjust_saturation(peasycap, v4l2_control.value)) - ; - break; - } - case V4L2_CID_HUE: { - JOM(8, "user requests hue %i\n", v4l2_control.value); - if (0 != adjust_hue(peasycap, v4l2_control.value)) - ; - break; - } - case V4L2_CID_AUDIO_VOLUME: { - JOM(8, "user requests volume %i\n", v4l2_control.value); - if (0 != adjust_volume(peasycap, v4l2_control.value)) - ; - break; - } - case V4L2_CID_AUDIO_MUTE: { - int mute; + JOM(8, "VIDIOC_QUERYCTRL\n"); - JOM(8, "user requests mute %i\n", v4l2_control.value); - if (true == v4l2_control.value) - mute = 1; - else - mute = 0; + if (0 != copy_from_user(&v4l2_queryctrl, (void __user *)arg, + sizeof(struct v4l2_queryctrl))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - if (0 != adjust_mute(peasycap, mute)) - SAM("WARNING: failed to adjust mute to %i\n", mute); + i1 = 0; + while (0xFFFFFFFF != easycap_control[i1].id) { + if (easycap_control[i1].id == v4l2_queryctrl.id) { + JOM(8, "VIDIOC_QUERYCTRL %s=easycap_control[%i]" + ".name\n", &easycap_control[i1].name[0], i1); + memcpy(&v4l2_queryctrl, &easycap_control[i1], + sizeof(struct v4l2_queryctrl)); + break; + } + i1++; + } + if (0xFFFFFFFF == easycap_control[i1].id) { + JOM(8, "%i=index: exhausts controls\n", i1); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + if (copy_to_user((void __user *)arg, &v4l2_queryctrl, + sizeof(struct v4l2_queryctrl))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } break; } - default: { - SAM("ERROR: unknown V4L2 control: 0x%08X=id\n", \ - v4l2_control.id); - mutex_unlock(&easycap_dongle[kd].mutex_video); +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + case VIDIOC_QUERYMENU: { + JOM(8, "VIDIOC_QUERYMENU unsupported\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } - } - break; -} -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_S_EXT_CTRLS: { - JOM(8, "VIDIOC_S_EXT_CTRLS unsupported\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_ENUM_FMT: { - __u32 index; - struct v4l2_fmtdesc v4l2_fmtdesc; - - JOM(8, "VIDIOC_ENUM_FMT\n"); - - if (0 != copy_from_user(&v4l2_fmtdesc, (void __user *)arg, \ - sizeof(struct v4l2_fmtdesc))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; - } - - index = v4l2_fmtdesc.index; - memset(&v4l2_fmtdesc, 0, sizeof(struct v4l2_fmtdesc)); - - v4l2_fmtdesc.index = index; - v4l2_fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + case VIDIOC_G_CTRL: { + struct v4l2_control *pv4l2_control; + + JOM(8, "VIDIOC_G_CTRL\n"); + pv4l2_control = kzalloc(sizeof(struct v4l2_control), GFP_KERNEL); + if (!pv4l2_control) { + SAM("ERROR: out of memory\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -ENOMEM; + } + if (0 != copy_from_user(pv4l2_control, (void __user *)arg, + sizeof(struct v4l2_control))) { + kfree(pv4l2_control); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - switch (index) { - case 0: { - v4l2_fmtdesc.flags = 0; - strcpy(&v4l2_fmtdesc.description[0], "uyvy"); - v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_UYVY; - JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); - break; - } - case 1: { - v4l2_fmtdesc.flags = 0; - strcpy(&v4l2_fmtdesc.description[0], "yuy2"); - v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_YUYV; - JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); - break; - } - case 2: { - v4l2_fmtdesc.flags = 0; - strcpy(&v4l2_fmtdesc.description[0], "rgb24"); - v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB24; - JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); - break; - } - case 3: { - v4l2_fmtdesc.flags = 0; - strcpy(&v4l2_fmtdesc.description[0], "rgb32"); - v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB32; - JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); - break; - } - case 4: { - v4l2_fmtdesc.flags = 0; - strcpy(&v4l2_fmtdesc.description[0], "bgr24"); - v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR24; - JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); - break; - } - case 5: { - v4l2_fmtdesc.flags = 0; - strcpy(&v4l2_fmtdesc.description[0], "bgr32"); - v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR32; - JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); + switch (pv4l2_control->id) { + case V4L2_CID_BRIGHTNESS: { + pv4l2_control->value = peasycap->brightness; + JOM(8, "user enquires brightness: %i\n", pv4l2_control->value); + break; + } + case V4L2_CID_CONTRAST: { + pv4l2_control->value = peasycap->contrast; + JOM(8, "user enquires contrast: %i\n", pv4l2_control->value); + break; + } + case V4L2_CID_SATURATION: { + pv4l2_control->value = peasycap->saturation; + JOM(8, "user enquires saturation: %i\n", pv4l2_control->value); + break; + } + case V4L2_CID_HUE: { + pv4l2_control->value = peasycap->hue; + JOM(8, "user enquires hue: %i\n", pv4l2_control->value); + break; + } + case V4L2_CID_AUDIO_VOLUME: { + pv4l2_control->value = peasycap->volume; + JOM(8, "user enquires volume: %i\n", pv4l2_control->value); + break; + } + case V4L2_CID_AUDIO_MUTE: { + if (1 == peasycap->mute) + pv4l2_control->value = true; + else + pv4l2_control->value = false; + JOM(8, "user enquires mute: %i\n", pv4l2_control->value); + break; + } + default: { + SAM("ERROR: unknown V4L2 control: 0x%08X=id\n", + pv4l2_control->id); + kfree(pv4l2_control); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + } + if (copy_to_user((void __user *)arg, pv4l2_control, + sizeof(struct v4l2_control))) { + kfree(pv4l2_control); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + kfree(pv4l2_control); break; } - default: { - JOM(8, "%i=index: exhausts formats\n", index); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; - } - } - if (0 != copy_to_user((void __user *)arg, &v4l2_fmtdesc, \ - sizeof(struct v4l2_fmtdesc))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; - } - break; -} -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -/* - * THE RESPONSE TO VIDIOC_ENUM_FRAMESIZES MUST BE CONDITIONED ON THE - * THE CURRENT STANDARD, BECAUSE THAT IS WHAT gstreamer EXPECTS. BEWARE. -*/ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_ENUM_FRAMESIZES: { - __u32 index; - struct v4l2_frmsizeenum v4l2_frmsizeenum; - - JOM(8, "VIDIOC_ENUM_FRAMESIZES\n"); - - if (0 != copy_from_user(&v4l2_frmsizeenum, (void __user *)arg, \ - sizeof(struct v4l2_frmsizeenum))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; - } + case VIDIOC_S_CTRL: + { + struct v4l2_control v4l2_control; - index = v4l2_frmsizeenum.index; + JOM(8, "VIDIOC_S_CTRL\n"); - v4l2_frmsizeenum.type = (__u32) V4L2_FRMSIZE_TYPE_DISCRETE; + if (0 != copy_from_user(&v4l2_control, (void __user *)arg, + sizeof(struct v4l2_control))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - if (true == peasycap->ntsc) { - switch (index) { - case 0: { - v4l2_frmsizeenum.discrete.width = 640; - v4l2_frmsizeenum.discrete.height = 480; - JOM(8, "%i=index: %ix%i\n", index, \ - (int)(v4l2_frmsizeenum.\ - discrete.width), \ - (int)(v4l2_frmsizeenum.\ - discrete.height)); + switch (v4l2_control.id) { + case V4L2_CID_BRIGHTNESS: { + JOM(8, "user requests brightness %i\n", v4l2_control.value); + if (0 != adjust_brightness(peasycap, v4l2_control.value)) + ; break; } - case 1: { - v4l2_frmsizeenum.discrete.width = 320; - v4l2_frmsizeenum.discrete.height = 240; - JOM(8, "%i=index: %ix%i\n", index, \ - (int)(v4l2_frmsizeenum.\ - discrete.width), \ - (int)(v4l2_frmsizeenum.\ - discrete.height)); + case V4L2_CID_CONTRAST: { + JOM(8, "user requests contrast %i\n", v4l2_control.value); + if (0 != adjust_contrast(peasycap, v4l2_control.value)) + ; break; } - case 2: { - v4l2_frmsizeenum.discrete.width = 720; - v4l2_frmsizeenum.discrete.height = 480; - JOM(8, "%i=index: %ix%i\n", index, \ - (int)(v4l2_frmsizeenum.\ - discrete.width), \ - (int)(v4l2_frmsizeenum.\ - discrete.height)); + case V4L2_CID_SATURATION: { + JOM(8, "user requests saturation %i\n", v4l2_control.value); + if (0 != adjust_saturation(peasycap, v4l2_control.value)) + ; break; } - case 3: { - v4l2_frmsizeenum.discrete.width = 360; - v4l2_frmsizeenum.discrete.height = 240; - JOM(8, "%i=index: %ix%i\n", index, \ - (int)(v4l2_frmsizeenum.\ - discrete.width), \ - (int)(v4l2_frmsizeenum.\ - discrete.height)); + case V4L2_CID_HUE: { + JOM(8, "user requests hue %i\n", v4l2_control.value); + if (0 != adjust_hue(peasycap, v4l2_control.value)) + ; + break; + } + case V4L2_CID_AUDIO_VOLUME: { + JOM(8, "user requests volume %i\n", v4l2_control.value); + if (0 != adjust_volume(peasycap, v4l2_control.value)) + ; + break; + } + case V4L2_CID_AUDIO_MUTE: { + int mute; + + JOM(8, "user requests mute %i\n", v4l2_control.value); + if (v4l2_control.value) + mute = 1; + else + mute = 0; + + if (0 != adjust_mute(peasycap, mute)) + SAM("WARNING: failed to adjust mute to %i\n", mute); break; } default: { - JOM(8, "%i=index: exhausts framesizes\n", index); - mutex_unlock(&easycap_dongle[kd].mutex_video); + SAM("ERROR: unknown V4L2 control: 0x%08X=id\n", + v4l2_control.id); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } } - } else { + break; + } +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + case VIDIOC_S_EXT_CTRLS: { + JOM(8, "VIDIOC_S_EXT_CTRLS unsupported\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + case VIDIOC_ENUM_FMT: { + u32 index; + struct v4l2_fmtdesc v4l2_fmtdesc; + + JOM(8, "VIDIOC_ENUM_FMT\n"); + + if (0 != copy_from_user(&v4l2_fmtdesc, (void __user *)arg, + sizeof(struct v4l2_fmtdesc))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + + index = v4l2_fmtdesc.index; + memset(&v4l2_fmtdesc, 0, sizeof(struct v4l2_fmtdesc)); + + v4l2_fmtdesc.index = index; + v4l2_fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + switch (index) { case 0: { - v4l2_frmsizeenum.discrete.width = 640; - v4l2_frmsizeenum.discrete.height = 480; - JOM(8, "%i=index: %ix%i\n", index, \ - (int)(v4l2_frmsizeenum.\ - discrete.width), \ - (int)(v4l2_frmsizeenum.\ - discrete.height)); + v4l2_fmtdesc.flags = 0; + strcpy(&v4l2_fmtdesc.description[0], "uyvy"); + v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_UYVY; + JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); break; } case 1: { - v4l2_frmsizeenum.discrete.width = 320; - v4l2_frmsizeenum.discrete.height = 240; - JOM(8, "%i=index: %ix%i\n", index, \ - (int)(v4l2_frmsizeenum.\ - discrete.width), \ - (int)(v4l2_frmsizeenum.\ - discrete.height)); + v4l2_fmtdesc.flags = 0; + strcpy(&v4l2_fmtdesc.description[0], "yuy2"); + v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_YUYV; + JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); break; } case 2: { - v4l2_frmsizeenum.discrete.width = 704; - v4l2_frmsizeenum.discrete.height = 576; - JOM(8, "%i=index: %ix%i\n", index, \ - (int)(v4l2_frmsizeenum.\ - discrete.width), \ - (int)(v4l2_frmsizeenum.\ - discrete.height)); + v4l2_fmtdesc.flags = 0; + strcpy(&v4l2_fmtdesc.description[0], "rgb24"); + v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB24; + JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); break; } case 3: { - v4l2_frmsizeenum.discrete.width = 720; - v4l2_frmsizeenum.discrete.height = 576; - JOM(8, "%i=index: %ix%i\n", index, \ - (int)(v4l2_frmsizeenum.\ - discrete.width), \ - (int)(v4l2_frmsizeenum.\ - discrete.height)); + v4l2_fmtdesc.flags = 0; + strcpy(&v4l2_fmtdesc.description[0], "rgb32"); + v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB32; + JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); break; } case 4: { - v4l2_frmsizeenum.discrete.width = 360; - v4l2_frmsizeenum.discrete.height = 288; - JOM(8, "%i=index: %ix%i\n", index, \ - (int)(v4l2_frmsizeenum.\ - discrete.width), \ - (int)(v4l2_frmsizeenum.\ - discrete.height)); + v4l2_fmtdesc.flags = 0; + strcpy(&v4l2_fmtdesc.description[0], "bgr24"); + v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR24; + JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); + break; + } + case 5: { + v4l2_fmtdesc.flags = 0; + strcpy(&v4l2_fmtdesc.description[0], "bgr32"); + v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR32; + JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); break; } default: { - JOM(8, "%i=index: exhausts framesizes\n", index); - mutex_unlock(&easycap_dongle[kd].mutex_video); + JOM(8, "%i=index: exhausts formats\n", index); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EINVAL; } } + if (copy_to_user((void __user *)arg, &v4l2_fmtdesc, + sizeof(struct v4l2_fmtdesc))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + break; } - if (0 != copy_to_user((void __user *)arg, &v4l2_frmsizeenum, \ - sizeof(struct v4l2_frmsizeenum))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; - } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /* - * THE RESPONSE TO VIDIOC_ENUM_FRAMEINTERVALS MUST BE CONDITIONED ON THE - * THE CURRENT STANDARD, BECAUSE THAT IS WHAT gstreamer EXPECTS. BEWARE. -*/ + * THE RESPONSE TO VIDIOC_ENUM_FRAMESIZES MUST BE CONDITIONED ON THE + * THE CURRENT STANDARD, BECAUSE THAT IS WHAT gstreamer EXPECTS. BEWARE. + */ /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_ENUM_FRAMEINTERVALS: { - __u32 index; - int denominator; - struct v4l2_frmivalenum v4l2_frmivalenum; + case VIDIOC_ENUM_FRAMESIZES: { + u32 index; + struct v4l2_frmsizeenum v4l2_frmsizeenum; - JOM(8, "VIDIOC_ENUM_FRAMEINTERVALS\n"); + JOM(8, "VIDIOC_ENUM_FRAMESIZES\n"); - if (peasycap->fps) - denominator = peasycap->fps; - else { - if (true == peasycap->ntsc) - denominator = 30; - else - denominator = 25; - } + if (0 != copy_from_user(&v4l2_frmsizeenum, (void __user *)arg, + sizeof(struct v4l2_frmsizeenum))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - if (0 != copy_from_user(&v4l2_frmivalenum, (void __user *)arg, \ - sizeof(struct v4l2_frmivalenum))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; + index = v4l2_frmsizeenum.index; + + v4l2_frmsizeenum.type = (u32) V4L2_FRMSIZE_TYPE_DISCRETE; + + if (peasycap->ntsc) { + switch (index) { + case 0: { + v4l2_frmsizeenum.discrete.width = 640; + v4l2_frmsizeenum.discrete.height = 480; + JOM(8, "%i=index: %ix%i\n", index, + (int)(v4l2_frmsizeenum. + discrete.width), + (int)(v4l2_frmsizeenum. + discrete.height)); + break; + } + case 1: { + v4l2_frmsizeenum.discrete.width = 320; + v4l2_frmsizeenum.discrete.height = 240; + JOM(8, "%i=index: %ix%i\n", index, + (int)(v4l2_frmsizeenum. + discrete.width), + (int)(v4l2_frmsizeenum. + discrete.height)); + break; + } + case 2: { + v4l2_frmsizeenum.discrete.width = 720; + v4l2_frmsizeenum.discrete.height = 480; + JOM(8, "%i=index: %ix%i\n", index, + (int)(v4l2_frmsizeenum. + discrete.width), + (int)(v4l2_frmsizeenum. + discrete.height)); + break; + } + case 3: { + v4l2_frmsizeenum.discrete.width = 360; + v4l2_frmsizeenum.discrete.height = 240; + JOM(8, "%i=index: %ix%i\n", index, + (int)(v4l2_frmsizeenum. + discrete.width), + (int)(v4l2_frmsizeenum. + discrete.height)); + break; + } + default: { + JOM(8, "%i=index: exhausts framesizes\n", index); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + } + } else { + switch (index) { + case 0: { + v4l2_frmsizeenum.discrete.width = 640; + v4l2_frmsizeenum.discrete.height = 480; + JOM(8, "%i=index: %ix%i\n", index, + (int)(v4l2_frmsizeenum. + discrete.width), + (int)(v4l2_frmsizeenum. + discrete.height)); + break; + } + case 1: { + v4l2_frmsizeenum.discrete.width = 320; + v4l2_frmsizeenum.discrete.height = 240; + JOM(8, "%i=index: %ix%i\n", index, + (int)(v4l2_frmsizeenum. + discrete.width), + (int)(v4l2_frmsizeenum. + discrete.height)); + break; + } + case 2: { + v4l2_frmsizeenum.discrete.width = 704; + v4l2_frmsizeenum.discrete.height = 576; + JOM(8, "%i=index: %ix%i\n", index, + (int)(v4l2_frmsizeenum. + discrete.width), + (int)(v4l2_frmsizeenum. + discrete.height)); + break; + } + case 3: { + v4l2_frmsizeenum.discrete.width = 720; + v4l2_frmsizeenum.discrete.height = 576; + JOM(8, "%i=index: %ix%i\n", index, + (int)(v4l2_frmsizeenum. + discrete.width), + (int)(v4l2_frmsizeenum. + discrete.height)); + break; + } + case 4: { + v4l2_frmsizeenum.discrete.width = 360; + v4l2_frmsizeenum.discrete.height = 288; + JOM(8, "%i=index: %ix%i\n", index, + (int)(v4l2_frmsizeenum. + discrete.width), + (int)(v4l2_frmsizeenum. + discrete.height)); + break; + } + default: { + JOM(8, "%i=index: exhausts framesizes\n", index); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + } + } + if (copy_to_user((void __user *)arg, &v4l2_frmsizeenum, + sizeof(struct v4l2_frmsizeenum))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + break; } +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +/* + * THE RESPONSE TO VIDIOC_ENUM_FRAMEINTERVALS MUST BE CONDITIONED ON THE + * THE CURRENT STANDARD, BECAUSE THAT IS WHAT gstreamer EXPECTS. BEWARE. + */ +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + case VIDIOC_ENUM_FRAMEINTERVALS: { + u32 index; + int denominator; + struct v4l2_frmivalenum v4l2_frmivalenum; + + JOM(8, "VIDIOC_ENUM_FRAMEINTERVALS\n"); + + if (peasycap->fps) + denominator = peasycap->fps; + else { + if (peasycap->ntsc) + denominator = 30; + else + denominator = 25; + } - index = v4l2_frmivalenum.index; + if (0 != copy_from_user(&v4l2_frmivalenum, (void __user *)arg, + sizeof(struct v4l2_frmivalenum))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - v4l2_frmivalenum.type = (__u32) V4L2_FRMIVAL_TYPE_DISCRETE; + index = v4l2_frmivalenum.index; - switch (index) { - case 0: { - v4l2_frmivalenum.discrete.numerator = 1; - v4l2_frmivalenum.discrete.denominator = denominator; - JOM(8, "%i=index: %i/%i\n", index, \ - (int)(v4l2_frmivalenum.discrete.numerator), \ - (int)(v4l2_frmivalenum.discrete.denominator)); - break; - } - case 1: { - v4l2_frmivalenum.discrete.numerator = 1; - v4l2_frmivalenum.discrete.denominator = denominator/5; - JOM(8, "%i=index: %i/%i\n", index, \ - (int)(v4l2_frmivalenum.discrete.numerator), \ - (int)(v4l2_frmivalenum.discrete.denominator)); - break; - } - default: { - JOM(8, "%i=index: exhausts frameintervals\n", index); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; - } - } - if (0 != copy_to_user((void __user *)arg, &v4l2_frmivalenum, \ + v4l2_frmivalenum.type = (u32) V4L2_FRMIVAL_TYPE_DISCRETE; + + switch (index) { + case 0: { + v4l2_frmivalenum.discrete.numerator = 1; + v4l2_frmivalenum.discrete.denominator = denominator; + JOM(8, "%i=index: %i/%i\n", index, + (int)(v4l2_frmivalenum.discrete.numerator), + (int)(v4l2_frmivalenum.discrete.denominator)); + break; + } + case 1: { + v4l2_frmivalenum.discrete.numerator = 1; + v4l2_frmivalenum.discrete.denominator = denominator/5; + JOM(8, "%i=index: %i/%i\n", index, + (int)(v4l2_frmivalenum.discrete.numerator), + (int)(v4l2_frmivalenum.discrete.denominator)); + break; + } + default: { + JOM(8, "%i=index: exhausts frameintervals\n", index); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + } + if (copy_to_user((void __user *)arg, &v4l2_frmivalenum, sizeof(struct v4l2_frmivalenum))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + break; } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_G_FMT: { - struct v4l2_format *pv4l2_format; - struct v4l2_pix_format *pv4l2_pix_format; - - JOM(8, "VIDIOC_G_FMT\n"); - pv4l2_format = kzalloc(sizeof(struct v4l2_format), GFP_KERNEL); - if (!pv4l2_format) { - SAM("ERROR: out of memory\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -ENOMEM; - } - pv4l2_pix_format = kzalloc(sizeof(struct v4l2_pix_format), GFP_KERNEL); - if (!pv4l2_pix_format) { - SAM("ERROR: out of memory\n"); - kfree(pv4l2_format); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -ENOMEM; - } - if (0 != copy_from_user(pv4l2_format, (void __user *)arg, \ + case VIDIOC_G_FMT: { + struct v4l2_format *pv4l2_format; + struct v4l2_pix_format *pv4l2_pix_format; + + JOM(8, "VIDIOC_G_FMT\n"); + pv4l2_format = kzalloc(sizeof(struct v4l2_format), GFP_KERNEL); + if (!pv4l2_format) { + SAM("ERROR: out of memory\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -ENOMEM; + } + pv4l2_pix_format = kzalloc(sizeof(struct v4l2_pix_format), GFP_KERNEL); + if (!pv4l2_pix_format) { + SAM("ERROR: out of memory\n"); + kfree(pv4l2_format); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -ENOMEM; + } + if (0 != copy_from_user(pv4l2_format, (void __user *)arg, sizeof(struct v4l2_format))) { - kfree(pv4l2_format); - kfree(pv4l2_pix_format); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; - } + kfree(pv4l2_format); + kfree(pv4l2_pix_format); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - if (pv4l2_format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - kfree(pv4l2_format); - kfree(pv4l2_pix_format); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; - } + if (pv4l2_format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + kfree(pv4l2_format); + kfree(pv4l2_pix_format); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } - memset(pv4l2_pix_format, 0, sizeof(struct v4l2_pix_format)); - pv4l2_format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - memcpy(&pv4l2_format->fmt.pix, \ - &easycap_format[peasycap->format_offset]\ - .v4l2_format.fmt.pix, sizeof(struct v4l2_pix_format)); - JOM(8, "user is told: %s\n", \ - &easycap_format[peasycap->format_offset].name[0]); + memset(pv4l2_pix_format, 0, sizeof(struct v4l2_pix_format)); + pv4l2_format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + memcpy(&pv4l2_format->fmt.pix, + &easycap_format[peasycap->format_offset] + .v4l2_format.fmt.pix, sizeof(struct v4l2_pix_format)); + JOM(8, "user is told: %s\n", + &easycap_format[peasycap->format_offset].name[0]); - if (0 != copy_to_user((void __user *)arg, pv4l2_format, \ + if (copy_to_user((void __user *)arg, pv4l2_format, sizeof(struct v4l2_format))) { + kfree(pv4l2_format); + kfree(pv4l2_pix_format); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } kfree(pv4l2_format); kfree(pv4l2_pix_format); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; + break; } - kfree(pv4l2_format); - kfree(pv4l2_pix_format); - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_TRY_FMT: -case VIDIOC_S_FMT: { - struct v4l2_format v4l2_format; - struct v4l2_pix_format v4l2_pix_format; - bool try; - int best_format; - - if (VIDIOC_TRY_FMT == cmd) { - JOM(8, "VIDIOC_TRY_FMT\n"); - try = true; - } else { - JOM(8, "VIDIOC_S_FMT\n"); - try = false; - } + case VIDIOC_TRY_FMT: + case VIDIOC_S_FMT: { + struct v4l2_format v4l2_format; + struct v4l2_pix_format v4l2_pix_format; + bool try; + int best_format; + + if (VIDIOC_TRY_FMT == cmd) { + JOM(8, "VIDIOC_TRY_FMT\n"); + try = true; + } else { + JOM(8, "VIDIOC_S_FMT\n"); + try = false; + } - if (0 != copy_from_user(&v4l2_format, (void __user *)arg, \ + if (0 != copy_from_user(&v4l2_format, (void __user *)arg, sizeof(struct v4l2_format))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; - } + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - best_format = adjust_format(peasycap, \ - v4l2_format.fmt.pix.width, \ - v4l2_format.fmt.pix.height, \ - v4l2_format.fmt.pix.pixelformat, \ - v4l2_format.fmt.pix.field, \ + best_format = adjust_format(peasycap, + v4l2_format.fmt.pix.width, + v4l2_format.fmt.pix.height, + v4l2_format.fmt.pix.pixelformat, + v4l2_format.fmt.pix.field, try); - if (0 > best_format) { - if (-EBUSY == best_format) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EBUSY; + if (0 > best_format) { + if (-EBUSY == best_format) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EBUSY; + } + JOM(8, "WARNING: adjust_format() returned %i\n", best_format); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -ENOENT; } - JOM(8, "WARNING: adjust_format() returned %i\n", best_format); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -ENOENT; - } /*...........................................................................*/ - memset(&v4l2_pix_format, 0, sizeof(struct v4l2_pix_format)); - v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + memset(&v4l2_pix_format, 0, sizeof(struct v4l2_pix_format)); + v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - memcpy(&(v4l2_format.fmt.pix), &(easycap_format[best_format]\ - .v4l2_format.fmt.pix), sizeof(v4l2_pix_format)); - JOM(8, "user is told: %s\n", &easycap_format[best_format].name[0]); + memcpy(&(v4l2_format.fmt.pix), + &(easycap_format[best_format].v4l2_format.fmt.pix), + sizeof(v4l2_pix_format)); + JOM(8, "user is told: %s\n", &easycap_format[best_format].name[0]); - if (0 != copy_to_user((void __user *)arg, &v4l2_format, \ + if (copy_to_user((void __user *)arg, &v4l2_format, sizeof(struct v4l2_format))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + break; } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_CROPCAP: { - struct v4l2_cropcap v4l2_cropcap; + case VIDIOC_CROPCAP: { + struct v4l2_cropcap v4l2_cropcap; - JOM(8, "VIDIOC_CROPCAP\n"); + JOM(8, "VIDIOC_CROPCAP\n"); - if (0 != copy_from_user(&v4l2_cropcap, (void __user *)arg, \ + if (0 != copy_from_user(&v4l2_cropcap, (void __user *)arg, sizeof(struct v4l2_cropcap))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; - } - - if (v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - JOM(8, "v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); - - memset(&v4l2_cropcap, 0, sizeof(struct v4l2_cropcap)); - v4l2_cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - v4l2_cropcap.bounds.left = 0; - v4l2_cropcap.bounds.top = 0; - v4l2_cropcap.bounds.width = peasycap->width; - v4l2_cropcap.bounds.height = peasycap->height; - v4l2_cropcap.defrect.left = 0; - v4l2_cropcap.defrect.top = 0; - v4l2_cropcap.defrect.width = peasycap->width; - v4l2_cropcap.defrect.height = peasycap->height; - v4l2_cropcap.pixelaspect.numerator = 1; - v4l2_cropcap.pixelaspect.denominator = 1; - - JOM(8, "user is told: %ix%i\n", peasycap->width, peasycap->height); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - if (0 != copy_to_user((void __user *)arg, &v4l2_cropcap, \ + if (v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + JOM(8, "v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); + + memset(&v4l2_cropcap, 0, sizeof(struct v4l2_cropcap)); + v4l2_cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + v4l2_cropcap.bounds.left = 0; + v4l2_cropcap.bounds.top = 0; + v4l2_cropcap.bounds.width = peasycap->width; + v4l2_cropcap.bounds.height = peasycap->height; + v4l2_cropcap.defrect.left = 0; + v4l2_cropcap.defrect.top = 0; + v4l2_cropcap.defrect.width = peasycap->width; + v4l2_cropcap.defrect.height = peasycap->height; + v4l2_cropcap.pixelaspect.numerator = 1; + v4l2_cropcap.pixelaspect.denominator = 1; + + JOM(8, "user is told: %ix%i\n", peasycap->width, peasycap->height); + + if (copy_to_user((void __user *)arg, &v4l2_cropcap, sizeof(struct v4l2_cropcap))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + break; } - break; -} -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_G_CROP: -case VIDIOC_S_CROP: { - JOM(8, "VIDIOC_G_CROP|VIDIOC_S_CROP unsupported\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; -} -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_QUERYSTD: { - JOM(8, "VIDIOC_QUERYSTD: " \ - "EasyCAP is incapable of detecting standard\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -/*---------------------------------------------------------------------------*/ -/* - * THE MANIPULATIONS INVOLVING last0,last1,last2,last3 CONSTITUTE A WORKAROUND - * FOR WHAT APPEARS TO BE A BUG IN 64-BIT mplayer. - * NOT NEEDED, BUT HOPEFULLY HARMLESS, FOR 32-BIT mplayer. - */ -/*---------------------------------------------------------------------------*/ -case VIDIOC_ENUMSTD: { - int last0 = -1, last1 = -1, last2 = -1, last3 = -1; - struct v4l2_standard v4l2_standard; - __u32 index; - struct easycap_standard const *peasycap_standard; - - JOM(8, "VIDIOC_ENUMSTD\n"); - - if (0 != copy_from_user(&v4l2_standard, (void __user *)arg, \ - sizeof(struct v4l2_standard))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; + case VIDIOC_G_CROP: + case VIDIOC_S_CROP: { + JOM(8, "VIDIOC_G_CROP|VIDIOC_S_CROP unsupported\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; } - index = v4l2_standard.index; - - last3 = last2; last2 = last1; last1 = last0; last0 = index; - if ((index == last3) && (index == last2) && \ - (index == last1) && (index == last0)) { - index++; - last3 = last2; last2 = last1; last1 = last0; last0 = index; +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + case VIDIOC_QUERYSTD: { + JOM(8, "VIDIOC_QUERYSTD: " + "EasyCAP is incapable of detecting standard\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + break; } + /*-------------------------------------------------------------------*/ + /* + * THE MANIPULATIONS INVOLVING last0,last1,last2,last3 + * CONSTITUTE A WORKAROUND * FOR WHAT APPEARS TO BE + * A BUG IN 64-BIT mplayer. + * NOT NEEDED, BUT HOPEFULLY HARMLESS, FOR 32-BIT mplayer. + */ + /*------------------------------------------------------------------*/ + case VIDIOC_ENUMSTD: { + int last0 = -1, last1 = -1, last2 = -1, last3 = -1; + struct v4l2_standard v4l2_standard; + u32 index; + struct easycap_standard const *peasycap_standard; + + JOM(8, "VIDIOC_ENUMSTD\n"); + + if (0 != copy_from_user(&v4l2_standard, (void __user *)arg, + sizeof(struct v4l2_standard))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + index = v4l2_standard.index; + + last3 = last2; + last2 = last1; + last1 = last0; + last0 = index; + if ((index == last3) && (index == last2) && + (index == last1) && (index == last0)) { + index++; + last3 = last2; + last2 = last1; + last1 = last0; + last0 = index; + } - memset(&v4l2_standard, 0, sizeof(struct v4l2_standard)); + memset(&v4l2_standard, 0, sizeof(struct v4l2_standard)); - peasycap_standard = &easycap_standard[0]; - while (0xFFFF != peasycap_standard->mask) { - if ((int)(peasycap_standard - &easycap_standard[0]) == index) - break; - peasycap_standard++; - } - if (0xFFFF == peasycap_standard->mask) { - JOM(8, "%i=index: exhausts standards\n", index); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; - } - JOM(8, "%i=index: %s\n", index, \ - &(peasycap_standard->v4l2_standard.name[0])); - memcpy(&v4l2_standard, &(peasycap_standard->v4l2_standard), \ - sizeof(struct v4l2_standard)); + peasycap_standard = &easycap_standard[0]; + while (0xFFFF != peasycap_standard->mask) { + if ((int)(peasycap_standard - &easycap_standard[0]) == index) + break; + peasycap_standard++; + } + if (0xFFFF == peasycap_standard->mask) { + JOM(8, "%i=index: exhausts standards\n", index); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + JOM(8, "%i=index: %s\n", index, + &(peasycap_standard->v4l2_standard.name[0])); + memcpy(&v4l2_standard, &(peasycap_standard->v4l2_standard), + sizeof(struct v4l2_standard)); - v4l2_standard.index = index; + v4l2_standard.index = index; - if (0 != copy_to_user((void __user *)arg, &v4l2_standard, \ - sizeof(struct v4l2_standard))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; + if (copy_to_user((void __user *)arg, &v4l2_standard, + sizeof(struct v4l2_standard))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + break; } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_G_STD: { - v4l2_std_id std_id; - struct easycap_standard const *peasycap_standard; + case VIDIOC_G_STD: { + v4l2_std_id std_id; + struct easycap_standard const *peasycap_standard; - JOM(8, "VIDIOC_G_STD\n"); + JOM(8, "VIDIOC_G_STD\n"); - if (0 > peasycap->standard_offset) { - JOM(8, "%i=peasycap->standard_offset\n", \ - peasycap->standard_offset); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EBUSY; - } + if (0 > peasycap->standard_offset) { + JOM(8, "%i=peasycap->standard_offset\n", + peasycap->standard_offset); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EBUSY; + } - if (0 != copy_from_user(&std_id, (void __user *)arg, \ - sizeof(v4l2_std_id))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; - } + if (0 != copy_from_user(&std_id, (void __user *)arg, + sizeof(v4l2_std_id))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - peasycap_standard = &easycap_standard[peasycap->standard_offset]; - std_id = peasycap_standard->v4l2_standard.id; + peasycap_standard = &easycap_standard[peasycap->standard_offset]; + std_id = peasycap_standard->v4l2_standard.id; - JOM(8, "user is told: %s\n", \ - &peasycap_standard->v4l2_standard.name[0]); + JOM(8, "user is told: %s\n", + &peasycap_standard->v4l2_standard.name[0]); - if (0 != copy_to_user((void __user *)arg, &std_id, \ - sizeof(v4l2_std_id))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; + if (copy_to_user((void __user *)arg, &std_id, + sizeof(v4l2_std_id))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + break; } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_S_STD: { - v4l2_std_id std_id; - int rc; + case VIDIOC_S_STD: { + v4l2_std_id std_id; + int rc; - JOM(8, "VIDIOC_S_STD\n"); + JOM(8, "VIDIOC_S_STD\n"); - if (0 != copy_from_user(&std_id, (void __user *)arg, \ - sizeof(v4l2_std_id))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; - } + if (0 != copy_from_user(&std_id, (void __user *)arg, + sizeof(v4l2_std_id))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - JOM(8, "User requests standard: 0x%08X%08X\n", \ - (int)((std_id & (((v4l2_std_id)0xFFFFFFFF) << 32)) >> 32), \ - (int)(std_id & ((v4l2_std_id)0xFFFFFFFF))); + JOM(8, "User requests standard: 0x%08X%08X\n", + (int)((std_id & (((v4l2_std_id)0xFFFFFFFF) << 32)) >> 32), + (int)(std_id & ((v4l2_std_id)0xFFFFFFFF))); - rc = adjust_standard(peasycap, std_id); - if (0 > rc) { - JOM(8, "WARNING: adjust_standard() returned %i\n", rc); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -ENOENT; + rc = adjust_standard(peasycap, std_id); + if (0 > rc) { + JOM(8, "WARNING: adjust_standard() returned %i\n", rc); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -ENOENT; + } + break; } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_REQBUFS: { - int nbuffers; - struct v4l2_requestbuffers v4l2_requestbuffers; + case VIDIOC_REQBUFS: { + int nbuffers; + struct v4l2_requestbuffers v4l2_requestbuffers; - JOM(8, "VIDIOC_REQBUFS\n"); + JOM(8, "VIDIOC_REQBUFS\n"); - if (0 != copy_from_user(&v4l2_requestbuffers, (void __user *)arg, \ - sizeof(struct v4l2_requestbuffers))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; - } + if (0 != copy_from_user(&v4l2_requestbuffers, + (void __user *)arg, + sizeof(struct v4l2_requestbuffers))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - if (v4l2_requestbuffers.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; - } - if (v4l2_requestbuffers.memory != V4L2_MEMORY_MMAP) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; - } - nbuffers = v4l2_requestbuffers.count; - JOM(8, " User requests %i buffers ...\n", nbuffers); - if (nbuffers < 2) - nbuffers = 2; - if (nbuffers > FRAME_BUFFER_MANY) - nbuffers = FRAME_BUFFER_MANY; - if (v4l2_requestbuffers.count == nbuffers) { - JOM(8, " ... agree to %i buffers\n", \ - nbuffers); - } else { - JOM(8, " ... insist on %i buffers\n", \ - nbuffers); - v4l2_requestbuffers.count = nbuffers; - } - peasycap->frame_buffer_many = nbuffers; + if (v4l2_requestbuffers.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + if (v4l2_requestbuffers.memory != V4L2_MEMORY_MMAP) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + nbuffers = v4l2_requestbuffers.count; + JOM(8, " User requests %i buffers ...\n", nbuffers); + if (nbuffers < 2) + nbuffers = 2; + if (nbuffers > FRAME_BUFFER_MANY) + nbuffers = FRAME_BUFFER_MANY; + if (v4l2_requestbuffers.count == nbuffers) { + JOM(8, " ... agree to %i buffers\n", + nbuffers); + } else { + JOM(8, " ... insist on %i buffers\n", + nbuffers); + v4l2_requestbuffers.count = nbuffers; + } + peasycap->frame_buffer_many = nbuffers; - if (0 != copy_to_user((void __user *)arg, &v4l2_requestbuffers, \ - sizeof(struct v4l2_requestbuffers))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; + if (copy_to_user((void __user *)arg, &v4l2_requestbuffers, + sizeof(struct v4l2_requestbuffers))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + break; } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_QUERYBUF: { - __u32 index; - struct v4l2_buffer v4l2_buffer; + case VIDIOC_QUERYBUF: { + u32 index; + struct v4l2_buffer v4l2_buffer; - JOM(8, "VIDIOC_QUERYBUF\n"); + JOM(8, "VIDIOC_QUERYBUF\n"); - if (peasycap->video_eof) { - JOM(8, "returning -EIO because %i=video_eof\n", \ - peasycap->video_eof); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EIO; - } + if (peasycap->video_eof) { + JOM(8, "returning -EIO because %i=video_eof\n", + peasycap->video_eof); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EIO; + } - if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \ + if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, sizeof(struct v4l2_buffer))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; - } + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; - } - index = v4l2_buffer.index; - if (index < 0 || index >= peasycap->frame_buffer_many) - return -EINVAL; - memset(&v4l2_buffer, 0, sizeof(struct v4l2_buffer)); - v4l2_buffer.index = index; - v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - v4l2_buffer.bytesused = peasycap->frame_buffer_used; - v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | \ - peasycap->done[index] | \ - peasycap->queued[index]; - v4l2_buffer.field = V4L2_FIELD_NONE; - v4l2_buffer.memory = V4L2_MEMORY_MMAP; - v4l2_buffer.m.offset = index * FRAME_BUFFER_SIZE; - v4l2_buffer.length = FRAME_BUFFER_SIZE; - - JOM(16, " %10i=index\n", v4l2_buffer.index); - JOM(16, " 0x%08X=type\n", v4l2_buffer.type); - JOM(16, " %10i=bytesused\n", v4l2_buffer.bytesused); - JOM(16, " 0x%08X=flags\n", v4l2_buffer.flags); - JOM(16, " %10i=field\n", v4l2_buffer.field); - JOM(16, " %10li=timestamp.tv_usec\n", \ - (long)v4l2_buffer.timestamp.tv_usec); - JOM(16, " %10i=sequence\n", v4l2_buffer.sequence); - JOM(16, " 0x%08X=memory\n", v4l2_buffer.memory); - JOM(16, " %10i=m.offset\n", v4l2_buffer.m.offset); - JOM(16, " %10i=length\n", v4l2_buffer.length); - - if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \ + if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + index = v4l2_buffer.index; + if (index < 0 || index >= peasycap->frame_buffer_many) + return -EINVAL; + memset(&v4l2_buffer, 0, sizeof(struct v4l2_buffer)); + v4l2_buffer.index = index; + v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + v4l2_buffer.bytesused = peasycap->frame_buffer_used; + v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | + peasycap->done[index] | + peasycap->queued[index]; + v4l2_buffer.field = V4L2_FIELD_NONE; + v4l2_buffer.memory = V4L2_MEMORY_MMAP; + v4l2_buffer.m.offset = index * FRAME_BUFFER_SIZE; + v4l2_buffer.length = FRAME_BUFFER_SIZE; + + JOM(16, " %10i=index\n", v4l2_buffer.index); + JOM(16, " 0x%08X=type\n", v4l2_buffer.type); + JOM(16, " %10i=bytesused\n", v4l2_buffer.bytesused); + JOM(16, " 0x%08X=flags\n", v4l2_buffer.flags); + JOM(16, " %10i=field\n", v4l2_buffer.field); + JOM(16, " %10li=timestamp.tv_usec\n", + (long)v4l2_buffer.timestamp.tv_usec); + JOM(16, " %10i=sequence\n", v4l2_buffer.sequence); + JOM(16, " 0x%08X=memory\n", v4l2_buffer.memory); + JOM(16, " %10i=m.offset\n", v4l2_buffer.m.offset); + JOM(16, " %10i=length\n", v4l2_buffer.length); + + if (copy_to_user((void __user *)arg, &v4l2_buffer, sizeof(struct v4l2_buffer))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + break; } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_QBUF: { - struct v4l2_buffer v4l2_buffer; + case VIDIOC_QBUF: { + struct v4l2_buffer v4l2_buffer; - JOM(8, "VIDIOC_QBUF\n"); + JOM(8, "VIDIOC_QBUF\n"); - if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \ + if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, sizeof(struct v4l2_buffer))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; - } + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; - } - if (v4l2_buffer.memory != V4L2_MEMORY_MMAP) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; - } - if (v4l2_buffer.index < 0 || \ - (v4l2_buffer.index >= peasycap->frame_buffer_many)) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; - } - v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED; + if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + if (v4l2_buffer.memory != V4L2_MEMORY_MMAP) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + if (v4l2_buffer.index < 0 || + v4l2_buffer.index >= peasycap->frame_buffer_many) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED; - peasycap->done[v4l2_buffer.index] = 0; - peasycap->queued[v4l2_buffer.index] = V4L2_BUF_FLAG_QUEUED; + peasycap->done[v4l2_buffer.index] = 0; + peasycap->queued[v4l2_buffer.index] = V4L2_BUF_FLAG_QUEUED; - if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \ + if (copy_to_user((void __user *)arg, &v4l2_buffer, sizeof(struct v4l2_buffer))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; - } + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - JOM(8, "..... user queueing frame buffer %i\n", \ - (int)v4l2_buffer.index); + JOM(8, "..... user queueing frame buffer %i\n", + (int)v4l2_buffer.index); - peasycap->frame_lock = 0; + peasycap->frame_lock = 0; - break; -} + break; + } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_DQBUF: + case VIDIOC_DQBUF: { -#if defined(AUDIOTIME) - struct signed_div_result sdr; - long long int above, below, dnbydt, fudge, sll; - unsigned long long int ull; - struct timeval timeval8; - struct timeval timeval1; -#endif /*AUDIOTIME*/ - struct timeval timeval, timeval2; - int i, j; - struct v4l2_buffer v4l2_buffer; - int rcdq; - __u16 input; - - JOM(8, "VIDIOC_DQBUF\n"); - - if ((peasycap->video_idle) || (peasycap->video_eof)) { - JOM(8, "returning -EIO because " \ - "%i=video_idle %i=video_eof\n", \ - peasycap->video_idle, peasycap->video_eof); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EIO; - } - - if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \ - sizeof(struct v4l2_buffer))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; - } + struct timeval timeval, timeval2; + int i, j; + struct v4l2_buffer v4l2_buffer; + int rcdq; + u16 input; + + JOM(8, "VIDIOC_DQBUF\n"); + + if ((peasycap->video_idle) || (peasycap->video_eof)) { + JOM(8, "returning -EIO because " + "%i=video_idle %i=video_eof\n", + peasycap->video_idle, peasycap->video_eof); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EIO; + } - if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; - } + if (copy_from_user(&v4l2_buffer, (void __user *)arg, + sizeof(struct v4l2_buffer))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - if (true == peasycap->offerfields) { - /*-----------------------------------------------------------*/ - /* - * IN ITS 50 "fps" MODE tvtime SEEMS ALWAYS TO REQUEST - * V4L2_FIELD_BOTTOM - */ - /*-----------------------------------------------------------*/ - if (V4L2_FIELD_TOP == v4l2_buffer.field) - JOM(8, "user wants V4L2_FIELD_TOP\n"); - else if (V4L2_FIELD_BOTTOM == v4l2_buffer.field) - JOM(8, "user wants V4L2_FIELD_BOTTOM\n"); - else if (V4L2_FIELD_ANY == v4l2_buffer.field) - JOM(8, "user wants V4L2_FIELD_ANY\n"); - else - JOM(8, "user wants V4L2_FIELD_...UNKNOWN: %i\n", \ - v4l2_buffer.field); - } + if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } - if (!peasycap->video_isoc_streaming) { - JOM(16, "returning -EIO because video urbs not streaming\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EIO; - } -/*---------------------------------------------------------------------------*/ -/* - * IF THE USER HAS PREVIOUSLY CALLED easycap_poll(), AS DETERMINED BY FINDING - * THE FLAG peasycap->polled SET, THERE MUST BE NO FURTHER WAIT HERE. IN THIS - * CASE, JUST CHOOSE THE FRAME INDICATED BY peasycap->frame_read - */ -/*---------------------------------------------------------------------------*/ + if (peasycap->offerfields) { + /*---------------------------------------------------*/ + /* + * IN ITS 50 "fps" MODE tvtime SEEMS ALWAYS TO REQUEST + * V4L2_FIELD_BOTTOM + */ + /*---------------------------------------------------*/ + if (V4L2_FIELD_TOP == v4l2_buffer.field) + JOM(8, "user wants V4L2_FIELD_TOP\n"); + else if (V4L2_FIELD_BOTTOM == v4l2_buffer.field) + JOM(8, "user wants V4L2_FIELD_BOTTOM\n"); + else if (V4L2_FIELD_ANY == v4l2_buffer.field) + JOM(8, "user wants V4L2_FIELD_ANY\n"); + else + JOM(8, "user wants V4L2_FIELD_...UNKNOWN: %i\n", + v4l2_buffer.field); + } - if (!peasycap->polled) { - do { - rcdq = easycap_dqbuf(peasycap, 0); - if (-EIO == rcdq) { - JOM(8, "returning -EIO because " \ - "dqbuf() returned -EIO\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + if (!peasycap->video_isoc_streaming) { + JOM(16, "returning -EIO because video urbs not streaming\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EIO; + } + /*-------------------------------------------------------------------*/ + /* + * IF THE USER HAS PREVIOUSLY CALLED easycap_poll(), + * AS DETERMINED BY FINDING + * THE FLAG peasycap->polled SET, THERE MUST BE + * NO FURTHER WAIT HERE. IN THIS + * CASE, JUST CHOOSE THE FRAME INDICATED BY peasycap->frame_read + */ + /*-------------------------------------------------------------------*/ + + if (!peasycap->polled) { + do { + rcdq = easycap_dqbuf(peasycap, 0); + if (-EIO == rcdq) { + JOM(8, "returning -EIO because " + "dqbuf() returned -EIO\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EIO; + } + } while (0 != rcdq); + } else { + if (peasycap->video_eof) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EIO; } - } while (0 != rcdq); - } else { - if (peasycap->video_eof) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EIO; } - } - if (V4L2_BUF_FLAG_DONE != peasycap->done[peasycap->frame_read]) { - SAM("ERROR: V4L2_BUF_FLAG_DONE != 0x%08X\n", \ - peasycap->done[peasycap->frame_read]); - } - peasycap->polled = 0; - - if (!(peasycap->isequence % 10)) { - for (i = 0; i < 179; i++) - peasycap->merit[i] = peasycap->merit[i+1]; - peasycap->merit[179] = merit_saa(peasycap->pusb_device); - j = 0; - for (i = 0; i < 180; i++) - j += peasycap->merit[i]; - if (90 < j) { - SAM("easycap driver shutting down " \ - "on condition blue\n"); - peasycap->video_eof = 1; peasycap->audio_eof = 1; + if (V4L2_BUF_FLAG_DONE != peasycap->done[peasycap->frame_read]) { + JOM(8, "V4L2_BUF_FLAG_DONE != 0x%08X\n", + peasycap->done[peasycap->frame_read]); + } + peasycap->polled = 0; + + if (!(peasycap->isequence % 10)) { + for (i = 0; i < 179; i++) + peasycap->merit[i] = peasycap->merit[i+1]; + peasycap->merit[179] = merit_saa(peasycap->pusb_device); + j = 0; + for (i = 0; i < 180; i++) + j += peasycap->merit[i]; + if (90 < j) { + SAM("easycap driver shutting down " + "on condition blue\n"); + peasycap->video_eof = 1; + peasycap->audio_eof = 1; + } } - } - - v4l2_buffer.index = peasycap->frame_read; - v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - v4l2_buffer.bytesused = peasycap->frame_buffer_used; - v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE; - if (true == peasycap->offerfields) - v4l2_buffer.field = V4L2_FIELD_BOTTOM; - else - v4l2_buffer.field = V4L2_FIELD_NONE; - do_gettimeofday(&timeval); - timeval2 = timeval; -#if defined(AUDIOTIME) - if (!peasycap->timeval0.tv_sec) { - timeval8 = timeval; - timeval1 = timeval; + v4l2_buffer.index = peasycap->frame_read; + v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + v4l2_buffer.bytesused = peasycap->frame_buffer_used; + v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE; + if (peasycap->offerfields) + v4l2_buffer.field = V4L2_FIELD_BOTTOM; + else + v4l2_buffer.field = V4L2_FIELD_NONE; + do_gettimeofday(&timeval); timeval2 = timeval; - dnbydt = 192000; - peasycap->timeval0 = timeval8; - } else { - dnbydt = peasycap->dnbydt; - timeval1 = peasycap->timeval1; - above = dnbydt * MICROSECONDS(timeval, timeval1); - below = 192000; - sdr = signed_div(above, below); - - above = sdr.quotient + timeval1.tv_usec - 350000; - - below = 1000000; - sdr = signed_div(above, below); - timeval2.tv_usec = sdr.remainder; - timeval2.tv_sec = timeval1.tv_sec + sdr.quotient; - } - if (!(peasycap->isequence % 500)) { - fudge = ((long long int)(1000000)) * \ - ((long long int)(timeval.tv_sec - \ - timeval2.tv_sec)) + \ - (long long int)(timeval.tv_usec - \ - timeval2.tv_usec); - sdr = signed_div(fudge, 1000); - sll = sdr.quotient; - ull = sdr.remainder; - - SAM("%5lli.%-3lli=ms timestamp fudge\n", sll, ull); - } -#endif /*AUDIOTIME*/ - - v4l2_buffer.timestamp = timeval2; - v4l2_buffer.sequence = peasycap->isequence++; - v4l2_buffer.memory = V4L2_MEMORY_MMAP; - v4l2_buffer.m.offset = v4l2_buffer.index * FRAME_BUFFER_SIZE; - v4l2_buffer.length = FRAME_BUFFER_SIZE; - - JOM(16, " %10i=index\n", v4l2_buffer.index); - JOM(16, " 0x%08X=type\n", v4l2_buffer.type); - JOM(16, " %10i=bytesused\n", v4l2_buffer.bytesused); - JOM(16, " 0x%08X=flags\n", v4l2_buffer.flags); - JOM(16, " %10i=field\n", v4l2_buffer.field); - JOM(16, " %10li=timestamp.tv_sec\n", \ - (long)v4l2_buffer.timestamp.tv_sec); - JOM(16, " %10li=timestamp.tv_usec\n", \ - (long)v4l2_buffer.timestamp.tv_usec); - JOM(16, " %10i=sequence\n", v4l2_buffer.sequence); - JOM(16, " 0x%08X=memory\n", v4l2_buffer.memory); - JOM(16, " %10i=m.offset\n", v4l2_buffer.m.offset); - JOM(16, " %10i=length\n", v4l2_buffer.length); - - if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \ - sizeof(struct v4l2_buffer))) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; - } - input = peasycap->frame_buffer[peasycap->frame_read][0].input; - if (0x08 & input) { - JOM(8, "user is offered frame buffer %i, input %i\n", \ - peasycap->frame_read, (0x07 & input)); - } else { - JOM(8, "user is offered frame buffer %i\n", \ - peasycap->frame_read); - } - peasycap->frame_lock = 1; - JOM(8, "%i=peasycap->frame_fill\n", peasycap->frame_fill); - if (peasycap->frame_read == peasycap->frame_fill) { - if (peasycap->frame_lock) { - JOM(8, "WORRY: filling frame buffer " \ - "while offered to user\n"); + v4l2_buffer.timestamp = timeval2; + v4l2_buffer.sequence = peasycap->isequence++; + v4l2_buffer.memory = V4L2_MEMORY_MMAP; + v4l2_buffer.m.offset = v4l2_buffer.index * FRAME_BUFFER_SIZE; + v4l2_buffer.length = FRAME_BUFFER_SIZE; + + JOM(16, " %10i=index\n", v4l2_buffer.index); + JOM(16, " 0x%08X=type\n", v4l2_buffer.type); + JOM(16, " %10i=bytesused\n", v4l2_buffer.bytesused); + JOM(16, " 0x%08X=flags\n", v4l2_buffer.flags); + JOM(16, " %10i=field\n", v4l2_buffer.field); + JOM(16, " %10li=timestamp.tv_sec\n", + (long)v4l2_buffer.timestamp.tv_sec); + JOM(16, " %10li=timestamp.tv_usec\n", + (long)v4l2_buffer.timestamp.tv_usec); + JOM(16, " %10i=sequence\n", v4l2_buffer.sequence); + JOM(16, " 0x%08X=memory\n", v4l2_buffer.memory); + JOM(16, " %10i=m.offset\n", v4l2_buffer.m.offset); + JOM(16, " %10i=length\n", v4l2_buffer.length); + + if (copy_to_user((void __user *)arg, &v4l2_buffer, + sizeof(struct v4l2_buffer))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + + input = peasycap->frame_buffer[peasycap->frame_read][0].input; + if (0x08 & input) { + JOM(8, "user is offered frame buffer %i, input %i\n", + peasycap->frame_read, (0x07 & input)); + } else { + JOM(8, "user is offered frame buffer %i\n", + peasycap->frame_read); } + peasycap->frame_lock = 1; + JOM(8, "%i=peasycap->frame_fill\n", peasycap->frame_fill); + if (peasycap->frame_read == peasycap->frame_fill) { + if (peasycap->frame_lock) { + JOM(8, "WORRY: filling frame buffer " + "while offered to user\n"); + } + } + break; } - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_STREAMON: { - int i; + case VIDIOC_STREAMON: { + int i; - JOM(8, "VIDIOC_STREAMON\n"); + JOM(8, "VIDIOC_STREAMON\n"); - peasycap->isequence = 0; - for (i = 0; i < 180; i++) - peasycap->merit[i] = 0; - if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; + peasycap->isequence = 0; + for (i = 0; i < 180; i++) + peasycap->merit[i] = 0; + if (!peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } + submit_video_urbs(peasycap); + peasycap->video_idle = 0; + peasycap->audio_idle = 0; + peasycap->video_eof = 0; + peasycap->audio_eof = 0; + break; } - submit_video_urbs(peasycap); - peasycap->video_idle = 0; - peasycap->audio_idle = 0; - peasycap->video_eof = 0; - peasycap->audio_eof = 0; - break; -} /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_STREAMOFF: { - JOM(8, "VIDIOC_STREAMOFF\n"); + case VIDIOC_STREAMOFF: { + JOM(8, "VIDIOC_STREAMOFF\n"); - if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; - } + if (!peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - peasycap->video_idle = 1; - peasycap->audio_idle = 1; peasycap->timeval0.tv_sec = 0; + peasycap->video_idle = 1; + peasycap->audio_idle = 1; + peasycap->timeval0.tv_sec = 0; /*---------------------------------------------------------------------------*/ /* * IF THE WAIT QUEUES ARE NOT CLEARED IN RESPONSE TO THE STREAMOFF COMMAND * THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT. BEWARE. */ /*---------------------------------------------------------------------------*/ - JOM(8, "calling wake_up on wq_video and wq_audio\n"); - wake_up_interruptible(&(peasycap->wq_video)); - wake_up_interruptible(&(peasycap->wq_audio)); + JOM(8, "calling wake_up on wq_video and wq_audio\n"); + wake_up_interruptible(&(peasycap->wq_video)); +#ifdef CONFIG_EASYCAP_OSS + wake_up_interruptible(&(peasycap->wq_audio)); + +#else + if (peasycap->psubstream) + snd_pcm_period_elapsed(peasycap->psubstream); +#endif /* CONFIG_EASYCAP_OSS */ /*---------------------------------------------------------------------------*/ - break; -} -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_G_PARM: { - struct v4l2_streamparm *pv4l2_streamparm; - - JOM(8, "VIDIOC_G_PARM\n"); - pv4l2_streamparm = kzalloc(sizeof(struct v4l2_streamparm), GFP_KERNEL); - if (!pv4l2_streamparm) { - SAM("ERROR: out of memory\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -ENOMEM; - } - if (0 != copy_from_user(pv4l2_streamparm, (void __user *)arg, \ - sizeof(struct v4l2_streamparm))) { - kfree(pv4l2_streamparm); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; + break; } +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + case VIDIOC_G_PARM: { + struct v4l2_streamparm *pv4l2_streamparm; + + JOM(8, "VIDIOC_G_PARM\n"); + pv4l2_streamparm = kzalloc(sizeof(struct v4l2_streamparm), GFP_KERNEL); + if (!pv4l2_streamparm) { + SAM("ERROR: out of memory\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -ENOMEM; + } + if (copy_from_user(pv4l2_streamparm, + (void __user *)arg, sizeof(struct v4l2_streamparm))) { + kfree(pv4l2_streamparm); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EFAULT; + } - if (pv4l2_streamparm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - kfree(pv4l2_streamparm); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; - } - pv4l2_streamparm->parm.capture.capability = 0; - pv4l2_streamparm->parm.capture.capturemode = 0; - pv4l2_streamparm->parm.capture.timeperframe.numerator = 1; + if (pv4l2_streamparm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + kfree(pv4l2_streamparm); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; + } + pv4l2_streamparm->parm.capture.capability = 0; + pv4l2_streamparm->parm.capture.capturemode = 0; + pv4l2_streamparm->parm.capture.timeperframe.numerator = 1; - if (peasycap->fps) { - pv4l2_streamparm->parm.capture.timeperframe.\ - denominator = peasycap->fps; - } else { - if (true == peasycap->ntsc) { - pv4l2_streamparm->parm.capture.timeperframe.\ - denominator = 30; + if (peasycap->fps) { + pv4l2_streamparm->parm.capture.timeperframe. + denominator = peasycap->fps; } else { - pv4l2_streamparm->parm.capture.timeperframe.\ - denominator = 25; + if (peasycap->ntsc) { + pv4l2_streamparm->parm.capture.timeperframe. + denominator = 30; + } else { + pv4l2_streamparm->parm.capture.timeperframe. + denominator = 25; + } } - } - - pv4l2_streamparm->parm.capture.readbuffers = \ - peasycap->frame_buffer_many; - pv4l2_streamparm->parm.capture.extendedmode = 0; - if (0 != copy_to_user((void __user *)arg, pv4l2_streamparm, \ - sizeof(struct v4l2_streamparm))) { - kfree(pv4l2_streamparm); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EFAULT; - } - kfree(pv4l2_streamparm); - break; -} -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_S_PARM: { - JOM(8, "VIDIOC_S_PARM unsupported\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; -} -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_G_AUDIO: { - JOM(8, "VIDIOC_G_AUDIO unsupported\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; -} -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_S_AUDIO: { - JOM(8, "VIDIOC_S_AUDIO unsupported\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; -} -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_S_TUNER: { - JOM(8, "VIDIOC_S_TUNER unsupported\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; -} -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_G_FBUF: -case VIDIOC_S_FBUF: -case VIDIOC_OVERLAY: { - JOM(8, "VIDIOC_G_FBUF|VIDIOC_S_FBUF|VIDIOC_OVERLAY unsupported\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; -} -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -case VIDIOC_G_TUNER: { - JOM(8, "VIDIOC_G_TUNER unsupported\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; -} -case VIDIOC_G_FREQUENCY: -case VIDIOC_S_FREQUENCY: { - JOM(8, "VIDIOC_G_FREQUENCY|VIDIOC_S_FREQUENCY unsupported\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -EINVAL; -} -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -default: { - JOM(8, "ERROR: unrecognized V4L2 IOCTL command: 0x%08X\n", cmd); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -ENOIOCTLCMD; -} -} -mutex_unlock(&easycap_dongle[kd].mutex_video); -JOM(4, "unlocked easycap_dongle[%i].mutex_video\n", kd); -return 0; -} -/*****************************************************************************/ -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if ((defined(EASYCAP_IS_VIDEODEV_CLIENT)) || \ - (defined(EASYCAP_NEEDS_UNLOCKED_IOCTL))) -long -easysnd_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg) { - return (long)easysnd_ioctl((struct inode *)NULL, file, cmd, arg); -} -#endif /*EASYCAP_IS_VIDEODEV_CLIENT||EASYCAP_NEEDS_UNLOCKED_IOCTL*/ -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*---------------------------------------------------------------------------*/ -int -easysnd_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ -struct easycap *peasycap; -struct usb_device *p; -int kd; - -if (NULL == file) { - SAY("ERROR: file is NULL\n"); - return -ERESTARTSYS; -} -peasycap = file->private_data; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL.\n"); - return -EFAULT; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - return -EFAULT; -} -p = peasycap->pusb_device; -if (NULL == p) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -kd = isdongle(peasycap); -if (0 <= kd && DONGLE_MANY > kd) { - if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_audio)) { - SAY("ERROR: cannot lock easycap_dongle[%i].mutex_audio\n", kd); - return -ERESTARTSYS; - } - JOM(4, "locked easycap_dongle[%i].mutex_audio\n", kd); -/*---------------------------------------------------------------------------*/ -/* - * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap, - * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. - * IF NECESSARY, BAIL OUT. -*/ -/*---------------------------------------------------------------------------*/ - if (kd != isdongle(peasycap)) - return -ERESTARTSYS; - if (NULL == file) { - SAY("ERROR: file is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -ERESTARTSYS; - } - peasycap = file->private_data; - if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -ERESTARTSYS; - } - if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -EFAULT; - } - p = peasycap->pusb_device; - if (NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -ERESTARTSYS; - } -} else { -/*---------------------------------------------------------------------------*/ -/* - * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE - * ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED. BAIL OUT. -*/ -/*---------------------------------------------------------------------------*/ - return -ERESTARTSYS; -} -/*---------------------------------------------------------------------------*/ -switch (cmd) { -case SNDCTL_DSP_GETCAPS: { - int caps; - JOM(8, "SNDCTL_DSP_GETCAPS\n"); - -#if defined(UPSAMPLE) - if (true == peasycap->microphone) - caps = 0x04400000; - else - caps = 0x04400000; -#else - if (true == peasycap->microphone) - caps = 0x02400000; - else - caps = 0x04400000; -#endif /*UPSAMPLE*/ - - if (0 != copy_to_user((void __user *)arg, &caps, sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -EFAULT; - } - break; -} -case SNDCTL_DSP_GETFMTS: { - int incoming; - JOM(8, "SNDCTL_DSP_GETFMTS\n"); -#if defined(UPSAMPLE) - if (true == peasycap->microphone) - incoming = AFMT_S16_LE; - else - incoming = AFMT_S16_LE; -#else - if (true == peasycap->microphone) - incoming = AFMT_S16_LE; - else - incoming = AFMT_S16_LE; -#endif /*UPSAMPLE*/ - - if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -EFAULT; - } - break; -} -case SNDCTL_DSP_SETFMT: { - int incoming, outgoing; - JOM(8, "SNDCTL_DSP_SETFMT\n"); - if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -EFAULT; - } - JOM(8, "........... %i=incoming\n", incoming); - -#if defined(UPSAMPLE) - if (true == peasycap->microphone) - outgoing = AFMT_S16_LE; - else - outgoing = AFMT_S16_LE; -#else - if (true == peasycap->microphone) - outgoing = AFMT_S16_LE; - else - outgoing = AFMT_S16_LE; -#endif /*UPSAMPLE*/ - - if (incoming != outgoing) { - JOM(8, "........... %i=outgoing\n", outgoing); - JOM(8, " cf. %i=AFMT_S16_LE\n", AFMT_S16_LE); - JOM(8, " cf. %i=AFMT_U8\n", AFMT_U8); - if (0 != copy_to_user((void __user *)arg, &outgoing, \ - sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); + pv4l2_streamparm->parm.capture.readbuffers = + peasycap->frame_buffer_many; + pv4l2_streamparm->parm.capture.extendedmode = 0; + if (copy_to_user((void __user *)arg, + pv4l2_streamparm, + sizeof(struct v4l2_streamparm))) { + kfree(pv4l2_streamparm); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); return -EFAULT; } - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -EINVAL ; - } - break; -} -case SNDCTL_DSP_STEREO: { - int incoming; - JOM(8, "SNDCTL_DSP_STEREO\n"); - if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -EFAULT; + kfree(pv4l2_streamparm); + break; } - JOM(8, "........... %i=incoming\n", incoming); - -#if defined(UPSAMPLE) - if (true == peasycap->microphone) - incoming = 1; - else - incoming = 1; -#else - if (true == peasycap->microphone) - incoming = 0; - else - incoming = 1; -#endif /*UPSAMPLE*/ - - if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -EFAULT; +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + case VIDIOC_S_PARM: { + JOM(8, "VIDIOC_S_PARM unsupported\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; } - break; -} -case SNDCTL_DSP_SPEED: { - int incoming; - JOM(8, "SNDCTL_DSP_SPEED\n"); - if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -EFAULT; +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + case VIDIOC_G_AUDIO: { + JOM(8, "VIDIOC_G_AUDIO unsupported\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; } - JOM(8, "........... %i=incoming\n", incoming); - -#if defined(UPSAMPLE) - if (true == peasycap->microphone) - incoming = 32000; - else - incoming = 48000; -#else - if (true == peasycap->microphone) - incoming = 8000; - else - incoming = 48000; -#endif /*UPSAMPLE*/ - - if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -EFAULT; +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + case VIDIOC_S_AUDIO: { + JOM(8, "VIDIOC_S_AUDIO unsupported\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; } - break; -} -case SNDCTL_DSP_GETTRIGGER: { - int incoming; - JOM(8, "SNDCTL_DSP_GETTRIGGER\n"); - if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -EFAULT; +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + case VIDIOC_S_TUNER: { + JOM(8, "VIDIOC_S_TUNER unsupported\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; } - JOM(8, "........... %i=incoming\n", incoming); - - incoming = PCM_ENABLE_INPUT; - if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -EFAULT; +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + case VIDIOC_G_FBUF: + case VIDIOC_S_FBUF: + case VIDIOC_OVERLAY: { + JOM(8, "VIDIOC_G_FBUF|VIDIOC_S_FBUF|VIDIOC_OVERLAY unsupported\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; } - break; -} -case SNDCTL_DSP_SETTRIGGER: { - int incoming; - JOM(8, "SNDCTL_DSP_SETTRIGGER\n"); - if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -EFAULT; +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + case VIDIOC_G_TUNER: { + JOM(8, "VIDIOC_G_TUNER unsupported\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; } - JOM(8, "........... %i=incoming\n", incoming); - JOM(8, "........... cf 0x%x=PCM_ENABLE_INPUT " \ - "0x%x=PCM_ENABLE_OUTPUT\n", \ - PCM_ENABLE_INPUT, PCM_ENABLE_OUTPUT); - ; - ; - ; - ; - break; -} -case SNDCTL_DSP_GETBLKSIZE: { - int incoming; - JOM(8, "SNDCTL_DSP_GETBLKSIZE\n"); - if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -EFAULT; + case VIDIOC_G_FREQUENCY: + case VIDIOC_S_FREQUENCY: { + JOM(8, "VIDIOC_G_FREQUENCY|VIDIOC_S_FREQUENCY unsupported\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -EINVAL; } - JOM(8, "........... %i=incoming\n", incoming); - incoming = peasycap->audio_bytes_per_fragment; - if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -EFAULT; +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + default: { + JOM(8, "ERROR: unrecognized V4L2 IOCTL command: 0x%08X\n", cmd); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -ENOIOCTLCMD; } - break; -} -case SNDCTL_DSP_GETISPACE: { - struct audio_buf_info audio_buf_info; - - JOM(8, "SNDCTL_DSP_GETISPACE\n"); - - audio_buf_info.bytes = peasycap->audio_bytes_per_fragment; - audio_buf_info.fragments = 1; - audio_buf_info.fragsize = 0; - audio_buf_info.fragstotal = 0; - - if (0 != copy_to_user((void __user *)arg, &audio_buf_info, \ - sizeof(int))) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -EFAULT; } - break; -} -case 0x00005401: -case 0x00005402: -case 0x00005403: -case 0x00005404: -case 0x00005405: -case 0x00005406: { - JOM(8, "SNDCTL_TMR_...: 0x%08X unsupported\n", cmd); - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -ENOIOCTLCMD; -} -default: { - JOM(8, "ERROR: unrecognized DSP IOCTL command: 0x%08X\n", cmd); - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -ENOIOCTLCMD; -} -} -mutex_unlock(&easycap_dongle[kd].mutex_audio); -return 0; + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + JOM(4, "unlocked easycapdc60_dongle[%i].mutex_video\n", kd); + return 0; } /*****************************************************************************/ - - diff --git a/drivers/staging/easycap/easycap_ioctl.h b/drivers/staging/easycap/easycap_ioctl.h deleted file mode 100644 index 210cd627235..00000000000 --- a/drivers/staging/easycap/easycap_ioctl.h +++ /dev/null @@ -1,28 +0,0 @@ -/***************************************************************************** -* * -* easycap_ioctl.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 - * -*/ -/*****************************************************************************/ -extern struct easycap_format easycap_format[]; -extern struct v4l2_queryctrl easycap_control[]; diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index 28c4d1e3c02..0385735ac6d 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -39,10 +39,29 @@ /****************************************************************************/ #include "easycap.h" -#include "easycap_debug.h" + +#define GET(X, Y, Z) do { \ + int __rc; \ + *(Z) = (u16)0; \ + __rc = regget(X, Y, Z, sizeof(u8)); \ + 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) /*--------------------------------------------------------------------------*/ -const struct stk1160config { int reg; int set; } stk1160configPAL[256] = { +static const struct stk1160config { + int reg; + int set; +} stk1160configPAL[256] = { {0x000, 0x0098}, {0x002, 0x0093}, @@ -84,7 +103,7 @@ const struct stk1160config { int reg; int set; } stk1160configPAL[256] = { {0xFFF, 0xFFFF} }; /*--------------------------------------------------------------------------*/ -const struct stk1160config stk1160configNTSC[256] = { +static const struct stk1160config stk1160configNTSC[256] = { {0x000, 0x0098}, {0x002, 0x0093}, @@ -126,13 +145,12 @@ const struct stk1160config stk1160configNTSC[256] = { {0xFFF, 0xFFFF} }; /*--------------------------------------------------------------------------*/ -const struct saa7113config { int reg; int set; } saa7113configPAL[256] = { +static const struct saa7113config { + int reg; + int set; +} saa7113configPAL[256] = { {0x01, 0x08}, -#if defined(ANTIALIAS) - {0x02, 0xC0}, -#else {0x02, 0x80}, -#endif /*ANTIALIAS*/ {0x03, 0x33}, {0x04, 0x00}, {0x05, 0x00}, @@ -184,13 +202,9 @@ const struct saa7113config { int reg; int set; } saa7113configPAL[256] = { {0xFF, 0xFF} }; /*--------------------------------------------------------------------------*/ -const struct saa7113config saa7113configNTSC[256] = { +static const struct saa7113config saa7113configNTSC[256] = { {0x01, 0x08}, -#if defined(ANTIALIAS) - {0x02, 0xC0}, -#else {0x02, 0x80}, -#endif /*ANTIALIAS*/ {0x03, 0x33}, {0x04, 0x00}, {0x05, 0x00}, @@ -241,139 +255,210 @@ const struct saa7113config saa7113configNTSC[256] = { {0xFF, 0xFF} }; + +static int regget(struct usb_device *pusb_device, + u16 index, void *reg, int reg_size) +{ + int rc; + + if (!pusb_device) + return -ENODEV; + + rc = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), + 0x00, + (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), + 0x00, + index, reg, reg_size, 50000); + + return rc; +} + +static int regset(struct usb_device *pusb_device, u16 index, u16 value) +{ + int rc; + + if (!pusb_device) + return -ENODEV; + + rc = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), + 0x01, + (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE), + value, index, NULL, 0, 500); + + if (rc < 0) + return rc; + + if (easycap_readback) { + u16 igot = 0; + rc = regget(pusb_device, index, &igot, sizeof(igot)); + igot = 0xFF & igot; + switch (index) { + case 0x000: + case 0x500: + case 0x502: + case 0x503: + case 0x504: + case 0x506: + case 0x507: + break; + + case 0x204: + case 0x205: + case 0x350: + case 0x351: + if (igot) + JOT(8, "unexpected 0x%02X " + "for STK register 0x%03X\n", + igot, index); + break; + + default: + if ((0xFF & value) != igot) + JOT(8, "unexpected 0x%02X != 0x%02X " + "for STK register 0x%03X\n", + igot, value, index); + break; + } + } + + return rc; +} +/*--------------------------------------------------------------------------*/ +/* + * FUNCTION wait_i2c() RETURNS 0 ON SUCCESS +*/ /*--------------------------------------------------------------------------*/ +static int wait_i2c(struct usb_device *p) +{ + u16 get0; + u8 igot; + const int max = 2; + int k; + + if (!p) + return -ENODEV; + + for (k = 0; k < max; k++) { + GET(p, 0x0201, &igot); get0 = igot; + switch (get0) { + case 0x04: + case 0x01: + return 0; + case 0x00: + msleep(20); + continue; + default: + return get0 - 1; + } + } + return -1; +} /****************************************************************************/ -int -confirm_resolution(struct usb_device *p) +int confirm_resolution(struct usb_device *p) { -__u8 get0, get1, get2, get3, get4, get5, get6, get7; - -if (NULL == p) - return -ENODEV; -GET(p, 0x0110, &get0); -GET(p, 0x0111, &get1); -GET(p, 0x0112, &get2); -GET(p, 0x0113, &get3); -GET(p, 0x0114, &get4); -GET(p, 0x0115, &get5); -GET(p, 0x0116, &get6); -GET(p, 0x0117, &get7); -JOT(8, "0x%03X, 0x%03X, " \ - "0x%03X, 0x%03X, " \ - "0x%03X, 0x%03X, " \ - "0x%03X, 0x%03X\n", \ - get0, get1, get2, get3, get4, get5, get6, get7); -JOT(8, "....cf PAL_720x526: " \ - "0x%03X, 0x%03X, " \ - "0x%03X, 0x%03X, " \ - "0x%03X, 0x%03X, " \ - "0x%03X, 0x%03X\n", \ - 0x000, 0x000, 0x001, 0x000, 0x5A0, 0x005, 0x121, 0x001); -JOT(8, "....cf PAL_704x526: " \ - "0x%03X, 0x%03X, " \ - "0x%03X, 0x%03X, " \ - "0x%03X, 0x%03X, " \ - "0x%03X, 0x%03X\n", \ - 0x004, 0x000, 0x001, 0x000, 0x584, 0x005, 0x121, 0x001); -JOT(8, "....cf VGA_640x480: " \ - "0x%03X, 0x%03X, " \ - "0x%03X, 0x%03X, " \ - "0x%03X, 0x%03X, " \ - "0x%03X, 0x%03X\n", \ - 0x008, 0x000, 0x020, 0x000, 0x508, 0x005, 0x110, 0x001); -return 0; + u8 get0, get1, get2, get3, get4, get5, get6, get7; + + if (!p) + return -ENODEV; + GET(p, 0x0110, &get0); + GET(p, 0x0111, &get1); + GET(p, 0x0112, &get2); + GET(p, 0x0113, &get3); + GET(p, 0x0114, &get4); + GET(p, 0x0115, &get5); + GET(p, 0x0116, &get6); + GET(p, 0x0117, &get7); + JOT(8, "0x%03X, 0x%03X, " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X\n", + get0, get1, get2, get3, get4, get5, get6, get7); + JOT(8, "....cf PAL_720x526: " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X\n", + 0x000, 0x000, 0x001, 0x000, 0x5A0, 0x005, 0x121, 0x001); + JOT(8, "....cf PAL_704x526: " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X\n", + 0x004, 0x000, 0x001, 0x000, 0x584, 0x005, 0x121, 0x001); + JOT(8, "....cf VGA_640x480: " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X, " + "0x%03X, 0x%03X\n", + 0x008, 0x000, 0x020, 0x000, 0x508, 0x005, 0x110, 0x001); + return 0; } /****************************************************************************/ -int -confirm_stream(struct usb_device *p) +int confirm_stream(struct usb_device *p) { -__u16 get2; -__u8 igot; - -if (NULL == p) - return -ENODEV; -GET(p, 0x0100, &igot); get2 = 0x80 & igot; -if (0x80 == get2) - JOT(8, "confirm_stream: OK\n"); -else - JOT(8, "confirm_stream: STUCK\n"); -return 0; + u16 get2; + u8 igot; + + if (!p) + return -ENODEV; + GET(p, 0x0100, &igot); get2 = 0x80 & igot; + if (0x80 == get2) + JOT(8, "confirm_stream: OK\n"); + else + JOT(8, "confirm_stream: STUCK\n"); + return 0; } /****************************************************************************/ -int -setup_stk(struct usb_device *p, bool ntsc) +int setup_stk(struct usb_device *p, bool ntsc) { -int i0; - -if (NULL == p) - return -ENODEV; -i0 = 0; -if (true == ntsc) { - while (0xFFF != stk1160configNTSC[i0].reg) { - SET(p, stk1160configNTSC[i0].reg, stk1160configNTSC[i0].set); - i0++; - } -} else { - while (0xFFF != stk1160configPAL[i0].reg) { - SET(p, stk1160configPAL[i0].reg, stk1160configPAL[i0].set); - i0++; - } -} + int i; + const struct stk1160config *cfg; + if (!p) + return -ENODEV; + cfg = (ntsc) ? stk1160configNTSC : stk1160configPAL; + for (i = 0; cfg[i].reg != 0xFFF; i++) + SET(p, cfg[i].reg, cfg[i].set); -write_300(p); + write_300(p); -return 0; + return 0; } /****************************************************************************/ -int -setup_saa(struct usb_device *p, bool ntsc) +int setup_saa(struct usb_device *p, bool ntsc) { -int i0, ir; - -if (NULL == p) - return -ENODEV; -i0 = 0; -if (true == ntsc) { - while (0xFF != saa7113configNTSC[i0].reg) { - ir = write_saa(p, saa7113configNTSC[i0].reg, \ - saa7113configNTSC[i0].set); - i0++; - } -} else { - while (0xFF != saa7113configPAL[i0].reg) { - ir = write_saa(p, saa7113configPAL[i0].reg, \ - saa7113configPAL[i0].set); - i0++; - } -} -return 0; + int i, ir; + const struct saa7113config *cfg; + if (!p) + return -ENODEV; + cfg = (ntsc) ? saa7113configNTSC : saa7113configPAL; + for (i = 0; cfg[i].reg != 0xFF; i++) + ir = write_saa(p, cfg[i].reg, cfg[i].set); + return 0; } /****************************************************************************/ -int -write_000(struct usb_device *p, __u16 set2, __u16 set0) +int write_000(struct usb_device *p, u16 set2, u16 set0) { -__u8 igot0, igot2; - -if (NULL == p) - return -ENODEV; -GET(p, 0x0002, &igot2); -GET(p, 0x0000, &igot0); -SET(p, 0x0002, set2); -SET(p, 0x0000, set0); -return 0; + u8 igot0, igot2; + + if (!p) + return -ENODEV; + GET(p, 0x0002, &igot2); + GET(p, 0x0000, &igot0); + SET(p, 0x0002, set2); + SET(p, 0x0000, set0); + return 0; } /****************************************************************************/ -int -write_saa(struct usb_device *p, __u16 reg0, __u16 set0) +int write_saa(struct usb_device *p, u16 reg0, u16 set0) { -if (NULL == p) - return -ENODEV; -SET(p, 0x200, 0x00); -SET(p, 0x204, reg0); -SET(p, 0x205, set0); -SET(p, 0x200, 0x01); -return wait_i2c(p); + if (!p) + return -ENODEV; + SET(p, 0x200, 0x00); + SET(p, 0x204, reg0); + SET(p, 0x205, set0); + SET(p, 0x200, 0x01); + return wait_i2c(p); } /****************************************************************************/ /*--------------------------------------------------------------------------*/ @@ -386,32 +471,32 @@ return wait_i2c(p); */ /*--------------------------------------------------------------------------*/ int -write_vt(struct usb_device *p, __u16 reg0, __u16 set0) +write_vt(struct usb_device *p, u16 reg0, u16 set0) { -__u8 igot; -__u16 got502, got503; -__u16 set502, set503; + u8 igot; + u16 got502, got503; + u16 set502, set503; -if (NULL == p) - return -ENODEV; -SET(p, 0x0504, reg0); -SET(p, 0x0500, 0x008B); + if (!p) + return -ENODEV; + SET(p, 0x0504, reg0); + SET(p, 0x0500, 0x008B); -GET(p, 0x0502, &igot); got502 = (0xFF & igot); -GET(p, 0x0503, &igot); got503 = (0xFF & igot); + GET(p, 0x0502, &igot); got502 = (0xFF & igot); + GET(p, 0x0503, &igot); got503 = (0xFF & igot); -JOT(16, "write_vt(., 0x%04X, 0x%04X): was 0x%04X\n", \ - reg0, set0, ((got503 << 8) | got502)); + JOT(16, "write_vt(., 0x%04X, 0x%04X): was 0x%04X\n", + reg0, set0, ((got503 << 8) | got502)); -set502 = (0x00FF & set0); -set503 = ((0xFF00 & set0) >> 8); + set502 = (0x00FF & set0); + set503 = ((0xFF00 & set0) >> 8); -SET(p, 0x0504, reg0); -SET(p, 0x0502, set502); -SET(p, 0x0503, set503); -SET(p, 0x0500, 0x008C); + SET(p, 0x0504, reg0); + SET(p, 0x0502, set502); + SET(p, 0x0503, set503); + SET(p, 0x0500, 0x008C); -return 0; + return 0; } /****************************************************************************/ /*--------------------------------------------------------------------------*/ @@ -423,23 +508,23 @@ return 0; * REGISTER 504: TARGET ADDRESS ON VT1612A */ /*--------------------------------------------------------------------------*/ -int -read_vt(struct usb_device *p, __u16 reg0) +int read_vt(struct usb_device *p, u16 reg0) { -__u8 igot; -__u16 got502, got503; + u8 igot; + u16 got502, got503; -if (NULL == p) - return -ENODEV; -SET(p, 0x0504, reg0); -SET(p, 0x0500, 0x008B); + if (!p) + return -ENODEV; + SET(p, 0x0504, reg0); + SET(p, 0x0500, 0x008B); -GET(p, 0x0502, &igot); got502 = (0xFF & igot); -GET(p, 0x0503, &igot); got503 = (0xFF & igot); + GET(p, 0x0502, &igot); got502 = (0xFF & igot); + GET(p, 0x0503, &igot); got503 = (0xFF & igot); -JOT(16, "read_vt(., 0x%04X): has 0x%04X\n", reg0, ((got503 << 8) | got502)); + JOT(16, "read_vt(., 0x%04X): has 0x%04X\n", + reg0, ((got503 << 8) | got502)); -return (got503 << 8) | got502; + return (got503 << 8) | got502; } /****************************************************************************/ /*--------------------------------------------------------------------------*/ @@ -447,18 +532,17 @@ return (got503 << 8) | got502; * THESE APPEAR TO HAVE NO EFFECT ON EITHER VIDEO OR AUDIO. */ /*--------------------------------------------------------------------------*/ -int -write_300(struct usb_device *p) +int write_300(struct usb_device *p) { -if (NULL == p) - return -ENODEV; -SET(p, 0x300, 0x0012); -SET(p, 0x350, 0x002D); -SET(p, 0x351, 0x0001); -SET(p, 0x352, 0x0000); -SET(p, 0x353, 0x0000); -SET(p, 0x300, 0x0080); -return 0; + if (!p) + return -ENODEV; + SET(p, 0x300, 0x0012); + SET(p, 0x350, 0x002D); + SET(p, 0x351, 0x0001); + SET(p, 0x352, 0x0000); + SET(p, 0x353, 0x0000); + SET(p, 0x300, 0x0080); + return 0; } /****************************************************************************/ /*--------------------------------------------------------------------------*/ @@ -467,75 +551,42 @@ return 0; * REGISTER 0x0F, WHICH IS INVOLVED IN CHROMINANCE AUTOMATIC GAIN CONTROL. */ /*--------------------------------------------------------------------------*/ -int -check_saa(struct usb_device *p, bool ntsc) +int check_saa(struct usb_device *p, bool ntsc) { -int i0, ir, rc; - -if (NULL == p) - return -ENODEV; -i0 = 0; -rc = 0; -if (true == ntsc) { - while (0xFF != saa7113configNTSC[i0].reg) { - if (0x0F == saa7113configNTSC[i0].reg) { - i0++; + int i, ir, rc = 0; + struct saa7113config const *cfg; + if (!p) + return -ENODEV; + + cfg = (ntsc) ? saa7113configNTSC : saa7113configPAL; + for (i = 0; cfg[i].reg != 0xFF; i++) { + if (0x0F == cfg[i].reg) continue; + ir = read_saa(p, cfg[i].reg); + if (ir != cfg[i].set) { + SAY("SAA register 0x%02X has 0x%02X, expected 0x%02X\n", + cfg[i].reg, ir, cfg[i].set); + rc--; } - - ir = read_saa(p, saa7113configNTSC[i0].reg); - if (ir != saa7113configNTSC[i0].set) { - SAY("SAA register 0x%02X has 0x%02X, " \ - "expected 0x%02X\n", \ - saa7113configNTSC[i0].reg, \ - ir, saa7113configNTSC[i0].set); - rc--; - } - i0++; } -} else { - while (0xFF != saa7113configPAL[i0].reg) { - if (0x0F == saa7113configPAL[i0].reg) { - i0++; - continue; - } - ir = read_saa(p, saa7113configPAL[i0].reg); - if (ir != saa7113configPAL[i0].set) { - SAY("SAA register 0x%02X has 0x%02X, " \ - "expected 0x%02X\n", \ - saa7113configPAL[i0].reg, \ - ir, saa7113configPAL[i0].set); - rc--; - } - i0++; - } -} -if (-8 > rc) - return rc; -else - return 0; + return (rc < -8) ? rc : 0; } /****************************************************************************/ -int -merit_saa(struct usb_device *p) +int merit_saa(struct usb_device *p) { -int rc; - -if (NULL == p) - return -ENODEV; -rc = read_saa(p, 0x1F); -if ((0 > rc) || (0x02 & rc)) - return 1 ; -else - return 0; + int rc; + + if (!p) + return -ENODEV; + rc = read_saa(p, 0x1F); + return ((0 > rc) || (0x02 & rc)) ? 1 : 0; } /****************************************************************************/ -int -ready_saa(struct usb_device *p) +int ready_saa(struct usb_device *p) { -int j, rc, rate; -const int max = 5, marktime = PATIENCE/5; + int j, rc, rate; + const int max = 5, marktime = PATIENCE/5; /*--------------------------------------------------------------------------*/ /* * RETURNS 0 FOR INTERLACED 50 Hz @@ -544,38 +595,38 @@ const int max = 5, marktime = PATIENCE/5; * 3 FOR NON-INTERLACED 60 Hz */ /*--------------------------------------------------------------------------*/ -if (NULL == p) - return -ENODEV; -j = 0; -while (max > j) { - rc = read_saa(p, 0x1F); - if (0 <= rc) { - if (0 == (0x40 & rc)) - break; - if (1 == (0x01 & rc)) - break; - } - msleep(marktime); - j++; -} -if (max == j) - return -1; -else { - if (0x20 & rc) { - rate = 2; - JOT(8, "hardware detects 60 Hz\n"); - } else { - rate = 0; - JOT(8, "hardware detects 50 Hz\n"); + if (!p) + return -ENODEV; + j = 0; + while (max > j) { + rc = read_saa(p, 0x1F); + if (0 <= rc) { + if (0 == (0x40 & rc)) + break; + if (1 == (0x01 & rc)) + break; + } + msleep(marktime); + j++; } - if (0x80 & rc) - JOT(8, "hardware detects interlacing\n"); + if (max == j) + return -1; else { - rate++; - JOT(8, "hardware detects no interlacing\n"); + if (0x20 & rc) { + rate = 2; + JOT(8, "hardware detects 60 Hz\n"); + } else { + rate = 0; + JOT(8, "hardware detects 50 Hz\n"); + } + if (0x80 & rc) + JOT(8, "hardware detects interlacing\n"); + else { + rate++; + JOT(8, "hardware detects no interlacing\n"); + } } -} -return 0; + return 0; } /****************************************************************************/ /*--------------------------------------------------------------------------*/ @@ -585,106 +636,61 @@ return 0; * REGISTER 0x100: ACCEPT ALSO (0x80 | stk1160config....[.].set) */ /*--------------------------------------------------------------------------*/ -int -check_stk(struct usb_device *p, bool ntsc) +int check_stk(struct usb_device *p, bool ntsc) { -int i0, ir; - -if (NULL == p) - return -ENODEV; -i0 = 0; -if (true == ntsc) { - while (0xFFF != stk1160configNTSC[i0].reg) { - if (0x000 == stk1160configNTSC[i0].reg) { - i0++; continue; - } - if (0x002 == stk1160configNTSC[i0].reg) { - i0++; continue; - } - ir = read_stk(p, stk1160configNTSC[i0].reg); - if (0x100 == stk1160configNTSC[i0].reg) { - if ((ir != (0xFF & stk1160configNTSC[i0].set)) && \ - (ir != (0x80 | (0xFF & \ - stk1160configNTSC[i0].set))) && \ - (0xFFFF != \ - stk1160configNTSC[i0].set)) { - SAY("STK register 0x%03X has 0x%02X, " \ - "expected 0x%02X\n", \ - stk1160configNTSC[i0].reg, \ - ir, stk1160configNTSC[i0].set); - } - i0++; continue; - } - if ((ir != (0xFF & stk1160configNTSC[i0].set)) && \ - (0xFFFF != stk1160configNTSC[i0].set)) { - SAY("STK register 0x%03X has 0x%02X, " \ - "expected 0x%02X\n", \ - stk1160configNTSC[i0].reg, \ - ir, stk1160configNTSC[i0].set); - } - i0++; - } -} else { - while (0xFFF != stk1160configPAL[i0].reg) { - if (0x000 == stk1160configPAL[i0].reg) { - i0++; continue; - } - if (0x002 == stk1160configPAL[i0].reg) { - i0++; continue; - } - ir = read_stk(p, stk1160configPAL[i0].reg); - if (0x100 == stk1160configPAL[i0].reg) { - if ((ir != (0xFF & stk1160configPAL[i0].set)) && \ - (ir != (0x80 | (0xFF & \ - stk1160configPAL[i0].set))) && \ - (0xFFFF != \ - stk1160configPAL[i0].set)) { - SAY("STK register 0x%03X has 0x%02X, " \ - "expected 0x%02X\n", \ - stk1160configPAL[i0].reg, \ - ir, stk1160configPAL[i0].set); - } - i0++; continue; + int i, ir; + const struct stk1160config *cfg; + + if (!p) + return -ENODEV; + cfg = (ntsc) ? stk1160configNTSC : stk1160configPAL; + + for (i = 0; 0xFFF != cfg[i].reg; i++) { + if (0x000 == cfg[i].reg || 0x002 == cfg[i].reg) + continue; + + + ir = read_stk(p, cfg[i].reg); + if (0x100 == cfg[i].reg) { + if ((ir != (0xFF & cfg[i].set)) && + (ir != (0x80 | (0xFF & cfg[i].set))) && + (0xFFFF != cfg[i].set)) { + SAY("STK reg[0x%03X]=0x%02X expected 0x%02X\n", + cfg[i].reg, ir, cfg[i].set); } - if ((ir != (0xFF & stk1160configPAL[i0].set)) && \ - (0xFFFF != stk1160configPAL[i0].set)) { - SAY("STK register 0x%03X has 0x%02X, " \ - "expected 0x%02X\n", \ - stk1160configPAL[i0].reg, \ - ir, stk1160configPAL[i0].set); + continue; } - i0++; + if ((ir != (0xFF & cfg[i].set)) && (0xFFFF != cfg[i].set)) + SAY("STK register 0x%03X has 0x%02X,expected 0x%02X\n", + cfg[i].reg, ir, cfg[i].set); } -} -return 0; + return 0; } /****************************************************************************/ -int -read_saa(struct usb_device *p, __u16 reg0) +int read_saa(struct usb_device *p, u16 reg0) { -__u8 igot; + u8 igot; -if (NULL == p) - return -ENODEV; -SET(p, 0x208, reg0); -SET(p, 0x200, 0x20); -if (0 != wait_i2c(p)) - return -1; -igot = 0; -GET(p, 0x0209, &igot); -return igot; + if (!p) + return -ENODEV; + SET(p, 0x208, reg0); + SET(p, 0x200, 0x20); + if (0 != wait_i2c(p)) + return -1; + igot = 0; + GET(p, 0x0209, &igot); + return igot; } /****************************************************************************/ -int -read_stk(struct usb_device *p, __u32 reg0) +int read_stk(struct usb_device *p, u32 reg0) { -__u8 igot; + u8 igot; -if (NULL == p) - return -ENODEV; -igot = 0; -GET(p, reg0, &igot); -return igot; + if (!p) + return -ENODEV; + igot = 0; + GET(p, reg0, &igot); + return igot; } /****************************************************************************/ /*--------------------------------------------------------------------------*/ @@ -708,307 +714,186 @@ return igot; int select_input(struct usb_device *p, int input, int mode) { -int ir; - -if (NULL == p) - return -ENODEV; -stop_100(p); -switch (input) { -case 0: -case 1: { - if (0 != write_saa(p, 0x02, 0x80)) { - SAY("ERROR: failed to set SAA register 0x02 for input %i\n", \ - input); - } - SET(p, 0x0000, 0x0098); - SET(p, 0x0002, 0x0078); - break; -} -case 2: { - if (0 != write_saa(p, 0x02, 0x80)) { - SAY("ERROR: failed to set SAA register 0x02 for input %i\n", \ - input); + int ir; + + if (!p) + return -ENODEV; + stop_100(p); + switch (input) { + case 0: + case 1: { + if (0 != write_saa(p, 0x02, 0x80)) + SAY("ERROR: failed to set SAA register 0x02 " + "for input %i\n", input); + + SET(p, 0x0000, 0x0098); + SET(p, 0x0002, 0x0078); + break; } - SET(p, 0x0000, 0x0090); - SET(p, 0x0002, 0x0078); - break; -} -case 3: { - if (0 != write_saa(p, 0x02, 0x80)) { - SAY("ERROR: failed to set SAA register 0x02 for input %i\n", \ - input); + case 2: { + if (0 != write_saa(p, 0x02, 0x80)) + SAY("ERROR: failed to set SAA register 0x02 " + "for input %i\n", input); + + SET(p, 0x0000, 0x0090); + SET(p, 0x0002, 0x0078); + break; } - SET(p, 0x0000, 0x0088); - SET(p, 0x0002, 0x0078); - break; -} -case 4: { - if (0 != write_saa(p, 0x02, 0x80)) { - SAY("ERROR: failed to set SAA register 0x02 for input %i\n", \ - input); + case 3: { + if (0 != write_saa(p, 0x02, 0x80)) + SAY("ERROR: failed to set SAA register 0x02 " + " for input %i\n", input); + + SET(p, 0x0000, 0x0088); + SET(p, 0x0002, 0x0078); + break; } - SET(p, 0x0000, 0x0080); - SET(p, 0x0002, 0x0078); - break; -} -case 5: { - if (9 != mode) - mode = 7; - switch (mode) { - case 7: { - if (0 != write_saa(p, 0x02, 0x87)) { - SAY("ERROR: failed to set SAA register 0x02 " \ - "for input %i\n", input); - } - if (0 != write_saa(p, 0x05, 0xFF)) { - SAY("ERROR: failed to set SAA register 0x05 " \ + case 4: { + if (0 != write_saa(p, 0x02, 0x80)) { + SAY("ERROR: failed to set SAA register 0x02 " "for input %i\n", input); } + SET(p, 0x0000, 0x0080); + SET(p, 0x0002, 0x0078); break; } - case 9: { - if (0 != write_saa(p, 0x02, 0x89)) { - SAY("ERROR: failed to set SAA register 0x02 " \ + case 5: { + if (9 != mode) + mode = 7; + switch (mode) { + case 7: { + if (0 != write_saa(p, 0x02, 0x87)) + SAY("ERROR: failed to set SAA register 0x02 " + "for input %i\n", input); + + if (0 != write_saa(p, 0x05, 0xFF)) + SAY("ERROR: failed to set SAA register 0x05 " "for input %i\n", input); + + break; } - if (0 != write_saa(p, 0x05, 0x00)) { - SAY("ERROR: failed to set SAA register 0x05 " \ + case 9: { + if (0 != write_saa(p, 0x02, 0x89)) + SAY("ERROR: failed to set SAA register 0x02 " "for input %i\n", input); + + if (0 != write_saa(p, 0x05, 0x00)) + SAY("ERROR: failed to set SAA register 0x05 " + "for input %i\n", input); + + break; } - break; + default: + SAY("MISTAKE: bad mode: %i\n", mode); + return -1; + } + + if (0 != write_saa(p, 0x04, 0x00)) + SAY("ERROR: failed to set SAA register 0x04 " + "for input %i\n", input); + + if (0 != write_saa(p, 0x09, 0x80)) + SAY("ERROR: failed to set SAA register 0x09 " + "for input %i\n", input); + + SET(p, 0x0002, 0x0093); + break; } - default: { - SAY("MISTAKE: bad mode: %i\n", mode); + default: + SAY("ERROR: bad input: %i\n", input); return -1; } - } - if (0 != write_saa(p, 0x04, 0x00)) { - SAY("ERROR: failed to set SAA register 0x04 for input %i\n", \ - input); - } - if (0 != write_saa(p, 0x09, 0x80)) { - SAY("ERROR: failed to set SAA register 0x09 for input %i\n", \ - input); - } - SET(p, 0x0002, 0x0093); - break; -} -default: { - SAY("ERROR: bad input: %i\n", input); - return -1; -} -} -ir = read_stk(p, 0x00); -JOT(8, "STK register 0x00 has 0x%02X\n", ir); -ir = read_saa(p, 0x02); -JOT(8, "SAA register 0x02 has 0x%02X\n", ir); -start_100(p); + ir = read_stk(p, 0x00); + JOT(8, "STK register 0x00 has 0x%02X\n", ir); + ir = read_saa(p, 0x02); + JOT(8, "SAA register 0x02 has 0x%02X\n", ir); + + start_100(p); -return 0; + return 0; } /****************************************************************************/ -int -set_resolution(struct usb_device *p, \ - __u16 set0, __u16 set1, __u16 set2, __u16 set3) +int set_resolution(struct usb_device *p, + u16 set0, u16 set1, u16 set2, u16 set3) { -__u16 u0x0111, u0x0113, u0x0115, u0x0117; - -if (NULL == p) - return -ENODEV; -u0x0111 = ((0xFF00 & set0) >> 8); -u0x0113 = ((0xFF00 & set1) >> 8); -u0x0115 = ((0xFF00 & set2) >> 8); -u0x0117 = ((0xFF00 & set3) >> 8); - -SET(p, 0x0110, (0x00FF & set0)); -SET(p, 0x0111, u0x0111); -SET(p, 0x0112, (0x00FF & set1)); -SET(p, 0x0113, u0x0113); -SET(p, 0x0114, (0x00FF & set2)); -SET(p, 0x0115, u0x0115); -SET(p, 0x0116, (0x00FF & set3)); -SET(p, 0x0117, u0x0117); - -return 0; + u16 u0x0111, u0x0113, u0x0115, u0x0117; + + if (!p) + return -ENODEV; + u0x0111 = ((0xFF00 & set0) >> 8); + u0x0113 = ((0xFF00 & set1) >> 8); + u0x0115 = ((0xFF00 & set2) >> 8); + u0x0117 = ((0xFF00 & set3) >> 8); + + SET(p, 0x0110, (0x00FF & set0)); + SET(p, 0x0111, u0x0111); + SET(p, 0x0112, (0x00FF & set1)); + SET(p, 0x0113, u0x0113); + SET(p, 0x0114, (0x00FF & set2)); + SET(p, 0x0115, u0x0115); + SET(p, 0x0116, (0x00FF & set3)); + SET(p, 0x0117, u0x0117); + + return 0; } /****************************************************************************/ -int -start_100(struct usb_device *p) +int start_100(struct usb_device *p) { -__u16 get116, get117, get0; -__u8 igot116, igot117, igot; - -if (NULL == p) - return -ENODEV; -GET(p, 0x0116, &igot116); -get116 = igot116; -GET(p, 0x0117, &igot117); -get117 = igot117; -SET(p, 0x0116, 0x0000); -SET(p, 0x0117, 0x0000); - -GET(p, 0x0100, &igot); -get0 = igot; -SET(p, 0x0100, (0x80 | get0)); - -SET(p, 0x0116, get116); -SET(p, 0x0117, get117); - -return 0; + u16 get116, get117, get0; + u8 igot116, igot117, igot; + + if (!p) + return -ENODEV; + GET(p, 0x0116, &igot116); + get116 = igot116; + GET(p, 0x0117, &igot117); + get117 = igot117; + SET(p, 0x0116, 0x0000); + SET(p, 0x0117, 0x0000); + + GET(p, 0x0100, &igot); + get0 = igot; + SET(p, 0x0100, (0x80 | get0)); + + SET(p, 0x0116, get116); + SET(p, 0x0117, get117); + + return 0; } /****************************************************************************/ -int -stop_100(struct usb_device *p) +int stop_100(struct usb_device *p) { -__u16 get0; -__u8 igot; - -if (NULL == p) - return -ENODEV; -GET(p, 0x0100, &igot); -get0 = igot; -SET(p, 0x0100, (0x7F & get0)); -return 0; + u16 get0; + u8 igot; + + if (!p) + return -ENODEV; + GET(p, 0x0100, &igot); + get0 = igot; + SET(p, 0x0100, (0x7F & get0)); + return 0; } /****************************************************************************/ -/*--------------------------------------------------------------------------*/ -/* - * FUNCTION wait_i2c() RETURNS 0 ON SUCCESS -*/ -/*--------------------------------------------------------------------------*/ -int -wait_i2c(struct usb_device *p) -{ -__u16 get0; -__u8 igot; -const int max = 2; -int k; - -if (NULL == p) - return -ENODEV; -for (k = 0; k < max; k++) { - GET(p, 0x0201, &igot); get0 = igot; - switch (get0) { - case 0x04: - case 0x01: { - return 0; - } - case 0x00: { - msleep(20); - continue; - } - default: { - return get0 - 1; - } - } -} -return -1; -} /****************************************************************************/ -int -regset(struct usb_device *pusb_device, __u16 index, __u16 value) -{ -__u16 igot; -int rc0, rc1; - -if (!pusb_device) - return -ENODEV; -rc1 = 0; igot = 0; -rc0 = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), \ - (__u8)0x01, \ - (__u8)(USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE), \ - (__u16)value, \ - (__u16)index, \ - (void *)NULL, \ - (__u16)0, \ - (int)500); - -#if defined(NOREADBACK) -# -#else -rc1 = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), \ - (__u8)0x00, \ - (__u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), \ - (__u16)0x00, \ - (__u16)index, \ - (void *)&igot, \ - (__u16)sizeof(__u16), \ - (int)50000); -igot = 0xFF & igot; -switch (index) { -case 0x000: -case 0x500: -case 0x502: -case 0x503: -case 0x504: -case 0x506: -case 0x507: { - break; -} -case 0x204: -case 0x205: -case 0x350: -case 0x351: { - if (0 != (0xFF & igot)) { - JOT(8, "unexpected 0x%02X for STK register 0x%03X\n", \ - igot, index); - } -break; -} -default: { - if ((0xFF & value) != (0xFF & igot)) { - JOT(8, "unexpected 0x%02X != 0x%02X " \ - "for STK register 0x%03X\n", \ - igot, value, index); - } -break; -} -} -#endif /* ! NOREADBACK*/ - -return (0 > rc0) ? rc0 : rc1; -} /*****************************************************************************/ -int -regget(struct usb_device *pusb_device, __u16 index, void *pvoid) -{ -int ir; - -if (!pusb_device) - return -ENODEV; -ir = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), \ - (__u8)0x00, \ - (__u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), \ - (__u16)0x00, \ - (__u16)index, \ - (void *)pvoid, \ - sizeof(__u8), \ - (int)50000); -return 0xFF & ir; -} -/*****************************************************************************/ -int -wakeup_device(struct usb_device *pusb_device) +int wakeup_device(struct usb_device *pusb_device) { -if (!pusb_device) - return -ENODEV; -return usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), \ - (__u8)USB_REQ_SET_FEATURE, \ - (__u8)(USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE), \ - USB_DEVICE_REMOTE_WAKEUP, \ - (__u16)0, \ - (void *) NULL, \ - (__u16)0, \ - (int)50000); + if (!pusb_device) + return -ENODEV; + return usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), + USB_REQ_SET_FEATURE, + USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, + USB_DEVICE_REMOTE_WAKEUP, + 0, NULL, 0, 50000); } /*****************************************************************************/ int audio_setup(struct easycap *peasycap) { -struct usb_device *pusb_device; -unsigned char buffer[1]; -int rc, id1, id2; + struct usb_device *pusb_device; + u8 buffer[1]; + int rc, id1, id2; /*---------------------------------------------------------------------------*/ /* * IMPORTANT: @@ -1017,44 +902,47 @@ int rc, id1, id2; * TO ENABLE AUDIO THE VALUE 0x0200 MUST BE SENT. */ /*---------------------------------------------------------------------------*/ -const __u8 request = 0x01; -const __u8 requesttype = \ - (__u8)(USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE); -const __u16 value_unmute = 0x0200; -const __u16 index = 0x0301; -const __u16 length = 1; - -if (NULL == peasycap) - return -EFAULT; - -pusb_device = peasycap->pusb_device; -if (NULL == pusb_device) - return -ENODEV; - -JOM(8, "%02X %02X %02X %02X %02X %02X %02X %02X\n", \ - requesttype, request, \ - (0x00FF & value_unmute), \ - (0xFF00 & value_unmute) >> 8, \ - (0x00FF & index), \ - (0xFF00 & index) >> 8, \ - (0x00FF & length), \ - (0xFF00 & length) >> 8); - -buffer[0] = 0x01; - -rc = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), \ - (__u8)request, \ - (__u8)requesttype, \ - (__u16)value_unmute, \ - (__u16)index, \ - (void *)&buffer[0], \ - (__u16)length, \ - (int)50000); - -JOT(8, "0x%02X=buffer\n", *((__u8 *) &buffer[0])); -if (rc != (int)length) - SAY("ERROR: usb_control_msg returned %i\n", rc); - + const u8 request = 0x01; + const u8 requesttype = USB_DIR_OUT | + USB_TYPE_CLASS | + USB_RECIP_INTERFACE; + const u16 value_unmute = 0x0200; + const u16 index = 0x0301; + const u16 length = 1; + + if (!peasycap) + return -EFAULT; + + pusb_device = peasycap->pusb_device; + if (!pusb_device) + return -ENODEV; + + JOM(8, "%02X %02X %02X %02X %02X %02X %02X %02X\n", + requesttype, request, + (0x00FF & value_unmute), + (0xFF00 & value_unmute) >> 8, + (0x00FF & index), + (0xFF00 & index) >> 8, + (0x00FF & length), + (0xFF00 & length) >> 8); + + buffer[0] = 0x01; + + rc = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), + request, requesttype, value_unmute, + index, &buffer[0], length, 50000); + + JOT(8, "0x%02X=buffer\n", buffer[0]); + if (rc != (int)length) { + switch (rc) { + case -EPIPE: + SAY("usb_control_msg returned -EPIPE\n"); + break; + default: + SAY("ERROR: usb_control_msg returned %i\n", rc); + break; + } + } /*--------------------------------------------------------------------------*/ /* * REGISTER 500: SETTING VALUE TO 0x0094 RESETS AUDIO CONFIGURATION ??? @@ -1070,84 +958,79 @@ if (rc != (int)length) * THE UPPER BYTE SEEMS TO HAVE NO EFFECT. */ /*--------------------------------------------------------------------------*/ -SET(pusb_device, 0x0500, 0x0094); -SET(pusb_device, 0x0500, 0x008C); -SET(pusb_device, 0x0506, 0x0001); -SET(pusb_device, 0x0507, 0x0000); -id1 = read_vt(pusb_device, 0x007C); -id2 = read_vt(pusb_device, 0x007E); -SAM("0x%04X:0x%04X is audio vendor id\n", id1, id2); + SET(pusb_device, 0x0500, 0x0094); + SET(pusb_device, 0x0500, 0x008C); + SET(pusb_device, 0x0506, 0x0001); + SET(pusb_device, 0x0507, 0x0000); + id1 = read_vt(pusb_device, 0x007C); + id2 = read_vt(pusb_device, 0x007E); + SAM("0x%04X:0x%04X is audio vendor id\n", id1, id2); /*---------------------------------------------------------------------------*/ /* * SELECT AUDIO SOURCE "LINE IN" AND SET THE AUDIO GAIN. */ /*---------------------------------------------------------------------------*/ -if (31 < easycap_gain) - easycap_gain = 31; -if (0 > easycap_gain) - easycap_gain = 0; -if (0 != audio_gainset(pusb_device, (__s8)easycap_gain)) - SAY("ERROR: audio_gainset() failed\n"); -check_vt(pusb_device); -return 0; + if (0 != audio_gainset(pusb_device, peasycap->gain)) + SAY("ERROR: audio_gainset() failed\n"); + check_vt(pusb_device); + return 0; } /*****************************************************************************/ -int -check_vt(struct usb_device *pusb_device) +int check_vt(struct usb_device *pusb_device) { -int igot; - -if (!pusb_device) - return -ENODEV; -igot = read_vt(pusb_device, 0x0002); -if (0 > igot) - SAY("ERROR: failed to read VT1612A register 0x02\n"); -if (0x8000 & igot) - SAY("register 0x%02X muted\n", 0x02); - -igot = read_vt(pusb_device, 0x000E); -if (0 > igot) - SAY("ERROR: failed to read VT1612A register 0x0E\n"); -if (0x8000 & igot) - SAY("register 0x%02X muted\n", 0x0E); - -igot = read_vt(pusb_device, 0x0010); -if (0 > igot) - SAY("ERROR: failed to read VT1612A register 0x10\n"); -if (0x8000 & igot) - SAY("register 0x%02X muted\n", 0x10); - -igot = read_vt(pusb_device, 0x0012); -if (0 > igot) - SAY("ERROR: failed to read VT1612A register 0x12\n"); -if (0x8000 & igot) - SAY("register 0x%02X muted\n", 0x12); - -igot = read_vt(pusb_device, 0x0014); -if (0 > igot) - SAY("ERROR: failed to read VT1612A register 0x14\n"); -if (0x8000 & igot) - SAY("register 0x%02X muted\n", 0x14); - -igot = read_vt(pusb_device, 0x0016); -if (0 > igot) - SAY("ERROR: failed to read VT1612A register 0x16\n"); -if (0x8000 & igot) - SAY("register 0x%02X muted\n", 0x16); - -igot = read_vt(pusb_device, 0x0018); -if (0 > igot) - SAY("ERROR: failed to read VT1612A register 0x18\n"); -if (0x8000 & igot) - SAY("register 0x%02X muted\n", 0x18); - -igot = read_vt(pusb_device, 0x001C); -if (0 > igot) - SAY("ERROR: failed to read VT1612A register 0x1C\n"); -if (0x8000 & igot) - SAY("register 0x%02X muted\n", 0x1C); - -return 0; + int igot; + + if (!pusb_device) + return -ENODEV; + igot = read_vt(pusb_device, 0x0002); + if (0 > igot) + SAY("ERROR: failed to read VT1612A register 0x02\n"); + if (0x8000 & igot) + SAY("register 0x%02X muted\n", 0x02); + + igot = read_vt(pusb_device, 0x000E); + if (0 > igot) + SAY("ERROR: failed to read VT1612A register 0x0E\n"); + if (0x8000 & igot) + SAY("register 0x%02X muted\n", 0x0E); + + igot = read_vt(pusb_device, 0x0010); + if (0 > igot) + SAY("ERROR: failed to read VT1612A register 0x10\n"); + if (0x8000 & igot) + SAY("register 0x%02X muted\n", 0x10); + + igot = read_vt(pusb_device, 0x0012); + if (0 > igot) + SAY("ERROR: failed to read VT1612A register 0x12\n"); + if (0x8000 & igot) + SAY("register 0x%02X muted\n", 0x12); + + igot = read_vt(pusb_device, 0x0014); + if (0 > igot) + SAY("ERROR: failed to read VT1612A register 0x14\n"); + if (0x8000 & igot) + SAY("register 0x%02X muted\n", 0x14); + + igot = read_vt(pusb_device, 0x0016); + if (0 > igot) + SAY("ERROR: failed to read VT1612A register 0x16\n"); + if (0x8000 & igot) + SAY("register 0x%02X muted\n", 0x16); + + igot = read_vt(pusb_device, 0x0018); + if (0 > igot) + SAY("ERROR: failed to read VT1612A register 0x18\n"); + if (0x8000 & igot) + SAY("register 0x%02X muted\n", 0x18); + + igot = read_vt(pusb_device, 0x001C); + if (0 > igot) + SAY("ERROR: failed to read VT1612A register 0x1C\n"); + if (0x8000 & igot) + SAY("register 0x%02X muted\n", 0x1C); + + return 0; } /*****************************************************************************/ /*---------------------------------------------------------------------------*/ @@ -1164,85 +1047,83 @@ return 0; * 31 12.0 22.5 34.5 */ /*---------------------------------------------------------------------------*/ -int -audio_gainset(struct usb_device *pusb_device, __s8 loud) +int audio_gainset(struct usb_device *pusb_device, s8 loud) { -int igot; -__u8 u8; -__u16 mute; - -if (NULL == pusb_device) - return -ENODEV; -if (0 > loud) - loud = 0; -if (31 < loud) - loud = 31; - -write_vt(pusb_device, 0x0002, 0x8000); + int igot; + u8 tmp; + u16 mute; + + if (!pusb_device) + return -ENODEV; + if (0 > loud) + loud = 0; + if (31 < loud) + loud = 31; + + write_vt(pusb_device, 0x0002, 0x8000); /*---------------------------------------------------------------------------*/ -igot = read_vt(pusb_device, 0x000E); -if (0 > igot) { - SAY("ERROR: failed to read VT1612A register 0x0E\n"); - mute = 0x0000; -} else - mute = 0x8000 & ((unsigned int)igot); -mute = 0; - -if (16 > loud) - u8 = 0x01 | (0x001F & (((__u8)(15 - loud)) << 1)); -else - u8 = 0; - -JOT(8, "0x%04X=(mute|u8) for VT1612A register 0x0E\n", mute | u8); -write_vt(pusb_device, 0x000E, (mute | u8)); + igot = read_vt(pusb_device, 0x000E); + if (0 > igot) { + SAY("ERROR: failed to read VT1612A register 0x0E\n"); + mute = 0x0000; + } else + mute = 0x8000 & ((unsigned int)igot); + mute = 0; + + if (16 > loud) + tmp = 0x01 | (0x001F & (((u8)(15 - loud)) << 1)); + else + tmp = 0; + + JOT(8, "0x%04X=(mute|tmp) for VT1612A register 0x0E\n", mute | tmp); + write_vt(pusb_device, 0x000E, (mute | tmp)); /*---------------------------------------------------------------------------*/ -igot = read_vt(pusb_device, 0x0010); -if (0 > igot) { - SAY("ERROR: failed to read VT1612A register 0x10\n"); - mute = 0x0000; -} else - mute = 0x8000 & ((unsigned int)igot); -mute = 0; - -JOT(8, "0x%04X=(mute|u8|(u8<<8)) for VT1612A register 0x10,...0x18\n", \ - mute | u8 | (u8 << 8)); -write_vt(pusb_device, 0x0010, (mute | u8 | (u8 << 8))); -write_vt(pusb_device, 0x0012, (mute | u8 | (u8 << 8))); -write_vt(pusb_device, 0x0014, (mute | u8 | (u8 << 8))); -write_vt(pusb_device, 0x0016, (mute | u8 | (u8 << 8))); -write_vt(pusb_device, 0x0018, (mute | u8 | (u8 << 8))); + igot = read_vt(pusb_device, 0x0010); + if (0 > igot) { + SAY("ERROR: failed to read VT1612A register 0x10\n"); + mute = 0x0000; + } else + mute = 0x8000 & ((unsigned int)igot); + mute = 0; + + JOT(8, "0x%04X=(mute|tmp|(tmp<<8)) for VT1612A register 0x10,...0x18\n", + mute | tmp | (tmp << 8)); + write_vt(pusb_device, 0x0010, (mute | tmp | (tmp << 8))); + write_vt(pusb_device, 0x0012, (mute | tmp | (tmp << 8))); + write_vt(pusb_device, 0x0014, (mute | tmp | (tmp << 8))); + write_vt(pusb_device, 0x0016, (mute | tmp | (tmp << 8))); + write_vt(pusb_device, 0x0018, (mute | tmp | (tmp << 8))); /*---------------------------------------------------------------------------*/ -igot = read_vt(pusb_device, 0x001C); -if (0 > igot) { - SAY("ERROR: failed to read VT1612A register 0x1C\n"); - mute = 0x0000; -} else - mute = 0x8000 & ((unsigned int)igot); -mute = 0; - -if (16 <= loud) - u8 = 0x000F & (__u8)(loud - 16); -else - u8 = 0; - -JOT(8, "0x%04X=(mute|u8|(u8<<8)) for VT1612A register 0x1C\n", \ - mute | u8 | (u8 << 8)); -write_vt(pusb_device, 0x001C, (mute | u8 | (u8 << 8))); -write_vt(pusb_device, 0x001A, 0x0404); -write_vt(pusb_device, 0x0002, 0x0000); -return 0; + igot = read_vt(pusb_device, 0x001C); + if (0 > igot) { + SAY("ERROR: failed to read VT1612A register 0x1C\n"); + mute = 0x0000; + } else + mute = 0x8000 & ((unsigned int)igot); + mute = 0; + + if (16 <= loud) + tmp = 0x000F & (u8)(loud - 16); + else + tmp = 0; + + JOT(8, "0x%04X=(mute|tmp|(tmp<<8)) for VT1612A register 0x1C\n", + mute | tmp | (tmp << 8)); + write_vt(pusb_device, 0x001C, (mute | tmp | (tmp << 8))); + write_vt(pusb_device, 0x001A, 0x0404); + write_vt(pusb_device, 0x0002, 0x0000); + return 0; } /*****************************************************************************/ -int -audio_gainget(struct usb_device *pusb_device) +int audio_gainget(struct usb_device *pusb_device) { -int igot; - -if (NULL == pusb_device) - return -ENODEV; -igot = read_vt(pusb_device, 0x001C); -if (0 > igot) - SAY("ERROR: failed to read VT1612A register 0x1C\n"); -return igot; + int igot; + + if (!pusb_device) + return -ENODEV; + igot = read_vt(pusb_device, 0x001C); + if (0 > igot) + SAY("ERROR: failed to read VT1612A register 0x1C\n"); + return igot; } /*****************************************************************************/ diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index acc1f56e6f2..cee3252ea2d 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -29,47 +29,86 @@ /*****************************************************************************/ #include "easycap.h" -#include "easycap_standard.h" -#include "easycap_ioctl.h" +#include <linux/usb/audio.h> -static int easycap_debug; -static int easycap_bars; -int easycap_gain = 16; + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("R.M. Thomas <rmthomas@sciolus.org>"); +MODULE_DESCRIPTION(EASYCAP_DRIVER_DESCRIPTION); +MODULE_VERSION(EASYCAP_DRIVER_VERSION); + +#ifdef CONFIG_EASYCAP_DEBUG +int easycap_debug; module_param_named(debug, easycap_debug, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(debug, "Debug level: 0(default),1,2,...,9"); +#endif /* CONFIG_EASYCAP_DEBUG */ + +bool easycap_readback; +module_param_named(readback, easycap_readback, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(readback, "read back written registers: (default false)"); + +static int easycap_bars = 1; module_param_named(bars, easycap_bars, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(bars, + "Testcard bars on input signal failure: 0=>no, 1=>yes(default)"); + +static int easycap_gain = 16; module_param_named(gain, easycap_gain, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(gain, "Audio gain: 0,...,16(default),...31"); -/*---------------------------------------------------------------------------*/ -/* - * dongle_this IS INDISPENSIBLY static BECAUSE FUNCTION easycap_usb_probe() - * IS CALLED SUCCESSIVELY FOR INTERFACES 0, 1, 2 AND THE POINTER peasycap - * ALLOCATED DURING THE PROBING OF INTERFACE 0 MUST BE REMEMBERED WHEN - * PROBING INTERFACES 1 AND 2. - * - * IOCTL LOCKING IS DONE AT MODULE LEVEL, NOT DEVICE LEVEL. -*/ -/*---------------------------------------------------------------------------*/ +static bool easycap_ntsc; +module_param_named(ntsc, easycap_ntsc, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(ntsc, "NTCS default encoding (default PAL)"); -struct easycap_dongle easycap_dongle[DONGLE_MANY]; -static int dongle_this; -static int dongle_done; -/*---------------------------------------------------------------------------*/ -/* - * PARAMETERS APPLICABLE TO ENTIRE DRIVER, I.E. BOTH VIDEO AND AUDIO - */ -/*---------------------------------------------------------------------------*/ -struct usb_device_id easycap_usb_device_id_table[] = { -{ USB_DEVICE(USB_EASYCAP_VENDOR_ID, USB_EASYCAP_PRODUCT_ID) }, -{ } -}; -MODULE_DEVICE_TABLE(usb, easycap_usb_device_id_table); -struct usb_driver easycap_usb_driver = { -.name = "easycap", -.id_table = easycap_usb_device_id_table, -.probe = easycap_usb_probe, -.disconnect = easycap_usb_disconnect, -}; + +struct easycap_dongle easycapdc60_dongle[DONGLE_MANY]; +static struct mutex mutex_dongle; +static void easycap_complete(struct urb *purb); +static int reset(struct easycap *peasycap); + +const char *strerror(int err) +{ +#define ERRNOSTR(_e) case _e: return # _e + switch (err) { + case 0: return "OK"; + ERRNOSTR(ENOMEM); + ERRNOSTR(ENODEV); + ERRNOSTR(ENXIO); + ERRNOSTR(EINVAL); + ERRNOSTR(EAGAIN); + ERRNOSTR(EFBIG); + ERRNOSTR(EPIPE); + ERRNOSTR(EMSGSIZE); + ERRNOSTR(ENOSPC); + ERRNOSTR(EINPROGRESS); + ERRNOSTR(ENOSR); + ERRNOSTR(EOVERFLOW); + ERRNOSTR(EPROTO); + ERRNOSTR(EILSEQ); + ERRNOSTR(ETIMEDOUT); + ERRNOSTR(EOPNOTSUPP); + ERRNOSTR(EPFNOSUPPORT); + ERRNOSTR(EAFNOSUPPORT); + ERRNOSTR(EADDRINUSE); + ERRNOSTR(EADDRNOTAVAIL); + ERRNOSTR(ENOBUFS); + ERRNOSTR(EISCONN); + ERRNOSTR(ENOTCONN); + ERRNOSTR(ESHUTDOWN); + ERRNOSTR(ENOENT); + ERRNOSTR(ECONNRESET); + ERRNOSTR(ETIME); + ERRNOSTR(ECOMM); + ERRNOSTR(EREMOTEIO); + ERRNOSTR(EXDEV); + ERRNOSTR(EPERM); + default: return "unknown"; + } + +#undef ERRNOSTR +} + /*---------------------------------------------------------------------------*/ /* * PARAMETERS USED WHEN REGISTERING THE VIDEO INTERFACE @@ -79,171 +118,77 @@ struct usb_driver easycap_usb_driver = { * THIS IS THE CASE FOR OpenSUSE. */ /*---------------------------------------------------------------------------*/ -const struct file_operations easycap_fops = { - .owner = THIS_MODULE, - .open = easycap_open, - .release = easycap_release, -#if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL) - .unlocked_ioctl = easycap_ioctl_noinode, -#else - .ioctl = easycap_ioctl, -#endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/ - .poll = easycap_poll, - .mmap = easycap_mmap, - .llseek = no_llseek, -}; -struct vm_operations_struct easycap_vm_ops = { - .open = easycap_vma_open, - .close = easycap_vma_close, - .fault = easycap_vma_fault, -}; -struct usb_class_driver easycap_class = { - .name = "usb/easycap%d", - .fops = &easycap_fops, - .minor_base = USB_SKEL_MINOR_BASE, -}; -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if defined(EASYCAP_IS_VIDEODEV_CLIENT) -#if defined(EASYCAP_NEEDS_V4L2_FOPS) -const struct v4l2_file_operations v4l2_fops = { - .owner = THIS_MODULE, - .open = easycap_open_noinode, - .release = easycap_release_noinode, -#if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL) - .unlocked_ioctl = easycap_ioctl_noinode, -#else - .ioctl = easycap_ioctl, -#endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/ - .poll = easycap_poll, - .mmap = easycap_mmap, -}; -#endif /*EASYCAP_NEEDS_V4L2_FOPS*/ -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*--------------------------------------------------------------------------*/ -/* - * PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE - */ -/*--------------------------------------------------------------------------*/ -const struct file_operations easysnd_fops = { - .owner = THIS_MODULE, - .open = easysnd_open, - .release = easysnd_release, -#if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL) - .unlocked_ioctl = easysnd_ioctl_noinode, -#else - .ioctl = easysnd_ioctl, -#endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/ - .read = easysnd_read, - .llseek = no_llseek, -}; -struct usb_class_driver easysnd_class = { -.name = "usb/easysnd%d", -.fops = &easysnd_fops, -.minor_base = USB_SKEL_MINOR_BASE, -}; /****************************************************************************/ /*---------------------------------------------------------------------------*/ /* * THIS ROUTINE DOES NOT DETECT DUPLICATE OCCURRENCES OF POINTER peasycap */ /*---------------------------------------------------------------------------*/ -int -isdongle(struct easycap *peasycap) +int isdongle(struct easycap *peasycap) { -int k; -if (NULL == peasycap) - return -2; -for (k = 0; k < DONGLE_MANY; k++) { - if (easycap_dongle[k].peasycap == peasycap) { - peasycap->isdongle = k; - return k; + int k; + if (!peasycap) + return -2; + for (k = 0; k < DONGLE_MANY; k++) { + if (easycapdc60_dongle[k].peasycap == peasycap) { + peasycap->isdongle = k; + return k; + } } + return -1; } -return -1; -} -/*****************************************************************************/ -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if defined(EASYCAP_IS_VIDEODEV_CLIENT) -int -easycap_open_noinode(struct file *file) -{ -return easycap_open((struct inode *)NULL, file); -} -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -int -easycap_open(struct inode *inode, struct file *file) +static int easycap_open(struct inode *inode, struct file *file) { -#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) -struct usb_interface *pusb_interface; -#else -struct video_device *pvideo_device; -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ -struct easycap *peasycap; -int rc; + struct video_device *pvideo_device; + struct easycap *peasycap; + int rc; -JOT(4, "\n"); -SAY("==========OPEN=========\n"); + JOT(4, "\n"); + SAY("==========OPEN=========\n"); -peasycap = (struct easycap *)NULL; -/*---------------------------------------------------------------------------*/ -#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) -if ((struct inode *)NULL == inode) { - SAY("ERROR: inode is NULL.\n"); - return -EFAULT; -} -pusb_interface = usb_find_interface(&easycap_usb_driver, iminor(inode)); -if (!pusb_interface) { - SAY("ERROR: pusb_interface is NULL.\n"); - return -EFAULT; -} -peasycap = usb_get_intfdata(pusb_interface); -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#else -pvideo_device = video_devdata(file); -if ((struct video_device *)NULL == pvideo_device) { - SAY("ERROR: pvideo_device is NULL.\n"); - return -EFAULT; -} -peasycap = (struct easycap *)video_get_drvdata(pvideo_device); -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); - return -EFAULT; -} -if (NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} else { - JOM(16, "0x%08lX=peasycap->pusb_device\n", \ - (long int)peasycap->pusb_device); -} -file->private_data = peasycap; -rc = wakeup_device(peasycap->pusb_device); -if (0 == rc) - JOM(8, "wakeup_device() OK\n"); -else { - SAM("ERROR: wakeup_device() returned %i\n", rc); - if (-ENODEV == rc) - SAM("ERROR: wakeup_device() returned -ENODEV\n"); - else - SAM("ERROR: wakeup_device() returned %i\n", rc); - return rc; -} -peasycap->input = 0; -rc = reset(peasycap); -if (0 != rc) { - SAM("ERROR: reset() returned %i\n", rc); - return -EFAULT; -} -return 0; + pvideo_device = video_devdata(file); + if (!pvideo_device) { + SAY("ERROR: pvideo_device is NULL.\n"); + return -EFAULT; + } + peasycap = (struct easycap *)video_get_drvdata(pvideo_device); + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: %p\n", peasycap); + return -EFAULT; + } + if (!peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; + } else { + JOM(16, "peasycap->pusb_device=%p\n", peasycap->pusb_device); + } + file->private_data = peasycap; + rc = wakeup_device(peasycap->pusb_device); + if (0 == rc) + JOM(8, "wakeup_device() OK\n"); + else { + SAM("ERROR: wakeup_device() rc = %i\n", rc); + if (-ENODEV == rc) + SAM("ERROR: wakeup_device() returned -ENODEV\n"); + else + SAM("ERROR: wakeup_device() rc = %i\n", rc); + return rc; + } + peasycap->input = 0; + rc = reset(peasycap); + if (rc) { + SAM("ERROR: reset() rc = %i\n", rc); + return -EFAULT; + } + return 0; } + /*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* @@ -253,18 +198,18 @@ return 0; * A BAD VIDEO FRAME SIZE. */ /*---------------------------------------------------------------------------*/ -int -reset(struct easycap *peasycap) +static int reset(struct easycap *peasycap) { -struct easycap_standard const *peasycap_standard; -int i, rc, input, rate; -bool ntsc, other; + struct easycap_standard const *peasycap_standard; + int i, rc, input, rate; + bool ntsc, other; + int fmtidx; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -input = peasycap->input; + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + input = peasycap->input; /*---------------------------------------------------------------------------*/ /* @@ -277,74 +222,70 @@ input = peasycap->input; * COMPLETE, SO SHOULD NOT BE INVOKED WITHOUT GOOD REASON. */ /*---------------------------------------------------------------------------*/ -other = false; -if (true == peasycap->ntsc) - JOM(8, "true=peasycap->ntsc\n"); -else - JOM(8, "false=peasycap->ntsc\n"); -rate = ready_saa(peasycap->pusb_device); -if (0 > rate) { - JOM(8, "not ready to capture after %i ms ...\n", PATIENCE); - if (true == peasycap->ntsc) { - JOM(8, "... trying PAL ...\n"); ntsc = false; - } else { - JOM(8, "... trying NTSC ...\n"); ntsc = true; -} -rc = setup_stk(peasycap->pusb_device, ntsc); -if (0 == rc) - JOM(4, "setup_stk() OK\n"); -else { - SAM("ERROR: setup_stk() returned %i\n", rc); - return -EFAULT; -} -rc = setup_saa(peasycap->pusb_device, ntsc); -if (0 == rc) - JOM(4, "setup_saa() OK\n"); -else { - SAM("ERROR: setup_saa() returned %i\n", rc); - return -EFAULT; -} -rate = ready_saa(peasycap->pusb_device); -if (0 > rate) { - JOM(8, "not ready to capture after %i ms ...\n", PATIENCE); - JOM(8, "... saa register 0x1F has 0x%02X\n", \ - read_saa(peasycap->pusb_device, 0x1F)); - ntsc = peasycap->ntsc; + other = false; + JOM(8, "peasycap->ntsc=%d\n", peasycap->ntsc); + + rate = ready_saa(peasycap->pusb_device); + if (0 > rate) { + JOM(8, "not ready to capture after %i ms ...\n", PATIENCE); + if (peasycap->ntsc) { + JOM(8, "... trying PAL ...\n"); ntsc = false; + } else { + JOM(8, "... trying NTSC ...\n"); ntsc = true; + } + rc = setup_stk(peasycap->pusb_device, ntsc); + if (0 == rc) + JOM(4, "setup_stk() OK\n"); + else { + SAM("ERROR: setup_stk() rc = %i\n", rc); + return -EFAULT; + } + rc = setup_saa(peasycap->pusb_device, ntsc); + if (0 == rc) + JOM(4, "setup_saa() OK\n"); + else { + SAM("ERROR: setup_saa() rc = %i\n", rc); + return -EFAULT; + } + rate = ready_saa(peasycap->pusb_device); + if (0 > rate) { + JOM(8, "not ready to capture after %i ms ...\n", PATIENCE); + JOM(8, "... saa register 0x1F has 0x%02X\n", + read_saa(peasycap->pusb_device, 0x1F)); + ntsc = peasycap->ntsc; + } else { + JOM(8, "... success at second try: %i=rate\n", rate); + ntsc = (0 < (rate/2)) ? true : false ; + other = true; + } } else { - JOM(8, "... success at second try: %i=rate\n", rate); - ntsc = (0 < (rate/2)) ? true : false ; - other = true; + JOM(8, "... success at first try: %i=rate\n", rate); + ntsc = (0 < rate/2) ? true : false ; } -} else { - JOM(8, "... success at first try: %i=rate\n", rate); - ntsc = (0 < rate/2) ? true : false ; -} -if (true == ntsc) - JOM(8, "true=ntsc\n"); -else - JOM(8, "false=ntsc\n"); -/*---------------------------------------------------------------------------*/ - -rc = setup_stk(peasycap->pusb_device, ntsc); -if (0 == rc) - JOM(4, "setup_stk() OK\n"); -else { - SAM("ERROR: setup_stk() returned %i\n", rc); - return -EFAULT; -} -rc = setup_saa(peasycap->pusb_device, ntsc); -if (0 == rc) - JOM(4, "setup_saa() OK\n"); -else { - SAM("ERROR: setup_saa() returned %i\n", rc); - return -EFAULT; -} + JOM(8, "ntsc=%d\n", ntsc); +/*---------------------------------------------------------------------------*/ + + rc = setup_stk(peasycap->pusb_device, ntsc); + if (0 == rc) + JOM(4, "setup_stk() OK\n"); + else { + SAM("ERROR: setup_stk() rc = %i\n", rc); + return -EFAULT; + } + rc = setup_saa(peasycap->pusb_device, ntsc); + if (0 == rc) + JOM(4, "setup_saa() OK\n"); + else { + SAM("ERROR: setup_saa() rc = %i\n", rc); + return -EFAULT; + } + + for (i = 0; i < 180; i++) + peasycap->merit[i] = 0; -for (i = 0; i < 180; i++) - peasycap->merit[i] = 0; -peasycap->video_eof = 0; -peasycap->audio_eof = 0; -do_gettimeofday(&peasycap->timeval7); + peasycap->video_eof = 0; + peasycap->audio_eof = 0; + do_gettimeofday(&peasycap->timeval7); /*---------------------------------------------------------------------------*/ /* * RESTORE INPUT AND FORCE REFRESH OF STANDARD, FORMAT, ETC. @@ -352,87 +293,75 @@ do_gettimeofday(&peasycap->timeval7); * WHILE THIS PROCEDURE IS IN PROGRESS, SOME IOCTL COMMANDS WILL RETURN -EBUSY. */ /*---------------------------------------------------------------------------*/ -peasycap->input = -8192; -peasycap->standard_offset = -8192; -if (true == other) { - peasycap_standard = &easycap_standard[0]; - while (0xFFFF != peasycap_standard->mask) { - if (true == ntsc) { - if (NTSC_M == \ - peasycap_standard->v4l2_standard.index) { - peasycap->inputset[input].standard_offset = \ - peasycap_standard - \ - &easycap_standard[0]; - break; - } - } else { - if (PAL_BGHIN == \ - peasycap_standard->v4l2_standard.index) { - peasycap->inputset[input].standard_offset = \ - peasycap_standard - - &easycap_standard[0]; + peasycap->input = -8192; + peasycap->standard_offset = -8192; + fmtidx = ntsc ? NTSC_M : PAL_BGHIN; + if (other) { + peasycap_standard = &easycap_standard[0]; + while (0xFFFF != peasycap_standard->mask) { + if (fmtidx == peasycap_standard->v4l2_standard.index) { + peasycap->inputset[input].standard_offset = + peasycap_standard - easycap_standard; break; } + peasycap_standard++; } - peasycap_standard++; - } - if (0xFFFF == peasycap_standard->mask) { - SAM("ERROR: standard not found\n"); - return -EINVAL; + if (0xFFFF == peasycap_standard->mask) { + SAM("ERROR: standard not found\n"); + return -EINVAL; + } + JOM(8, "%i=peasycap->inputset[%i].standard_offset\n", + peasycap->inputset[input].standard_offset, input); } -JOM(8, "%i=peasycap->inputset[%i].standard_offset\n", \ - peasycap->inputset[input].standard_offset, input); -} -peasycap->format_offset = -8192; -peasycap->brightness = -8192; -peasycap->contrast = -8192; -peasycap->saturation = -8192; -peasycap->hue = -8192; + peasycap->format_offset = -8192; + peasycap->brightness = -8192; + peasycap->contrast = -8192; + peasycap->saturation = -8192; + peasycap->hue = -8192; -rc = newinput(peasycap, input); + rc = newinput(peasycap, input); -if (0 == rc) + if (rc) { + SAM("ERROR: newinput(.,%i) rc = %i\n", rc, input); + return -EFAULT; + } JOM(4, "restored input, standard and format\n"); -else { - SAM("ERROR: newinput(.,%i) returned %i\n", rc, input); - return -EFAULT; -} -if (true == peasycap->ntsc) - JOM(8, "true=peasycap->ntsc\n"); -else - JOM(8, "false=peasycap->ntsc\n"); - -if (0 > peasycap->input) { - SAM("MISTAKE: %i=peasycap->input\n", peasycap->input); - return -ENOENT; -} -if (0 > peasycap->standard_offset) { - SAM("MISTAKE: %i=peasycap->standard_offset\n", \ - peasycap->standard_offset); - return -ENOENT; -} -if (0 > peasycap->format_offset) { - SAM("MISTAKE: %i=peasycap->format_offset\n", \ - peasycap->format_offset); - return -ENOENT; -} -if (0 > peasycap->brightness) { - SAM("MISTAKE: %i=peasycap->brightness\n", peasycap->brightness); - return -ENOENT; -} -if (0 > peasycap->contrast) { - SAM("MISTAKE: %i=peasycap->contrast\n", peasycap->contrast); - return -ENOENT; -} -if (0 > peasycap->saturation) { - SAM("MISTAKE: %i=peasycap->saturation\n", peasycap->saturation); - return -ENOENT; -} -if (0 > peasycap->hue) { - SAM("MISTAKE: %i=peasycap->hue\n", peasycap->hue); - return -ENOENT; -} -return 0; + + JOM(8, "true=peasycap->ntsc %d\n", peasycap->ntsc); + + if (0 > peasycap->input) { + SAM("MISTAKE: %i=peasycap->input\n", peasycap->input); + return -ENOENT; + } + if (0 > peasycap->standard_offset) { + SAM("MISTAKE: %i=peasycap->standard_offset\n", + peasycap->standard_offset); + return -ENOENT; + } + if (0 > peasycap->format_offset) { + SAM("MISTAKE: %i=peasycap->format_offset\n", + peasycap->format_offset); + return -ENOENT; + } + if (0 > peasycap->brightness) { + SAM("MISTAKE: %i=peasycap->brightness\n", + peasycap->brightness); + return -ENOENT; + } + if (0 > peasycap->contrast) { + SAM("MISTAKE: %i=peasycap->contrast\n", peasycap->contrast); + return -ENOENT; + } + if (0 > peasycap->saturation) { + SAM("MISTAKE: %i=peasycap->saturation\n", + peasycap->saturation); + return -ENOENT; + } + if (0 > peasycap->hue) { + SAM("MISTAKE: %i=peasycap->hue\n", peasycap->hue); + return -ENOENT; + } + return 0; } /*****************************************************************************/ /*---------------------------------------------------------------------------*/ @@ -454,21 +383,21 @@ return 0; int newinput(struct easycap *peasycap, int input) { -int rc, k, m, mood, off; -int inputnow, video_idlenow, audio_idlenow; -bool resubmit; + int rc, k, m, mood, off; + int inputnow, video_idlenow, audio_idlenow; + bool resubmit; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -JOM(8, "%i=input sought\n", input); + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + JOM(8, "%i=input sought\n", input); -if (0 > input && INPUT_MANY <= input) - return -ENOENT; -inputnow = peasycap->input; -if (input == inputnow) - return 0; + if (0 > input && INPUT_MANY <= input) + return -ENOENT; + inputnow = peasycap->input; + if (input == inputnow) + return 0; /*---------------------------------------------------------------------------*/ /* * IF STREAMING IS IN PROGRESS THE URBS ARE KILLED AT THIS @@ -477,414 +406,317 @@ if (input == inputnow) * ROUTINE. */ /*---------------------------------------------------------------------------*/ -video_idlenow = peasycap->video_idle; -audio_idlenow = peasycap->audio_idle; + video_idlenow = peasycap->video_idle; + audio_idlenow = peasycap->audio_idle; -peasycap->video_idle = 1; -peasycap->audio_idle = 1; -if (peasycap->video_isoc_streaming) { - resubmit = true; - kill_video_urbs(peasycap); -} else - resubmit = false; -/*---------------------------------------------------------------------------*/ -if (NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -ENODEV; -} -rc = usb_set_interface(peasycap->pusb_device, - peasycap->video_interface, \ - peasycap->video_altsetting_off); -if (0 != rc) { - SAM("ERROR: usb_set_interface() returned %i\n", rc); - return -EFAULT; -} -rc = stop_100(peasycap->pusb_device); -if (0 != rc) { - SAM("ERROR: stop_100() returned %i\n", rc); - return -EFAULT; -} -for (k = 0; k < FIELD_BUFFER_MANY; k++) { - for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) - memset(peasycap->field_buffer[k][m].pgo, 0, PAGE_SIZE); -} -for (k = 0; k < FRAME_BUFFER_MANY; k++) { - for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) - memset(peasycap->frame_buffer[k][m].pgo, 0, PAGE_SIZE); -} -peasycap->field_page = 0; -peasycap->field_read = 0; -peasycap->field_fill = 0; - -peasycap->frame_read = 0; -peasycap->frame_fill = 0; -for (k = 0; k < peasycap->input; k++) { - (peasycap->frame_fill)++; - if (peasycap->frame_buffer_many <= peasycap->frame_fill) - peasycap->frame_fill = 0; -} -peasycap->input = input; -select_input(peasycap->pusb_device, peasycap->input, 9); + peasycap->video_idle = 1; + peasycap->audio_idle = 1; + if (peasycap->video_isoc_streaming) { + resubmit = true; + kill_video_urbs(peasycap); + } else { + resubmit = false; + } /*---------------------------------------------------------------------------*/ -if (input == peasycap->inputset[input].input) { - off = peasycap->inputset[input].standard_offset; - if (off != peasycap->standard_offset) { - rc = adjust_standard(peasycap, \ + if (!peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -ENODEV; + } + rc = usb_set_interface(peasycap->pusb_device, + peasycap->video_interface, + peasycap->video_altsetting_off); + if (rc) { + SAM("ERROR: usb_set_interface() rc = %i\n", rc); + return -EFAULT; + } + rc = stop_100(peasycap->pusb_device); + if (rc) { + SAM("ERROR: stop_100() rc = %i\n", rc); + return -EFAULT; + } + for (k = 0; k < FIELD_BUFFER_MANY; k++) { + for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) + memset(peasycap->field_buffer[k][m].pgo, 0, PAGE_SIZE); + } + for (k = 0; k < FRAME_BUFFER_MANY; k++) { + for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) + memset(peasycap->frame_buffer[k][m].pgo, 0, PAGE_SIZE); + } + peasycap->field_page = 0; + peasycap->field_read = 0; + peasycap->field_fill = 0; + + peasycap->frame_read = 0; + peasycap->frame_fill = 0; + for (k = 0; k < peasycap->input; k++) { + (peasycap->frame_fill)++; + if (peasycap->frame_buffer_many <= peasycap->frame_fill) + peasycap->frame_fill = 0; + } + peasycap->input = input; + select_input(peasycap->pusb_device, peasycap->input, 9); +/*---------------------------------------------------------------------------*/ + if (input == peasycap->inputset[input].input) { + off = peasycap->inputset[input].standard_offset; + if (off != peasycap->standard_offset) { + rc = adjust_standard(peasycap, easycap_standard[off].v4l2_standard.id); - if (0 != rc) { - SAM("ERROR: adjust_standard() returned %i\n", rc); - return -EFAULT; - } - JOM(8, "%i=peasycap->standard_offset\n", \ - peasycap->standard_offset); - } else { - JOM(8, "%i=peasycap->standard_offset unchanged\n", \ + if (rc) { + SAM("ERROR: adjust_standard() rc = %i\n", rc); + return -EFAULT; + } + JOM(8, "%i=peasycap->standard_offset\n", + peasycap->standard_offset); + } else { + JOM(8, "%i=peasycap->standard_offset unchanged\n", peasycap->standard_offset); - } - off = peasycap->inputset[input].format_offset; - if (off != peasycap->format_offset) { - rc = adjust_format(peasycap, \ - easycap_format[off].v4l2_format.fmt.pix.width, \ - easycap_format[off].v4l2_format.fmt.pix.height, \ - easycap_format[off].v4l2_format.fmt.pix.pixelformat, \ - easycap_format[off].v4l2_format.fmt.pix.field, false); - if (0 > rc) { - SAM("ERROR: adjust_format() returned %i\n", rc); - return -EFAULT; } - JOM(8, "%i=peasycap->format_offset\n", peasycap->format_offset); - } else { - JOM(8, "%i=peasycap->format_offset unchanged\n", \ - peasycap->format_offset); - } - mood = peasycap->inputset[input].brightness; - if (mood != peasycap->brightness) { - rc = adjust_brightness(peasycap, mood); - if (0 != rc) { - SAM("ERROR: adjust_brightness returned %i\n", rc); - return -EFAULT; + off = peasycap->inputset[input].format_offset; + if (off != peasycap->format_offset) { + struct v4l2_pix_format *pix = + &easycap_format[off].v4l2_format.fmt.pix; + rc = adjust_format(peasycap, + pix->width, pix->height, + pix->pixelformat, pix->field, false); + if (0 > rc) { + SAM("ERROR: adjust_format() rc = %i\n", rc); + return -EFAULT; + } + JOM(8, "%i=peasycap->format_offset\n", + peasycap->format_offset); + } else { + JOM(8, "%i=peasycap->format_offset unchanged\n", + peasycap->format_offset); } - JOM(8, "%i=peasycap->brightness\n", peasycap->brightness); - } - mood = peasycap->inputset[input].contrast; - if (mood != peasycap->contrast) { - rc = adjust_contrast(peasycap, mood); - if (0 != rc) { - SAM("ERROR: adjust_contrast returned %i\n", rc); - return -EFAULT; + mood = peasycap->inputset[input].brightness; + if (mood != peasycap->brightness) { + rc = adjust_brightness(peasycap, mood); + if (rc) { + SAM("ERROR: adjust_brightness rc = %i\n", rc); + return -EFAULT; + } + JOM(8, "%i=peasycap->brightness\n", + peasycap->brightness); } - JOM(8, "%i=peasycap->contrast\n", peasycap->contrast); - } - mood = peasycap->inputset[input].saturation; - if (mood != peasycap->saturation) { - rc = adjust_saturation(peasycap, mood); - if (0 != rc) { - SAM("ERROR: adjust_saturation returned %i\n", rc); - return -EFAULT; + mood = peasycap->inputset[input].contrast; + if (mood != peasycap->contrast) { + rc = adjust_contrast(peasycap, mood); + if (rc) { + SAM("ERROR: adjust_contrast rc = %i\n", rc); + return -EFAULT; + } + JOM(8, "%i=peasycap->contrast\n", peasycap->contrast); } - JOM(8, "%i=peasycap->saturation\n", peasycap->saturation); - } - mood = peasycap->inputset[input].hue; - if (mood != peasycap->hue) { - rc = adjust_hue(peasycap, mood); - if (0 != rc) { - SAM("ERROR: adjust_hue returned %i\n", rc); - return -EFAULT; + mood = peasycap->inputset[input].saturation; + if (mood != peasycap->saturation) { + rc = adjust_saturation(peasycap, mood); + if (rc) { + SAM("ERROR: adjust_saturation rc = %i\n", rc); + return -EFAULT; + } + JOM(8, "%i=peasycap->saturation\n", + peasycap->saturation); } - JOM(8, "%i=peasycap->hue\n", peasycap->hue); + mood = peasycap->inputset[input].hue; + if (mood != peasycap->hue) { + rc = adjust_hue(peasycap, mood); + if (rc) { + SAM("ERROR: adjust_hue rc = %i\n", rc); + return -EFAULT; + } + JOM(8, "%i=peasycap->hue\n", peasycap->hue); + } + } else { + SAM("MISTAKE: easycap.inputset[%i] unpopulated\n", input); + return -ENOENT; } -} else { - SAM("MISTAKE: easycap.inputset[%i] unpopulated\n", input); - return -ENOENT; -} /*---------------------------------------------------------------------------*/ -if (NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -ENODEV; -} -rc = usb_set_interface(peasycap->pusb_device, - peasycap->video_interface, \ - peasycap->video_altsetting_on); -if (0 != rc) { - SAM("ERROR: usb_set_interface() returned %i\n", rc); - return -EFAULT; -} -rc = start_100(peasycap->pusb_device); -if (0 != rc) { - SAM("ERROR: start_100() returned %i\n", rc); - return -EFAULT; -} -if (true == resubmit) - submit_video_urbs(peasycap); + if (!peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -ENODEV; + } + rc = usb_set_interface(peasycap->pusb_device, + peasycap->video_interface, + peasycap->video_altsetting_on); + if (rc) { + SAM("ERROR: usb_set_interface() rc = %i\n", rc); + return -EFAULT; + } + rc = start_100(peasycap->pusb_device); + if (rc) { + SAM("ERROR: start_100() rc = %i\n", rc); + return -EFAULT; + } + if (resubmit) + submit_video_urbs(peasycap); -peasycap->video_isoc_sequence = VIDEO_ISOC_BUFFER_MANY - 1; -peasycap->video_idle = video_idlenow; -peasycap->audio_idle = audio_idlenow; -peasycap->video_junk = 0; + peasycap->video_isoc_sequence = VIDEO_ISOC_BUFFER_MANY - 1; + peasycap->video_idle = video_idlenow; + peasycap->audio_idle = audio_idlenow; + peasycap->video_junk = 0; -return 0; + return 0; } /*****************************************************************************/ -int -submit_video_urbs(struct easycap *peasycap) +int submit_video_urbs(struct easycap *peasycap) { -struct data_urb *pdata_urb; -struct urb *purb; -struct list_head *plist_head; -int j, isbad, nospc, m, rc; -int isbuf; - -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} + struct data_urb *pdata_urb; + struct urb *purb; + struct list_head *plist_head; + int j, isbad, nospc, m, rc; + int isbuf; -if (NULL == peasycap->purb_video_head) { - SAY("ERROR: peasycap->urb_video_head uninitialized\n"); - return -EFAULT; -} -if (NULL == peasycap->pusb_device) { - SAY("ERROR: peasycap->pusb_device is NULL\n"); - return -ENODEV; -} -if (!peasycap->video_isoc_streaming) { - JOM(4, "submission of all video urbs\n"); - isbad = 0; nospc = 0; m = 0; - list_for_each(plist_head, (peasycap->purb_video_head)) { - pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if (NULL != pdata_urb) { - purb = pdata_urb->purb; - if (NULL != purb) { + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + + if (!peasycap->purb_video_head) { + SAY("ERROR: peasycap->urb_video_head uninitialized\n"); + return -EFAULT; + } + if (!peasycap->pusb_device) { + SAY("ERROR: peasycap->pusb_device is NULL\n"); + return -ENODEV; + } + if (!peasycap->video_isoc_streaming) { + JOM(4, "submission of all video urbs\n"); + isbad = 0; nospc = 0; m = 0; + list_for_each(plist_head, (peasycap->purb_video_head)) { + pdata_urb = list_entry(plist_head, + struct data_urb, list_head); + if (pdata_urb && pdata_urb->purb) { + purb = pdata_urb->purb; isbuf = pdata_urb->isbuf; purb->interval = 1; purb->dev = peasycap->pusb_device; - purb->pipe = \ - usb_rcvisocpipe(peasycap->pusb_device,\ + purb->pipe = + usb_rcvisocpipe(peasycap->pusb_device, peasycap->video_endpointnumber); purb->transfer_flags = URB_ISO_ASAP; - purb->transfer_buffer = \ + purb->transfer_buffer = peasycap->video_isoc_buffer[isbuf].pgo; - purb->transfer_buffer_length = \ + purb->transfer_buffer_length = peasycap->video_isoc_buffer_size; purb->complete = easycap_complete; purb->context = peasycap; purb->start_frame = 0; - purb->number_of_packets = \ + purb->number_of_packets = peasycap->video_isoc_framesperdesc; - for (j = 0; j < peasycap->\ - video_isoc_framesperdesc; j++) { - purb->iso_frame_desc[j].\ - offset = j * \ - peasycap->\ - video_isoc_maxframesize; - purb->iso_frame_desc[j].\ - length = peasycap->\ - video_isoc_maxframesize; - } + for (j = 0; j < peasycap->video_isoc_framesperdesc; j++) { + purb->iso_frame_desc[j]. offset = + j * peasycap->video_isoc_maxframesize; + purb->iso_frame_desc[j]. length = + peasycap->video_isoc_maxframesize; + } rc = usb_submit_urb(purb, GFP_KERNEL); - if (0 != rc) { + if (rc) { isbad++; - SAM("ERROR: usb_submit_urb() failed " \ - "for urb with rc:\n"); - switch (rc) { - case -ENOMEM: { - SAM("ERROR: -ENOMEM=" \ - "usb_submit_urb()\n"); - break; - } - case -ENODEV: { - SAM("ERROR: -ENODEV=" \ - "usb_submit_urb()\n"); - break; - } - case -ENXIO: { - SAM("ERROR: -ENXIO=" \ - "usb_submit_urb()\n"); - break; - } - case -EINVAL: { - SAM("ERROR: -EINVAL=" \ - "usb_submit_urb()\n"); - break; - } - case -EAGAIN: { - SAM("ERROR: -EAGAIN=" \ - "usb_submit_urb()\n"); - break; - } - case -EFBIG: { - SAM("ERROR: -EFBIG=" \ - "usb_submit_urb()\n"); - break; - } - case -EPIPE: { - SAM("ERROR: -EPIPE=" \ - "usb_submit_urb()\n"); - break; - } - case -EMSGSIZE: { - SAM("ERROR: -EMSGSIZE=" \ - "usb_submit_urb()\n"); - break; - } - case -ENOSPC: { + SAM("ERROR: usb_submit_urb() failed " + "for urb with rc:-%s\n", + strerror(rc)); + if (rc == -ENOSPC) nospc++; - break; - } - default: { - SAM("ERROR: %i=" \ - "usb_submit_urb()\n",\ - rc); - break; - } - } } else { m++; } - } else { - isbad++; - } } else { - isbad++; + isbad++; } } - if (nospc) { - SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc); - SAM("..... possibly inadequate USB bandwidth\n"); - peasycap->video_eof = 1; - } + if (nospc) { + SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc); + SAM("..... possibly inadequate USB bandwidth\n"); + peasycap->video_eof = 1; + } - if (isbad) { - JOM(4, "attempting cleanup instead of submitting\n"); - list_for_each(plist_head, (peasycap->purb_video_head)) { - pdata_urb = list_entry(plist_head, struct data_urb, \ - list_head); - if (NULL != pdata_urb) { - purb = pdata_urb->purb; - if (NULL != purb) - usb_kill_urb(purb); + if (isbad) { + JOM(4, "attempting cleanup instead of submitting\n"); + list_for_each(plist_head, (peasycap->purb_video_head)) { + pdata_urb = list_entry(plist_head, + struct data_urb, list_head); + if (pdata_urb) { + purb = pdata_urb->purb; + if (purb) + usb_kill_urb(purb); + } } + peasycap->video_isoc_streaming = 0; + } else { + peasycap->video_isoc_streaming = 1; + JOM(4, "submitted %i video urbs\n", m); } - peasycap->video_isoc_streaming = 0; } else { - peasycap->video_isoc_streaming = 1; - JOM(4, "submitted %i video urbs\n", m); + JOM(4, "already streaming video urbs\n"); } -} else { - JOM(4, "already streaming video urbs\n"); -} -return 0; + return 0; } /*****************************************************************************/ -int -kill_video_urbs(struct easycap *peasycap) +int kill_video_urbs(struct easycap *peasycap) { -int m; -struct list_head *plist_head; -struct data_urb *pdata_urb; + int m; + struct list_head *plist_head; + struct data_urb *pdata_urb; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if (peasycap->video_isoc_streaming) { - if ((struct list_head *)NULL != peasycap->purb_video_head) { - peasycap->video_isoc_streaming = 0; - JOM(4, "killing video urbs\n"); - m = 0; - list_for_each(plist_head, (peasycap->purb_video_head)) { - pdata_urb = list_entry(plist_head, struct data_urb, \ - list_head); - if (NULL != pdata_urb) { - if (NULL != pdata_urb->purb) { - usb_kill_urb(pdata_urb->purb); - m++; - } - } - } - JOM(4, "%i video urbs killed\n", m); - } else { + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (!peasycap->video_isoc_streaming) { + JOM(8, "%i=video_isoc_streaming, no video urbs killed\n", + peasycap->video_isoc_streaming); + return 0; + } + if (!peasycap->purb_video_head) { SAM("ERROR: peasycap->purb_video_head is NULL\n"); return -EFAULT; } -} else { - JOM(8, "%i=video_isoc_streaming, no video urbs killed\n", \ - peasycap->video_isoc_streaming); -} -return 0; + + peasycap->video_isoc_streaming = 0; + JOM(4, "killing video urbs\n"); + m = 0; + list_for_each(plist_head, (peasycap->purb_video_head)) { + pdata_urb = list_entry(plist_head, struct data_urb, list_head); + if (pdata_urb && pdata_urb->purb) { + usb_kill_urb(pdata_urb->purb); + m++; + } + } + JOM(4, "%i video urbs killed\n", m); + + return 0; } /****************************************************************************/ -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if defined(EASYCAP_IS_VIDEODEV_CLIENT) -int -easycap_release_noinode(struct file *file) -{ -return easycap_release((struct inode *)NULL, file); -} -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*--------------------------------------------------------------------------*/ -int -easycap_release(struct inode *inode, struct file *file) +static int easycap_open_noinode(struct file *file) { -#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) -struct easycap *peasycap; - -JOT(4, "\n"); - -peasycap = file->private_data; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL.\n"); - SAY("ending unsuccessfully\n"); - return -EFAULT; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); - return -EFAULT; -} -if (0 != kill_video_urbs(peasycap)) { - SAM("ERROR: kill_video_urbs() failed\n"); - return -EFAULT; + return easycap_open(NULL, file); } -JOM(4, "ending successfully\n"); -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#else -# -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ -return 0; -} -/****************************************************************************/ -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if defined(EASYCAP_IS_VIDEODEV_CLIENT) -int -videodev_release(struct video_device *pvideo_device) +static int videodev_release(struct video_device *pvideo_device) { -struct easycap *peasycap; + struct easycap *peasycap; -JOT(4, "\n"); - -peasycap = video_get_drvdata(pvideo_device); -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - SAY("ending unsuccessfully\n"); - return -EFAULT; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); - return -EFAULT; -} -if (0 != kill_video_urbs(peasycap)) { - SAM("ERROR: kill_video_urbs() failed\n"); - return -EFAULT; -} -JOM(4, "ending successfully\n"); -return 0; + peasycap = video_get_drvdata(pvideo_device); + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + SAY("ending unsuccessfully\n"); + return -EFAULT; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: %p\n", peasycap); + return -EFAULT; + } + if (0 != kill_video_urbs(peasycap)) { + SAM("ERROR: kill_video_urbs() failed\n"); + return -EFAULT; + } + JOM(4, "ending successfully\n"); + return 0; } -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*****************************************************************************/ /*--------------------------------------------------------------------------*/ @@ -896,318 +728,331 @@ return 0; * peasycap->pusb_device IS NO LONGER VALID. */ /*---------------------------------------------------------------------------*/ -void -easycap_delete(struct kref *pkref) +static void easycap_delete(struct kref *pkref) { -int k, m, gone, kd; -int allocation_video_urb, allocation_video_page, allocation_video_struct; -int allocation_audio_urb, allocation_audio_page, allocation_audio_struct; -int registered_video, registered_audio; -struct easycap *peasycap; -struct data_urb *pdata_urb; -struct list_head *plist_head, *plist_next; - -JOT(4, "\n"); - -peasycap = container_of(pkref, struct easycap, kref); -if (NULL == peasycap) { - SAM("ERROR: peasycap is NULL: cannot perform deletions\n"); - return; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); - return; -} -kd = isdongle(peasycap); + struct easycap *peasycap; + struct data_urb *pdata_urb; + struct list_head *plist_head, *plist_next; + int k, m, gone, kd; + int allocation_video_urb; + int allocation_video_page; + int allocation_video_struct; + int allocation_audio_urb; + int allocation_audio_page; + int allocation_audio_struct; + int registered_video, registered_audio; + + peasycap = container_of(pkref, struct easycap, kref); + if (!peasycap) { + SAM("ERROR: peasycap is NULL: cannot perform deletions\n"); + return; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: %p\n", peasycap); + return; + } + kd = isdongle(peasycap); /*---------------------------------------------------------------------------*/ /* * FREE VIDEO. */ /*---------------------------------------------------------------------------*/ -if ((struct list_head *)NULL != peasycap->purb_video_head) { - JOM(4, "freeing video urbs\n"); - m = 0; - list_for_each(plist_head, (peasycap->purb_video_head)) { - pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if (NULL == pdata_urb) - JOM(4, "ERROR: pdata_urb is NULL\n"); - else { - if ((struct urb *)NULL != pdata_urb->purb) { - usb_free_urb(pdata_urb->purb); - pdata_urb->purb = (struct urb *)NULL; - peasycap->allocation_video_urb -= 1; + if (peasycap->purb_video_head) { + JOM(4, "freeing video urbs\n"); + m = 0; + list_for_each(plist_head, (peasycap->purb_video_head)) { + pdata_urb = list_entry(plist_head, + struct data_urb, list_head); + if (!pdata_urb) { + JOM(4, "ERROR: pdata_urb is NULL\n"); + } else { + if (pdata_urb->purb) { + usb_free_urb(pdata_urb->purb); + pdata_urb->purb = NULL; + peasycap->allocation_video_urb -= 1; + m++; + } + } + } + + JOM(4, "%i video urbs freed\n", m); +/*---------------------------------------------------------------------------*/ + JOM(4, "freeing video data_urb structures.\n"); + m = 0; + list_for_each_safe(plist_head, plist_next, + peasycap->purb_video_head) { + pdata_urb = list_entry(plist_head, + struct data_urb, list_head); + if (pdata_urb) { + peasycap->allocation_video_struct -= + sizeof(struct data_urb); + kfree(pdata_urb); + pdata_urb = NULL; m++; } } + JOM(4, "%i video data_urb structures freed\n", m); + JOM(4, "setting peasycap->purb_video_head=NULL\n"); + peasycap->purb_video_head = NULL; } - - JOM(4, "%i video urbs freed\n", m); /*---------------------------------------------------------------------------*/ - JOM(4, "freeing video data_urb structures.\n"); + JOM(4, "freeing video isoc buffers.\n"); m = 0; - list_for_each_safe(plist_head, plist_next, peasycap->purb_video_head) { - pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if ((struct data_urb *)NULL != pdata_urb) { - kfree(pdata_urb); pdata_urb = (struct data_urb *)NULL; - peasycap->allocation_video_struct -= \ - sizeof(struct data_urb); + for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { + if (peasycap->video_isoc_buffer[k].pgo) { + free_pages((unsigned long) + peasycap->video_isoc_buffer[k].pgo, + VIDEO_ISOC_ORDER); + peasycap->video_isoc_buffer[k].pgo = NULL; + peasycap->allocation_video_page -= + BIT(VIDEO_ISOC_ORDER); m++; } } - JOM(4, "%i video data_urb structures freed\n", m); - JOM(4, "setting peasycap->purb_video_head=NULL\n"); - peasycap->purb_video_head = (struct list_head *)NULL; -} + JOM(4, "isoc video buffers freed: %i pages\n", + m * (0x01 << VIDEO_ISOC_ORDER)); /*---------------------------------------------------------------------------*/ -JOM(4, "freeing video isoc buffers.\n"); -m = 0; -for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { - if ((void *)NULL != peasycap->video_isoc_buffer[k].pgo) { - free_pages((unsigned long)\ - (peasycap->video_isoc_buffer[k].pgo), \ - VIDEO_ISOC_ORDER); - peasycap->video_isoc_buffer[k].pgo = (void *)NULL; - peasycap->allocation_video_page -= \ - ((unsigned int)(0x01 << VIDEO_ISOC_ORDER)); - m++; - } -} -JOM(4, "isoc video buffers freed: %i pages\n", m * (0x01 << VIDEO_ISOC_ORDER)); -/*---------------------------------------------------------------------------*/ -JOM(4, "freeing video field buffers.\n"); -gone = 0; -for (k = 0; k < FIELD_BUFFER_MANY; k++) { - for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) { - if ((void *)NULL != peasycap->field_buffer[k][m].pgo) { - free_page((unsigned long)\ - (peasycap->field_buffer[k][m].pgo)); - peasycap->field_buffer[k][m].pgo = (void *)NULL; - peasycap->allocation_video_page -= 1; - gone++; + JOM(4, "freeing video field buffers.\n"); + gone = 0; + for (k = 0; k < FIELD_BUFFER_MANY; k++) { + for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) { + if (peasycap->field_buffer[k][m].pgo) { + free_page((unsigned long) + peasycap->field_buffer[k][m].pgo); + peasycap->field_buffer[k][m].pgo = NULL; + peasycap->allocation_video_page -= 1; + gone++; + } } } -} -JOM(4, "video field buffers freed: %i pages\n", gone); -/*---------------------------------------------------------------------------*/ -JOM(4, "freeing video frame buffers.\n"); -gone = 0; -for (k = 0; k < FRAME_BUFFER_MANY; k++) { - for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) { - if ((void *)NULL != peasycap->frame_buffer[k][m].pgo) { - free_page((unsigned long)\ - (peasycap->frame_buffer[k][m].pgo)); - peasycap->frame_buffer[k][m].pgo = (void *)NULL; - peasycap->allocation_video_page -= 1; - gone++; + JOM(4, "video field buffers freed: %i pages\n", gone); +/*---------------------------------------------------------------------------*/ + JOM(4, "freeing video frame buffers.\n"); + gone = 0; + for (k = 0; k < FRAME_BUFFER_MANY; k++) { + for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) { + if (peasycap->frame_buffer[k][m].pgo) { + free_page((unsigned long) + peasycap->frame_buffer[k][m].pgo); + peasycap->frame_buffer[k][m].pgo = NULL; + peasycap->allocation_video_page -= 1; + gone++; + } } } -} -JOM(4, "video frame buffers freed: %i pages\n", gone); + JOM(4, "video frame buffers freed: %i pages\n", gone); /*---------------------------------------------------------------------------*/ /* * FREE AUDIO. */ /*---------------------------------------------------------------------------*/ -if ((struct list_head *)NULL != peasycap->purb_audio_head) { - JOM(4, "freeing audio urbs\n"); - m = 0; - list_for_each(plist_head, (peasycap->purb_audio_head)) { - pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if (NULL == pdata_urb) - JOM(4, "ERROR: pdata_urb is NULL\n"); - else { - if ((struct urb *)NULL != pdata_urb->purb) { - usb_free_urb(pdata_urb->purb); - pdata_urb->purb = (struct urb *)NULL; - peasycap->allocation_audio_urb -= 1; + if (peasycap->purb_audio_head) { + JOM(4, "freeing audio urbs\n"); + m = 0; + list_for_each(plist_head, (peasycap->purb_audio_head)) { + pdata_urb = list_entry(plist_head, + struct data_urb, list_head); + if (!pdata_urb) + JOM(4, "ERROR: pdata_urb is NULL\n"); + else { + if (pdata_urb->purb) { + usb_free_urb(pdata_urb->purb); + pdata_urb->purb = NULL; + peasycap->allocation_audio_urb -= 1; + m++; + } + } + } + JOM(4, "%i audio urbs freed\n", m); +/*---------------------------------------------------------------------------*/ + JOM(4, "freeing audio data_urb structures.\n"); + m = 0; + list_for_each_safe(plist_head, plist_next, + peasycap->purb_audio_head) { + pdata_urb = list_entry(plist_head, + struct data_urb, list_head); + if (pdata_urb) { + peasycap->allocation_audio_struct -= + sizeof(struct data_urb); + kfree(pdata_urb); + pdata_urb = NULL; m++; } } + JOM(4, "%i audio data_urb structures freed\n", m); + JOM(4, "setting peasycap->purb_audio_head=NULL\n"); + peasycap->purb_audio_head = NULL; } - JOM(4, "%i audio urbs freed\n", m); /*---------------------------------------------------------------------------*/ - JOM(4, "freeing audio data_urb structures.\n"); + JOM(4, "freeing audio isoc buffers.\n"); m = 0; - list_for_each_safe(plist_head, plist_next, peasycap->purb_audio_head) { - pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if ((struct data_urb *)NULL != pdata_urb) { - kfree(pdata_urb); pdata_urb = (struct data_urb *)NULL; - peasycap->allocation_audio_struct -= \ - sizeof(struct data_urb); + for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { + if (peasycap->audio_isoc_buffer[k].pgo) { + free_pages((unsigned long) + (peasycap->audio_isoc_buffer[k].pgo), + AUDIO_ISOC_ORDER); + peasycap->audio_isoc_buffer[k].pgo = NULL; + peasycap->allocation_audio_page -= + BIT(AUDIO_ISOC_ORDER); m++; } } -JOM(4, "%i audio data_urb structures freed\n", m); -JOM(4, "setting peasycap->purb_audio_head=NULL\n"); -peasycap->purb_audio_head = (struct list_head *)NULL; -} + JOM(4, "easyoss_delete(): isoc audio buffers freed: %i pages\n", + m * (0x01 << AUDIO_ISOC_ORDER)); /*---------------------------------------------------------------------------*/ -JOM(4, "freeing audio isoc buffers.\n"); -m = 0; -for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { - if ((void *)NULL != peasycap->audio_isoc_buffer[k].pgo) { - free_pages((unsigned long)\ - (peasycap->audio_isoc_buffer[k].pgo), \ - AUDIO_ISOC_ORDER); - peasycap->audio_isoc_buffer[k].pgo = (void *)NULL; - peasycap->allocation_audio_page -= \ - ((unsigned int)(0x01 << AUDIO_ISOC_ORDER)); - m++; +#ifdef CONFIG_EASYCAP_OSS + JOM(4, "freeing audio buffers.\n"); + gone = 0; + for (k = 0; k < peasycap->audio_buffer_page_many; k++) { + if (peasycap->audio_buffer[k].pgo) { + free_page((unsigned long)peasycap->audio_buffer[k].pgo); + peasycap->audio_buffer[k].pgo = NULL; + peasycap->allocation_audio_page -= 1; + gone++; + } } -} -JOM(4, "easysnd_delete(): isoc audio buffers freed: %i pages\n", \ - m * (0x01 << AUDIO_ISOC_ORDER)); + JOM(4, "easyoss_delete(): audio buffers freed: %i pages\n", gone); +#endif /* CONFIG_EASYCAP_OSS */ /*---------------------------------------------------------------------------*/ -JOM(4, "freeing audio buffers.\n"); -gone = 0; -for (k = 0; k < peasycap->audio_buffer_page_many; k++) { - if ((void *)NULL != peasycap->audio_buffer[k].pgo) { - free_page((unsigned long)(peasycap->audio_buffer[k].pgo)); - peasycap->audio_buffer[k].pgo = (void *)NULL; - peasycap->allocation_audio_page -= 1; - gone++; + JOM(4, "freeing easycap structure.\n"); + allocation_video_urb = peasycap->allocation_video_urb; + allocation_video_page = peasycap->allocation_video_page; + allocation_video_struct = peasycap->allocation_video_struct; + registered_video = peasycap->registered_video; + allocation_audio_urb = peasycap->allocation_audio_urb; + allocation_audio_page = peasycap->allocation_audio_page; + allocation_audio_struct = peasycap->allocation_audio_struct; + registered_audio = peasycap->registered_audio; + + kfree(peasycap); + + if (0 <= kd && DONGLE_MANY > kd) { + if (mutex_lock_interruptible(&mutex_dongle)) { + SAY("ERROR: cannot down mutex_dongle\n"); + } else { + JOM(4, "locked mutex_dongle\n"); + easycapdc60_dongle[kd].peasycap = NULL; + mutex_unlock(&mutex_dongle); + JOM(4, "unlocked mutex_dongle\n"); + JOT(4, " null-->dongle[%i].peasycap\n", kd); + allocation_video_struct -= sizeof(struct easycap); + } + } else { + SAY("ERROR: cannot purge dongle[].peasycap"); } -} -JOM(4, "easysnd_delete(): audio buffers freed: %i pages\n", gone); -/*---------------------------------------------------------------------------*/ -JOM(4, "freeing easycap structure.\n"); -allocation_video_urb = peasycap->allocation_video_urb; -allocation_video_page = peasycap->allocation_video_page; -allocation_video_struct = peasycap->allocation_video_struct; -registered_video = peasycap->registered_video; -allocation_audio_urb = peasycap->allocation_audio_urb; -allocation_audio_page = peasycap->allocation_audio_page; -allocation_audio_struct = peasycap->allocation_audio_struct; -registered_audio = peasycap->registered_audio; - -kfree(peasycap); -if (0 <= kd && DONGLE_MANY > kd) { - easycap_dongle[kd].peasycap = (struct easycap *)NULL; - JOT(4, " null-->easycap_dongle[%i].peasycap\n", kd); - allocation_video_struct -= sizeof(struct easycap); -} else { - SAY("ERROR: cannot purge easycap_dongle[].peasycap"); -} /*---------------------------------------------------------------------------*/ -SAY("%8i= video urbs after all deletions\n", allocation_video_urb); -SAY("%8i= video pages after all deletions\n", allocation_video_page); -SAY("%8i= video structs after all deletions\n", allocation_video_struct); -SAY("%8i= video devices after all deletions\n", registered_video); -SAY("%8i= audio urbs after all deletions\n", allocation_audio_urb); -SAY("%8i= audio pages after all deletions\n", allocation_audio_page); -SAY("%8i= audio structs after all deletions\n", allocation_audio_struct); -SAY("%8i= audio devices after all deletions\n", registered_audio); - -JOT(4, "ending.\n"); -return; + SAY("%8i=video urbs after all deletions\n", allocation_video_urb); + SAY("%8i=video pages after all deletions\n", allocation_video_page); + SAY("%8i=video structs after all deletions\n", allocation_video_struct); + SAY("%8i=video devices after all deletions\n", registered_video); + SAY("%8i=audio urbs after all deletions\n", allocation_audio_urb); + SAY("%8i=audio pages after all deletions\n", allocation_audio_page); + SAY("%8i=audio structs after all deletions\n", allocation_audio_struct); + SAY("%8i=audio devices after all deletions\n", registered_audio); + + JOT(4, "ending.\n"); + return; } /*****************************************************************************/ -unsigned int easycap_poll(struct file *file, poll_table *wait) +static unsigned int easycap_poll(struct file *file, poll_table *wait) { -struct easycap *peasycap; -int rc, kd; + struct easycap *peasycap; + int rc, kd; -JOT(8, "\n"); + JOT(8, "\n"); -if (NULL == ((poll_table *)wait)) - JOT(8, "WARNING: poll table pointer is NULL ... continuing\n"); -if ((struct file *)NULL == file) { - SAY("ERROR: file pointer is NULL\n"); - return -ERESTARTSYS; -} -peasycap = file->private_data; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); - return -EFAULT; -} -if (NULL == peasycap->pusb_device) { - SAY("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -/*---------------------------------------------------------------------------*/ -kd = isdongle(peasycap); -if (0 <= kd && DONGLE_MANY > kd) { - if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_video)) { - SAY("ERROR: cannot down easycap_dongle[%i].mutex_video\n", kd); - return -ERESTARTSYS; - } - JOM(4, "locked easycap_dongle[%i].mutex_video\n", kd); - /*-------------------------------------------------------------------*/ - /* - * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER - * peasycap, IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. - * IF NECESSARY, BAIL OUT. - */ - /*-------------------------------------------------------------------*/ - if (kd != isdongle(peasycap)) - return -ERESTARTSYS; - if (NULL == file) { - SAY("ERROR: file is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); + if (NULL == ((poll_table *)wait)) + JOT(8, "WARNING: poll table pointer is NULL ... continuing\n"); + if (!file) { + SAY("ERROR: file pointer is NULL\n"); return -ERESTARTSYS; } peasycap = file->private_data; - if (NULL == peasycap) { + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -ERESTARTSYS; + return -EFAULT; } if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", \ - (unsigned long int) peasycap); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -ERESTARTSYS; + SAY("ERROR: bad peasycap: %p\n", peasycap); + return -EFAULT; } - if (NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_video); - return -ERESTARTSYS; + if (!peasycap->pusb_device) { + SAY("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; } -} else - /*-------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + kd = isdongle(peasycap); + if (0 <= kd && DONGLE_MANY > kd) { + if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) { + SAY("ERROR: cannot down dongle[%i].mutex_video\n", kd); + return -ERESTARTSYS; + } + JOM(4, "locked dongle[%i].mutex_video\n", kd); + /* + * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER + * peasycap, IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. + * IF NECESSARY, BAIL OUT. + */ + if (kd != isdongle(peasycap)) + return -ERESTARTSYS; + if (!file) { + SAY("ERROR: file is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -ERESTARTSYS; + } + peasycap = file->private_data; + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -ERESTARTSYS; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: %p\n", peasycap); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -ERESTARTSYS; + } + if (!peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return -ERESTARTSYS; + } + } else /* * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap * BEFORE THE ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL * HAVE FAILED. BAIL OUT. */ - /*-------------------------------------------------------------------*/ - return -ERESTARTSYS; -/*---------------------------------------------------------------------------*/ -rc = easycap_dqbuf(peasycap, 0); -peasycap->polled = 1; -mutex_unlock(&easycap_dongle[kd].mutex_video); -if (0 == rc) - return POLLIN | POLLRDNORM; -else - return POLLERR; -} + return -ERESTARTSYS; +/*---------------------------------------------------------------------------*/ + rc = easycap_dqbuf(peasycap, 0); + peasycap->polled = 1; + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + if (0 == rc) + return POLLIN | POLLRDNORM; + else + return POLLERR; + } /*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* * IF mode IS NONZERO THIS ROUTINE RETURNS -EAGAIN RATHER THAN BLOCKING. */ /*---------------------------------------------------------------------------*/ -int -easycap_dqbuf(struct easycap *peasycap, int mode) +int easycap_dqbuf(struct easycap *peasycap, int mode) { -int input, ifield, miss, rc; + int input, ifield, miss, rc; -JOT(8, "\n"); -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if (NULL == peasycap->pusb_device) { - SAY("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -ifield = 0; -JOM(8, "%i=ifield\n", ifield); + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (!peasycap->pusb_device) { + SAY("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; + } + ifield = 0; + JOM(8, "%i=ifield\n", ifield); /*---------------------------------------------------------------------------*/ /* * CHECK FOR LOST INPUT SIGNAL. @@ -1223,187 +1068,179 @@ JOM(8, "%i=ifield\n", ifield); * INPUT 0 UNPLUGGED, INPUT 4 UNPLUGGED => SCREEN 0 BARS, SCREEN 4 BARS */ /*---------------------------------------------------------------------------*/ -input = peasycap->input; -if (0 <= input && INPUT_MANY > input) { - rc = read_saa(peasycap->pusb_device, 0x1F); - if (0 <= rc) { - if (rc & 0x40) - peasycap->lost[input] += 1; - else - peasycap->lost[input] -= 2; + input = peasycap->input; + if (0 <= input && INPUT_MANY > input) { + rc = read_saa(peasycap->pusb_device, 0x1F); + if (0 <= rc) { + if (rc & 0x40) + peasycap->lost[input] += 1; + else + peasycap->lost[input] -= 2; - if (0 > peasycap->lost[input]) - peasycap->lost[input] = 0; - else if ((2 * VIDEO_LOST_TOLERATE) < peasycap->lost[input]) - peasycap->lost[input] = (2 * VIDEO_LOST_TOLERATE); + if (0 > peasycap->lost[input]) + peasycap->lost[input] = 0; + else if ((2 * VIDEO_LOST_TOLERATE) < peasycap->lost[input]) + peasycap->lost[input] = (2 * VIDEO_LOST_TOLERATE); + } } -} /*---------------------------------------------------------------------------*/ /* * WAIT FOR FIELD ifield (0 => TOP, 1 => BOTTOM) */ /*---------------------------------------------------------------------------*/ -miss = 0; -while ((peasycap->field_read == peasycap->field_fill) || \ - (0 != (0xFF00 & peasycap->field_buffer\ - [peasycap->field_read][0].kount)) || \ - (ifield != (0x00FF & peasycap->field_buffer\ + miss = 0; + while ((peasycap->field_read == peasycap->field_fill) || + (0 != (0xFF00 & peasycap->field_buffer + [peasycap->field_read][0].kount)) || + (ifield != (0x00FF & peasycap->field_buffer [peasycap->field_read][0].kount))) { - if (mode) - return -EAGAIN; + if (mode) + return -EAGAIN; - JOM(8, "first wait on wq_video, " \ - "%i=field_read %i=field_fill\n", \ + JOM(8, "first wait on wq_video, %i=field_read %i=field_fill\n", peasycap->field_read, peasycap->field_fill); - if (0 != (wait_event_interruptible(peasycap->wq_video, \ - (peasycap->video_idle || peasycap->video_eof || \ - ((peasycap->field_read != peasycap->field_fill) && \ - (0 == (0xFF00 & peasycap->field_buffer\ - [peasycap->field_read][0].kount)) && \ - (ifield == (0x00FF & peasycap->field_buffer\ - [peasycap->field_read][0].kount))))))) { - SAM("aborted by signal\n"); - return -EIO; + if (0 != (wait_event_interruptible(peasycap->wq_video, + (peasycap->video_idle || peasycap->video_eof || + ((peasycap->field_read != peasycap->field_fill) && + (0 == (0xFF00 & peasycap->field_buffer[peasycap->field_read][0].kount)) && + (ifield == (0x00FF & peasycap->field_buffer[peasycap->field_read][0].kount))))))) { + SAM("aborted by signal\n"); + return -EIO; } - if (peasycap->video_idle) { - JOM(8, "%i=peasycap->video_idle ... returning -EAGAIN\n", \ + if (peasycap->video_idle) { + JOM(8, "%i=peasycap->video_idle returning -EAGAIN\n", peasycap->video_idle); - return -EAGAIN; - } - if (peasycap->video_eof) { - JOM(8, "%i=peasycap->video_eof\n", peasycap->video_eof); - #if defined(PERSEVERE) - if (1 == peasycap->status) { - JOM(8, "persevering ...\n"); - peasycap->video_eof = 0; - peasycap->audio_eof = 0; - if (0 != reset(peasycap)) { - JOM(8, " ... failed ... returning -EIO\n"); - peasycap->video_eof = 1; - peasycap->audio_eof = 1; - kill_video_urbs(peasycap); - return -EIO; - } - peasycap->status = 0; - JOM(8, " ... OK ... returning -EAGAIN\n"); return -EAGAIN; } - #endif /*PERSEVERE*/ - peasycap->video_eof = 1; - peasycap->audio_eof = 1; - kill_video_urbs(peasycap); - JOM(8, "returning -EIO\n"); - return -EIO; + if (peasycap->video_eof) { + JOM(8, "%i=peasycap->video_eof\n", peasycap->video_eof); + #if defined(PERSEVERE) + if (1 == peasycap->status) { + JOM(8, "persevering ...\n"); + peasycap->video_eof = 0; + peasycap->audio_eof = 0; + if (0 != reset(peasycap)) { + JOM(8, " ... failed returning -EIO\n"); + peasycap->video_eof = 1; + peasycap->audio_eof = 1; + kill_video_urbs(peasycap); + return -EIO; + } + peasycap->status = 0; + JOM(8, " ... OK returning -EAGAIN\n"); + return -EAGAIN; + } + #endif /*PERSEVERE*/ + peasycap->video_eof = 1; + peasycap->audio_eof = 1; + kill_video_urbs(peasycap); + JOM(8, "returning -EIO\n"); + return -EIO; + } + miss++; } -miss++; -} -JOM(8, "first awakening on wq_video after %i waits\n", miss); + JOM(8, "first awakening on wq_video after %i waits\n", miss); -rc = field2frame(peasycap); -if (0 != rc) - SAM("ERROR: field2frame() returned %i\n", rc); + rc = field2frame(peasycap); + if (rc) + SAM("ERROR: field2frame() rc = %i\n", rc); /*---------------------------------------------------------------------------*/ /* * WAIT FOR THE OTHER FIELD */ /*---------------------------------------------------------------------------*/ -if (ifield) - ifield = 0; -else - ifield = 1; -miss = 0; -while ((peasycap->field_read == peasycap->field_fill) || \ - (0 != (0xFF00 & peasycap->field_buffer\ - [peasycap->field_read][0].kount)) || \ - (ifield != (0x00FF & peasycap->field_buffer\ - [peasycap->field_read][0].kount))) { - if (mode) - return -EAGAIN; + if (ifield) + ifield = 0; + else + ifield = 1; + miss = 0; + while ((peasycap->field_read == peasycap->field_fill) || + (0 != (0xFF00 & peasycap->field_buffer[peasycap->field_read][0].kount)) || + (ifield != (0x00FF & peasycap->field_buffer[peasycap->field_read][0].kount))) { + if (mode) + return -EAGAIN; - JOM(8, "second wait on wq_video, " \ - "%i=field_read %i=field_fill\n", \ + JOM(8, "second wait on wq_video %i=field_read %i=field_fill\n", peasycap->field_read, peasycap->field_fill); - if (0 != (wait_event_interruptible(peasycap->wq_video, \ - (peasycap->video_idle || peasycap->video_eof || \ - ((peasycap->field_read != peasycap->field_fill) && \ - (0 == (0xFF00 & peasycap->field_buffer\ - [peasycap->field_read][0].kount)) && \ - (ifield == (0x00FF & peasycap->field_buffer\ - [peasycap->field_read][0].\ - kount))))))) { - SAM("aborted by signal\n"); - return -EIO; - } - if (peasycap->video_idle) { - JOM(8, "%i=peasycap->video_idle ... returning -EAGAIN\n", \ + if (0 != (wait_event_interruptible(peasycap->wq_video, + (peasycap->video_idle || peasycap->video_eof || + ((peasycap->field_read != peasycap->field_fill) && + (0 == (0xFF00 & peasycap->field_buffer[peasycap->field_read][0].kount)) && + (ifield == (0x00FF & peasycap->field_buffer[peasycap->field_read][0].kount))))))) { + SAM("aborted by signal\n"); + return -EIO; + } + if (peasycap->video_idle) { + JOM(8, "%i=peasycap->video_idle returning -EAGAIN\n", peasycap->video_idle); - return -EAGAIN; - } - if (peasycap->video_eof) { - JOM(8, "%i=peasycap->video_eof\n", peasycap->video_eof); - #if defined(PERSEVERE) - if (1 == peasycap->status) { - JOM(8, "persevering ...\n"); - peasycap->video_eof = 0; - peasycap->audio_eof = 0; - if (0 != reset(peasycap)) { - JOM(8, " ... failed ... returning -EIO\n"); - peasycap->video_eof = 1; - peasycap->audio_eof = 1; - kill_video_urbs(peasycap); - return -EIO; - } - peasycap->status = 0; - JOM(8, " ... OK ... returning -EAGAIN\n"); return -EAGAIN; } - #endif /*PERSEVERE*/ - peasycap->video_eof = 1; - peasycap->audio_eof = 1; - kill_video_urbs(peasycap); - JOM(8, "returning -EIO\n"); - return -EIO; + if (peasycap->video_eof) { + JOM(8, "%i=peasycap->video_eof\n", peasycap->video_eof); +#if defined(PERSEVERE) + if (1 == peasycap->status) { + JOM(8, "persevering ...\n"); + peasycap->video_eof = 0; + peasycap->audio_eof = 0; + if (0 != reset(peasycap)) { + JOM(8, " ... failed returning -EIO\n"); + peasycap->video_eof = 1; + peasycap->audio_eof = 1; + kill_video_urbs(peasycap); + return -EIO; + } + peasycap->status = 0; + JOM(8, " ... OK ... returning -EAGAIN\n"); + return -EAGAIN; + } +#endif /*PERSEVERE*/ + peasycap->video_eof = 1; + peasycap->audio_eof = 1; + kill_video_urbs(peasycap); + JOM(8, "returning -EIO\n"); + return -EIO; + } + miss++; } -miss++; -} -JOM(8, "second awakening on wq_video after %i waits\n", miss); + JOM(8, "second awakening on wq_video after %i waits\n", miss); -rc = field2frame(peasycap); -if (0 != rc) - SAM("ERROR: field2frame() returned %i\n", rc); + rc = field2frame(peasycap); + if (rc) + SAM("ERROR: field2frame() rc = %i\n", rc); /*---------------------------------------------------------------------------*/ /* * WASTE THIS FRAME */ /*---------------------------------------------------------------------------*/ -if (0 != peasycap->skip) { - peasycap->skipped++; - if (peasycap->skip != peasycap->skipped) - return peasycap->skip - peasycap->skipped; - peasycap->skipped = 0; -} + if (peasycap->skip) { + peasycap->skipped++; + if (peasycap->skip != peasycap->skipped) + return peasycap->skip - peasycap->skipped; + else + peasycap->skipped = 0; + } /*---------------------------------------------------------------------------*/ -peasycap->frame_read = peasycap->frame_fill; -peasycap->queued[peasycap->frame_read] = 0; -peasycap->done[peasycap->frame_read] = V4L2_BUF_FLAG_DONE; + peasycap->frame_read = peasycap->frame_fill; + peasycap->queued[peasycap->frame_read] = 0; + peasycap->done[peasycap->frame_read] = V4L2_BUF_FLAG_DONE; -(peasycap->frame_fill)++; -if (peasycap->frame_buffer_many <= peasycap->frame_fill) - peasycap->frame_fill = 0; + peasycap->frame_fill++; + if (peasycap->frame_buffer_many <= peasycap->frame_fill) + peasycap->frame_fill = 0; -if (0x01 & easycap_standard[peasycap->standard_offset].mask) { - peasycap->frame_buffer[peasycap->frame_read][0].kount = \ + if (0x01 & easycap_standard[peasycap->standard_offset].mask) + peasycap->frame_buffer[peasycap->frame_read][0].kount = V4L2_FIELD_TOP; -} else { - peasycap->frame_buffer[peasycap->frame_read][0].kount = \ + else + peasycap->frame_buffer[peasycap->frame_read][0].kount = V4L2_FIELD_BOTTOM; -} -JOM(8, "setting: %i=peasycap->frame_read\n", peasycap->frame_read); -JOM(8, "bumped to: %i=peasycap->frame_fill\n", peasycap->frame_fill); -return 0; + JOM(8, "setting: %i=peasycap->frame_read\n", peasycap->frame_read); + JOM(8, "bumped to: %i=peasycap->frame_fill\n", peasycap->frame_fill); + + return 0; } /*****************************************************************************/ /*---------------------------------------------------------------------------*/ @@ -1421,222 +1258,204 @@ return 0; int field2frame(struct easycap *peasycap) { -struct timeval timeval; -long long int above, below; -__u32 remainder; -struct signed_div_result sdr; - -void *pex, *pad; -int kex, kad, mex, mad, rex, rad, rad2; -int c2, c3, w2, w3, cz, wz; -int rc, bytesperpixel, multiplier, much, more, over, rump, caches, input; -__u8 mask, margin; -bool odd, isuy, decimatepixel, offerfields, badinput; - -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} + struct timeval timeval; + long long int above, below; + u32 remainder; + struct signed_div_result sdr; + + void *pex, *pad; + int kex, kad, mex, mad, rex, rad, rad2; + int c2, c3, w2, w3, cz, wz; + int rc, bytesperpixel, multiplier; + int much, more, over, rump, caches, input; + u8 mask, margin; + bool odd, isuy, decimatepixel, offerfields, badinput; + + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } -badinput = false; -input = 0x07 & peasycap->field_buffer[peasycap->field_read][0].input; + badinput = false; + input = 0x07 & peasycap->field_buffer[peasycap->field_read][0].input; -JOM(8, "===== parity %i, input 0x%02X, field buffer %i --> " \ - "frame buffer %i\n", \ - peasycap->field_buffer[peasycap->field_read][0].kount,\ - peasycap->field_buffer[peasycap->field_read][0].input,\ + JOM(8, "===== parity %i, input 0x%02X, field buffer %i --> " + "frame buffer %i\n", + peasycap->field_buffer[peasycap->field_read][0].kount, + peasycap->field_buffer[peasycap->field_read][0].input, peasycap->field_read, peasycap->frame_fill); -JOM(8, "===== %i=bytesperpixel\n", peasycap->bytesperpixel); -if (true == peasycap->offerfields) - JOM(8, "===== offerfields\n"); + JOM(8, "===== %i=bytesperpixel\n", peasycap->bytesperpixel); + if (peasycap->offerfields) + JOM(8, "===== offerfields\n"); /*---------------------------------------------------------------------------*/ /* * REJECT OR CLEAN BAD FIELDS */ /*---------------------------------------------------------------------------*/ -if (peasycap->field_read == peasycap->field_fill) { - SAM("ERROR: on entry, still filling field buffer %i\n", \ - peasycap->field_read); - return 0; -} -#if defined(EASYCAP_TESTCARD) -easycap_testcard(peasycap, peasycap->field_read); + if (peasycap->field_read == peasycap->field_fill) { + SAM("ERROR: on entry, still filling field buffer %i\n", + peasycap->field_read); + return 0; + } +#ifdef EASYCAP_TESTCARD + easycap_testcard(peasycap, peasycap->field_read); #else -if (0 <= input && INPUT_MANY > input) { - if (easycap_bars && VIDEO_LOST_TOLERATE <= peasycap->lost[input]) - easycap_testcard(peasycap, peasycap->field_read); -} + if (0 <= input && INPUT_MANY > input) { + if (easycap_bars && VIDEO_LOST_TOLERATE <= peasycap->lost[input]) + easycap_testcard(peasycap, peasycap->field_read); + } #endif /*EASYCAP_TESTCARD*/ /*---------------------------------------------------------------------------*/ -offerfields = peasycap->offerfields; -bytesperpixel = peasycap->bytesperpixel; -decimatepixel = peasycap->decimatepixel; - -if ((2 != bytesperpixel) && \ - (3 != bytesperpixel) && \ - (4 != bytesperpixel)) { - SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel); - return -EFAULT; -} -if (true == decimatepixel) - multiplier = 2; -else - multiplier = 1; - -w2 = 2 * multiplier * (peasycap->width); -w3 = bytesperpixel * \ - multiplier * \ - (peasycap->width); -wz = multiplier * \ - (peasycap->height) * \ - multiplier * \ - (peasycap->width); - -kex = peasycap->field_read; mex = 0; -kad = peasycap->frame_fill; mad = 0; - -pex = peasycap->field_buffer[kex][0].pgo; rex = PAGE_SIZE; -pad = peasycap->frame_buffer[kad][0].pgo; rad = PAGE_SIZE; -if (peasycap->field_buffer[kex][0].kount) - odd = true; -else - odd = false; - -if ((true == odd) && (false == decimatepixel)) { - JOM(8, " initial skipping %4i bytes p.%4i\n", \ - w3/multiplier, mad); - pad += (w3 / multiplier); rad -= (w3 / multiplier); -} -isuy = true; -mask = 0; rump = 0; caches = 0; + offerfields = peasycap->offerfields; + bytesperpixel = peasycap->bytesperpixel; + decimatepixel = peasycap->decimatepixel; -cz = 0; -while (cz < wz) { - /*-------------------------------------------------------------------*/ - /* - ** PROCESS ONE LINE OF FRAME AT FULL RESOLUTION: - ** READ w2 BYTES FROM FIELD BUFFER, - ** WRITE w3 BYTES TO FRAME BUFFER - **/ - /*-------------------------------------------------------------------*/ - if (false == decimatepixel) { - over = w2; - do { - much = over; more = 0; margin = 0; mask = 0x00; - if (rex < much) - much = rex; - rump = 0; - - if (much % 2) { - SAM("MISTAKE: much is odd\n"); - return -EFAULT; - } + if ((2 != bytesperpixel) && + (3 != bytesperpixel) && + (4 != bytesperpixel)) { + SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel); + return -EFAULT; + } + if (decimatepixel) + multiplier = 2; + else + multiplier = 1; + + w2 = 2 * multiplier * (peasycap->width); + w3 = bytesperpixel * multiplier * (peasycap->width); + wz = multiplier * (peasycap->height) * + multiplier * (peasycap->width); + + kex = peasycap->field_read; mex = 0; + kad = peasycap->frame_fill; mad = 0; + + pex = peasycap->field_buffer[kex][0].pgo; rex = PAGE_SIZE; + pad = peasycap->frame_buffer[kad][0].pgo; rad = PAGE_SIZE; + odd = !!(peasycap->field_buffer[kex][0].kount); + + if (odd && (!decimatepixel)) { + JOM(8, "initial skipping %4i bytes p.%4i\n", + w3/multiplier, mad); + pad += (w3 / multiplier); rad -= (w3 / multiplier); + } + isuy = true; + mask = 0; rump = 0; caches = 0; + + cz = 0; + while (cz < wz) { + /* + * PROCESS ONE LINE OF FRAME AT FULL RESOLUTION: + * READ w2 BYTES FROM FIELD BUFFER, + * WRITE w3 BYTES TO FRAME BUFFER + */ + if (!decimatepixel) { + over = w2; + do { + much = over; more = 0; + margin = 0; mask = 0x00; + if (rex < much) + much = rex; + rump = 0; + + if (much % 2) { + SAM("MISTAKE: much is odd\n"); + return -EFAULT; + } - more = (bytesperpixel * \ - much) / 2; + more = (bytesperpixel * + much) / 2; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - if (1 < bytesperpixel) { - if (rad * 2 < much * bytesperpixel) { - /* - ** INJUDICIOUS ALTERATION OF THIS - ** STATEMENT BLOCK WILL CAUSE - ** BREAKAGE. BEWARE. - **/ - rad2 = rad + bytesperpixel - 1; - much = ((((2 * \ - rad2)/bytesperpixel)/2) * 2); - rump = ((bytesperpixel * \ - much) / 2) - rad; - more = rad; + if (1 < bytesperpixel) { + if (rad * 2 < much * bytesperpixel) { + /* + * INJUDICIOUS ALTERATION OF + * THIS STATEMENT BLOCK WILL + * CAUSE BREAKAGE. BEWARE. + */ + rad2 = rad + bytesperpixel - 1; + much = ((((2 * rad2)/bytesperpixel)/2) * 2); + rump = ((bytesperpixel * much) / 2) - rad; + more = rad; } - mask = (__u8)rump; - margin = 0; - if (much == rex) { - mask |= 0x04; - if ((mex + 1) < FIELD_BUFFER_SIZE/ \ - PAGE_SIZE) { - margin = *((__u8 *)(peasycap->\ - field_buffer\ - [kex][mex + 1].pgo)); - } else - mask |= 0x08; + mask = (u8)rump; + margin = 0; + if (much == rex) { + mask |= 0x04; + if ((mex + 1) < FIELD_BUFFER_SIZE / PAGE_SIZE) + margin = *((u8 *)(peasycap->field_buffer[kex][mex + 1].pgo)); + else + mask |= 0x08; + } + } else { + SAM("MISTAKE: %i=bytesperpixel\n", + bytesperpixel); + return -EFAULT; } -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - } else { - SAM("MISTAKE: %i=bytesperpixel\n", \ - bytesperpixel); - return -EFAULT; - } -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - if (rump) - caches++; - if (true == badinput) { - JOM(8, "ERROR: 0x%02X=->field_buffer" \ - "[%i][%i].input, " \ - "0x%02X=(0x08|->input)\n", \ - peasycap->field_buffer\ - [kex][mex].input, kex, mex, \ - (0x08|peasycap->input)); + if (rump) + caches++; + if (badinput) { + JOM(8, "ERROR: 0x%02X=->field_buffer" + "[%i][%i].input, " + "0x%02X=(0x08|->input)\n", + peasycap->field_buffer + [kex][mex].input, kex, mex, + (0x08|peasycap->input)); + } + rc = redaub(peasycap, pad, pex, much, more, + mask, margin, isuy); + if (0 > rc) { + SAM("ERROR: redaub() failed\n"); + return -EFAULT; } - rc = redaub(peasycap, pad, pex, much, more, \ - mask, margin, isuy); - if (0 > rc) { - SAM("ERROR: redaub() failed\n"); - return -EFAULT; - } - if (much % 4) { - if (isuy) - isuy = false; - else - isuy = true; - } - over -= much; cz += much; - pex += much; rex -= much; - if (!rex) { - mex++; - pex = peasycap->field_buffer[kex][mex].pgo; - rex = PAGE_SIZE; - if (peasycap->field_buffer[kex][mex].input != \ - (0x08|peasycap->input)) - badinput = true; - } - pad += more; - rad -= more; - if (!rad) { - mad++; - pad = peasycap->frame_buffer[kad][mad].pgo; - rad = PAGE_SIZE; - if (rump) { - pad += rump; - rad -= rump; + if (much % 4) + isuy = !isuy; + + over -= much; cz += much; + pex += much; rex -= much; + if (!rex) { + mex++; + pex = peasycap->field_buffer[kex][mex].pgo; + rex = PAGE_SIZE; + if (peasycap->field_buffer[kex][mex].input != (0x08|peasycap->input)) + badinput = true; } - } - } while (over); + pad += more; + rad -= more; + if (!rad) { + mad++; + pad = peasycap->frame_buffer[kad][mad].pgo; + rad = PAGE_SIZE; + if (rump) { + pad += rump; + rad -= rump; + } + } + } while (over); /*---------------------------------------------------------------------------*/ /* * SKIP w3 BYTES IN TARGET FRAME BUFFER, * UNLESS IT IS THE LAST LINE OF AN ODD FRAME */ /*---------------------------------------------------------------------------*/ - if ((false == odd) || (cz != wz)) { - over = w3; - do { - if (!rad) { - mad++; - pad = peasycap->frame_buffer\ - [kad][mad].pgo; - rad = PAGE_SIZE; - } - more = over; - if (rad < more) - more = rad; - over -= more; - pad += more; - rad -= more; - } while (over); - } + if (!odd || (cz != wz)) { + over = w3; + do { + if (!rad) { + mad++; + pad = peasycap->frame_buffer + [kad][mad].pgo; + rad = PAGE_SIZE; + } + more = over; + if (rad < more) + more = rad; + over -= more; + pad += more; + rad -= more; + } while (over); + } /*---------------------------------------------------------------------------*/ /* * PROCESS ONE LINE OF FRAME AT REDUCED RESOLUTION: @@ -1645,214 +1464,205 @@ while (cz < wz) { * WRITE w3 / 2 BYTES TO FRAME BUFFER */ /*---------------------------------------------------------------------------*/ - } else if (false == odd) { - over = w2; - do { - much = over; more = 0; margin = 0; mask = 0x00; - if (rex < much) - much = rex; - rump = 0; + } else if (!odd) { + over = w2; + do { + much = over; more = 0; margin = 0; mask = 0x00; + if (rex < much) + much = rex; + rump = 0; - if (much % 2) { - SAM("MISTAKE: much is odd\n"); - return -EFAULT; - } + if (much % 2) { + SAM("MISTAKE: much is odd\n"); + return -EFAULT; + } - more = (bytesperpixel * \ - much) / 4; + more = (bytesperpixel * much) / 4; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - if (1 < bytesperpixel) { - if (rad * 4 < much * bytesperpixel) { - /* - ** INJUDICIOUS ALTERATION OF THIS - ** STATEMENT BLOCK WILL CAUSE - ** BREAKAGE. BEWARE. - **/ - rad2 = rad + bytesperpixel - 1; - much = ((((2 * rad2)/bytesperpixel)/2)\ - * 4); - rump = ((bytesperpixel * \ - much) / 4) - rad; - more = rad; + if (1 < bytesperpixel) { + if (rad * 4 < much * bytesperpixel) { + /* + * INJUDICIOUS ALTERATION OF + * THIS STATEMENT BLOCK + * WILL CAUSE BREAKAGE. + * BEWARE. + */ + rad2 = rad + bytesperpixel - 1; + much = ((((2 * rad2) / bytesperpixel) / 2) * 4); + rump = ((bytesperpixel * much) / 4) - rad; + more = rad; } - mask = (__u8)rump; - margin = 0; - if (much == rex) { - mask |= 0x04; - if ((mex + 1) < FIELD_BUFFER_SIZE/ \ - PAGE_SIZE) { - margin = *((__u8 *)(peasycap->\ - field_buffer\ - [kex][mex + 1].pgo)); - } - else - mask |= 0x08; + mask = (u8)rump; + margin = 0; + if (much == rex) { + mask |= 0x04; + if ((mex + 1) < FIELD_BUFFER_SIZE / PAGE_SIZE) + margin = *((u8 *)(peasycap->field_buffer[kex][mex + 1].pgo)); + else + mask |= 0x08; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ } else { - SAM("MISTAKE: %i=bytesperpixel\n", \ + SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel); return -EFAULT; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - if (rump) - caches++; - - if (true == badinput) { - JOM(8, "ERROR: 0x%02X=->field_buffer" \ - "[%i][%i].input, " \ - "0x%02X=(0x08|->input)\n", \ - peasycap->field_buffer\ - [kex][mex].input, kex, mex, \ - (0x08|peasycap->input)); - } - rc = redaub(peasycap, pad, pex, much, more, \ + if (rump) + caches++; + + if (badinput) { + JOM(8, "ERROR: 0x%02X=->field_buffer" + "[%i][%i].input, " + "0x%02X=(0x08|->input)\n", + peasycap->field_buffer + [kex][mex].input, kex, mex, + (0x08|peasycap->input)); + } + rc = redaub(peasycap, pad, pex, much, more, mask, margin, isuy); - if (0 > rc) { - SAM("ERROR: redaub() failed\n"); - return -EFAULT; - } - over -= much; cz += much; - pex += much; rex -= much; - if (!rex) { - mex++; - pex = peasycap->field_buffer[kex][mex].pgo; - rex = PAGE_SIZE; - if (peasycap->field_buffer[kex][mex].input != \ - (0x08|peasycap->input)) - badinput = true; - } - pad += more; - rad -= more; - if (!rad) { - mad++; - pad = peasycap->frame_buffer[kad][mad].pgo; - rad = PAGE_SIZE; - if (rump) { - pad += rump; - rad -= rump; + if (0 > rc) { + SAM("ERROR: redaub() failed\n"); + return -EFAULT; } - } - } while (over); + over -= much; cz += much; + pex += much; rex -= much; + if (!rex) { + mex++; + pex = peasycap->field_buffer[kex][mex].pgo; + rex = PAGE_SIZE; + if (peasycap->field_buffer[kex][mex].input != + (0x08|peasycap->input)) + badinput = true; + } + pad += more; + rad -= more; + if (!rad) { + mad++; + pad = peasycap->frame_buffer[kad][mad].pgo; + rad = PAGE_SIZE; + if (rump) { + pad += rump; + rad -= rump; + } + } + } while (over); /*---------------------------------------------------------------------------*/ /* * OTHERWISE JUST * READ w2 BYTES FROM FIELD BUFFER AND DISCARD THEM */ /*---------------------------------------------------------------------------*/ - } else { - over = w2; - do { - if (!rex) { - mex++; - pex = peasycap->field_buffer[kex][mex].pgo; - rex = PAGE_SIZE; - if (peasycap->field_buffer[kex][mex].input != \ - (0x08|peasycap->input)) { - JOM(8, "ERROR: 0x%02X=->field_buffer"\ - "[%i][%i].input, " \ - "0x%02X=(0x08|->input)\n", \ - peasycap->field_buffer\ - [kex][mex].input, kex, mex, \ - (0x08|peasycap->input)); - badinput = true; + } else { + over = w2; + do { + if (!rex) { + mex++; + pex = peasycap->field_buffer[kex][mex].pgo; + rex = PAGE_SIZE; + if (peasycap->field_buffer[kex][mex].input != + (0x08|peasycap->input)) { + JOM(8, "ERROR: 0x%02X=->field_buffer" + "[%i][%i].input, " + "0x%02X=(0x08|->input)\n", + peasycap->field_buffer + [kex][mex].input, kex, mex, + (0x08|peasycap->input)); + badinput = true; + } } - } - much = over; - if (rex < much) - much = rex; - over -= much; - cz += much; - pex += much; - rex -= much; - } while (over); + much = over; + if (rex < much) + much = rex; + over -= much; + cz += much; + pex += much; + rex -= much; + } while (over); + } } -} /*---------------------------------------------------------------------------*/ /* * SANITY CHECKS */ /*---------------------------------------------------------------------------*/ -c2 = (mex + 1)*PAGE_SIZE - rex; -if (cz != c2) - SAM("ERROR: discrepancy %i in bytes read\n", c2 - cz); -c3 = (mad + 1)*PAGE_SIZE - rad; - -if (false == decimatepixel) { - if (bytesperpixel * \ - cz != c3) \ - SAM("ERROR: discrepancy %i in bytes written\n", \ - c3 - (bytesperpixel * \ - cz)); -} else { - if (false == odd) { - if (bytesperpixel * \ - cz != (4 * c3)) - SAM("ERROR: discrepancy %i in bytes written\n", \ - (2*c3)-(bytesperpixel * \ - cz)); - } else { - if (0 != c3) - SAM("ERROR: discrepancy %i " \ - "in bytes written\n", c3); - } -} -if (rump) - SAM("WORRY: undischarged cache at end of line in frame buffer\n"); + c2 = (mex + 1)*PAGE_SIZE - rex; + if (cz != c2) + SAM("ERROR: discrepancy %i in bytes read\n", c2 - cz); + c3 = (mad + 1)*PAGE_SIZE - rad; -JOM(8, "===== field2frame(): %i bytes --> %i bytes (incl skip)\n", c2, c3); -JOM(8, "===== field2frame(): %i=mad %i=rad\n", mad, rad); + if (!decimatepixel) { + if (bytesperpixel * cz != c3) + SAM("ERROR: discrepancy %i in bytes written\n", + c3 - (bytesperpixel * cz)); + } else { + if (!odd) { + if (bytesperpixel * + cz != (4 * c3)) + SAM("ERROR: discrepancy %i in bytes written\n", + (2*c3)-(bytesperpixel * cz)); + } else { + if (0 != c3) + SAM("ERROR: discrepancy %i " + "in bytes written\n", c3); + } + } + if (rump) + SAM("WORRY: undischarged cache at end of line in frame buffer\n"); -if (true == odd) - JOM(8, "+++++ field2frame(): frame buffer %i is full\n", kad); + JOM(8, "===== field2frame(): %i bytes --> %i bytes (incl skip)\n", c2, c3); + JOM(8, "===== field2frame(): %i=mad %i=rad\n", mad, rad); -if (peasycap->field_read == peasycap->field_fill) - SAM("WARNING: on exit, filling field buffer %i\n", \ - peasycap->field_read); + if (odd) + JOM(8, "+++++ field2frame(): frame buffer %i is full\n", kad); + + if (peasycap->field_read == peasycap->field_fill) + SAM("WARNING: on exit, filling field buffer %i\n", + peasycap->field_read); /*---------------------------------------------------------------------------*/ /* * CALCULATE VIDEO STREAMING RATE */ /*---------------------------------------------------------------------------*/ -do_gettimeofday(&timeval); -if (peasycap->timeval6.tv_sec) { - below = ((long long int)(1000000)) * \ - ((long long int)(timeval.tv_sec - \ - peasycap->timeval6.tv_sec)) + \ - (long long int)(timeval.tv_usec - peasycap->timeval6.tv_usec); - above = (long long int)1000000; + do_gettimeofday(&timeval); + if (peasycap->timeval6.tv_sec) { + below = ((long long int)(1000000)) * + ((long long int)(timeval.tv_sec - + peasycap->timeval6.tv_sec)) + + (long long int)(timeval.tv_usec - peasycap->timeval6.tv_usec); + above = (long long int)1000000; - sdr = signed_div(above, below); - above = sdr.quotient; - remainder = (__u32)sdr.remainder; + sdr = signed_div(above, below); + above = sdr.quotient; + remainder = (u32)sdr.remainder; - JOM(8, "video streaming at %3lli.%03i fields per second\n", above, \ - (remainder/1000)); -} -peasycap->timeval6 = timeval; + JOM(8, "video streaming at %3lli.%03i fields per second\n", + above, (remainder/1000)); + } + peasycap->timeval6 = timeval; -if (caches) - JOM(8, "%i=caches\n", caches); -return 0; + if (caches) + JOM(8, "%i=caches\n", caches); + return 0; } /*****************************************************************************/ struct signed_div_result signed_div(long long int above, long long int below) { -struct signed_div_result sdr; - -if (((0 <= above) && (0 <= below)) || ((0 > above) && (0 > below))) { - sdr.remainder = (unsigned long long int) do_div(above, below); - sdr.quotient = (long long int) above; -} else { - if (0 > above) - above = -above; - if (0 > below) - below = -below; - sdr.remainder = (unsigned long long int) do_div(above, below); - sdr.quotient = -((long long int) above); -} -return sdr; + struct signed_div_result sdr; + + if (((0 <= above) && (0 <= below)) || ((0 > above) && (0 > below))) { + sdr.remainder = (unsigned long long int) do_div(above, below); + sdr.quotient = (long long int) above; + } else { + if (0 > above) + above = -above; + if (0 > below) + below = -below; + sdr.remainder = (unsigned long long int) do_div(above, below); + sdr.quotient = -((long long int) above); + } + return sdr; } /*****************************************************************************/ /*---------------------------------------------------------------------------*/ @@ -1881,345 +1691,176 @@ return sdr; */ /*---------------------------------------------------------------------------*/ int -redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, \ - __u8 mask, __u8 margin, bool isuy) +redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, + u8 mask, u8 margin, bool isuy) { -static __s32 ay[256], bu[256], rv[256], gu[256], gv[256]; -__u8 *pcache; -__u8 r, g, b, y, u, v, c, *p2, *p3, *pz, *pr; -int bytesperpixel; -bool byteswaporder, decimatepixel, last; -int j, rump; -__s32 s32; - -if (much % 2) { - SAM("MISTAKE: much is odd\n"); - return -EFAULT; -} -bytesperpixel = peasycap->bytesperpixel; -byteswaporder = peasycap->byteswaporder; -decimatepixel = peasycap->decimatepixel; - -/*---------------------------------------------------------------------------*/ -if (!bu[255]) { - for (j = 0; j < 112; j++) { - s32 = (0xFF00 & (453 * j)) >> 8; - bu[j + 128] = s32; bu[127 - j] = -s32; - s32 = (0xFF00 & (359 * j)) >> 8; - rv[j + 128] = s32; rv[127 - j] = -s32; - s32 = (0xFF00 & (88 * j)) >> 8; - gu[j + 128] = s32; gu[127 - j] = -s32; - s32 = (0xFF00 & (183 * j)) >> 8; - gv[j + 128] = s32; gv[127 - j] = -s32; - } - for (j = 0; j < 16; j++) { - bu[j] = bu[16]; rv[j] = rv[16]; - gu[j] = gu[16]; gv[j] = gv[16]; - } - for (j = 240; j < 256; j++) { - bu[j] = bu[239]; rv[j] = rv[239]; - gu[j] = gu[239]; gv[j] = gv[239]; - } - for (j = 16; j < 236; j++) - ay[j] = j; - for (j = 0; j < 16; j++) - ay[j] = ay[16]; - for (j = 236; j < 256; j++) - ay[j] = ay[235]; - JOM(8, "lookup tables are prepared\n"); -} -pcache = peasycap->pcache; -if (NULL == pcache) - pcache = &peasycap->cache[0]; + static s32 ay[256], bu[256], rv[256], gu[256], gv[256]; + u8 *pcache; + u8 r, g, b, y, u, v, c, *p2, *p3, *pz, *pr; + int bytesperpixel; + bool byteswaporder, decimatepixel, last; + int j, rump; + s32 tmp; + + if (much % 2) { + SAM("MISTAKE: much is odd\n"); + return -EFAULT; + } + bytesperpixel = peasycap->bytesperpixel; + byteswaporder = peasycap->byteswaporder; + decimatepixel = peasycap->decimatepixel; + +/*---------------------------------------------------------------------------*/ + if (!bu[255]) { + for (j = 0; j < 112; j++) { + tmp = (0xFF00 & (453 * j)) >> 8; + bu[j + 128] = tmp; bu[127 - j] = -tmp; + tmp = (0xFF00 & (359 * j)) >> 8; + rv[j + 128] = tmp; rv[127 - j] = -tmp; + tmp = (0xFF00 & (88 * j)) >> 8; + gu[j + 128] = tmp; gu[127 - j] = -tmp; + tmp = (0xFF00 & (183 * j)) >> 8; + gv[j + 128] = tmp; gv[127 - j] = -tmp; + } + for (j = 0; j < 16; j++) { + bu[j] = bu[16]; rv[j] = rv[16]; + gu[j] = gu[16]; gv[j] = gv[16]; + } + for (j = 240; j < 256; j++) { + bu[j] = bu[239]; rv[j] = rv[239]; + gu[j] = gu[239]; gv[j] = gv[239]; + } + for (j = 16; j < 236; j++) + ay[j] = j; + for (j = 0; j < 16; j++) + ay[j] = ay[16]; + for (j = 236; j < 256; j++) + ay[j] = ay[235]; + JOM(8, "lookup tables are prepared\n"); + } + pcache = peasycap->pcache; + if (!pcache) + pcache = &peasycap->cache[0]; /*---------------------------------------------------------------------------*/ /* * TRANSFER CONTENTS OF CACHE TO THE FRAME BUFFER */ /*---------------------------------------------------------------------------*/ -if (!pcache) { - SAM("MISTAKE: pcache is NULL\n"); - return -EFAULT; -} + if (!pcache) { + SAM("MISTAKE: pcache is NULL\n"); + return -EFAULT; + } -if (pcache != &peasycap->cache[0]) - JOM(16, "cache has %i bytes\n", (int)(pcache - &peasycap->cache[0])); -p2 = &peasycap->cache[0]; -p3 = (__u8 *)pad - (int)(pcache - &peasycap->cache[0]); -while (p2 < pcache) { - *p3++ = *p2; p2++; -} -pcache = &peasycap->cache[0]; -if (p3 != pad) { - SAM("MISTAKE: pointer misalignment\n"); - return -EFAULT; -} -/*---------------------------------------------------------------------------*/ -rump = (int)(0x03 & mask); -u = 0; v = 0; -p2 = (__u8 *)pex; pz = p2 + much; pr = p3 + more; last = false; -p2++; - -if (true == isuy) - u = *(p2 - 1); -else - v = *(p2 - 1); - -if (rump) - JOM(16, "%4i=much %4i=more %i=rump\n", much, more, rump); - -/*---------------------------------------------------------------------------*/ -switch (bytesperpixel) { -case 2: { - if (false == decimatepixel) { - memcpy(pad, pex, (size_t)much); - if (false == byteswaporder) - /*---------------------------------------------------*/ - /* - ** UYVY - */ - /*---------------------------------------------------*/ - return 0; - else { - /*---------------------------------------------------*/ - /* - ** YUYV - */ - /*---------------------------------------------------*/ - p3 = (__u8 *)pad; pz = p3 + much; - while (pz > p3) { - c = *p3; - *p3 = *(p3 + 1); - *(p3 + 1) = c; - p3 += 2; - } - return 0; - } - } else { - if (false == byteswaporder) { - /*---------------------------------------------------*/ - /* - ** UYVY DECIMATED - */ - /*---------------------------------------------------*/ - p2 = (__u8 *)pex; p3 = (__u8 *)pad; pz = p2 + much; - while (pz > p2) { - *p3 = *p2; - *(p3 + 1) = *(p2 + 1); - *(p3 + 2) = *(p2 + 2); - *(p3 + 3) = *(p2 + 3); - p3 += 4; p2 += 8; - } - return 0; - } else { - /*---------------------------------------------------*/ - /* - ** YUYV DECIMATED - **/ - /*---------------------------------------------------*/ - p2 = (__u8 *)pex; p3 = (__u8 *)pad; pz = p2 + much; - while (pz > p2) { - *p3 = *(p2 + 1); - *(p3 + 1) = *p2; - *(p3 + 2) = *(p2 + 3); - *(p3 + 3) = *(p2 + 2); - p3 += 4; p2 += 8; - } - return 0; - } + if (pcache != &peasycap->cache[0]) + JOM(16, "cache has %i bytes\n", (int)(pcache - &peasycap->cache[0])); + p2 = &peasycap->cache[0]; + p3 = (u8 *)pad - (int)(pcache - &peasycap->cache[0]); + while (p2 < pcache) { + *p3++ = *p2; p2++; } - break; - } -case 3: - { - if (false == decimatepixel) { - if (false == byteswaporder) { - /*---------------------------------------------------*/ - /* - ** RGB - **/ - /*---------------------------------------------------*/ - while (pz > p2) { - if (pr <= (p3 + bytesperpixel)) - last = true; - else - last = false; - y = *p2; - if ((true == last) && (0x0C & mask)) { - if (0x04 & mask) { - if (true == isuy) - v = margin; - else - u = margin; - } else - if (0x08 & mask) - ; - } else { - if (true == isuy) - v = *(p2 + 1); - else - u = *(p2 + 1); - } + pcache = &peasycap->cache[0]; + if (p3 != pad) { + SAM("MISTAKE: pointer misalignment\n"); + return -EFAULT; + } +/*---------------------------------------------------------------------------*/ + rump = (int)(0x03 & mask); + u = 0; v = 0; + p2 = (u8 *)pex; pz = p2 + much; pr = p3 + more; last = false; + p2++; - s32 = ay[(int)y] + rv[(int)v]; - r = (255 < s32) ? 255 : ((0 > s32) ? \ - 0 : (__u8)s32); - s32 = ay[(int)y] - gu[(int)u] - gv[(int)v]; - g = (255 < s32) ? 255 : ((0 > s32) ? \ - 0 : (__u8)s32); - s32 = ay[(int)y] + bu[(int)u]; - b = (255 < s32) ? 255 : ((0 > s32) ? \ - 0 : (__u8)s32); - - if ((true == last) && rump) { - pcache = &peasycap->cache[0]; - switch (bytesperpixel - rump) { - case 1: { - *p3 = r; - *pcache++ = g; - *pcache++ = b; - break; - } - case 2: { - *p3 = r; - *(p3 + 1) = g; - *pcache++ = b; - break; - } - default: { - SAM("MISTAKE: %i=rump\n", \ - bytesperpixel - rump); - return -EFAULT; - } - } - } else { - *p3 = r; - *(p3 + 1) = g; - *(p3 + 2) = b; + if (isuy) + u = *(p2 - 1); + else + v = *(p2 - 1); + + if (rump) + JOM(16, "%4i=much %4i=more %i=rump\n", much, more, rump); + +/*---------------------------------------------------------------------------*/ + switch (bytesperpixel) { + case 2: { + if (!decimatepixel) { + memcpy(pad, pex, (size_t)much); + if (!byteswaporder) { + /* UYVY */ + return 0; + } else { + /* YUYV */ + p3 = (u8 *)pad; pz = p3 + much; + while (pz > p3) { + c = *p3; + *p3 = *(p3 + 1); + *(p3 + 1) = c; + p3 += 2; } - p2 += 2; - if (true == isuy) - isuy = false; - else - isuy = true; - p3 += bytesperpixel; + return 0; } - return 0; } else { - /*---------------------------------------------------*/ - /* - ** BGR - */ - /*---------------------------------------------------*/ - while (pz > p2) { - if (pr <= (p3 + bytesperpixel)) - last = true; - else - last = false; - y = *p2; - if ((true == last) && (0x0C & mask)) { - if (0x04 & mask) { - if (true == isuy) - v = margin; - else - u = margin; - } - else - if (0x08 & mask) - ; - } else { - if (true == isuy) - v = *(p2 + 1); - else - u = *(p2 + 1); + if (!byteswaporder) { + /* UYVY DECIMATED */ + p2 = (u8 *)pex; p3 = (u8 *)pad; pz = p2 + much; + while (pz > p2) { + *p3 = *p2; + *(p3 + 1) = *(p2 + 1); + *(p3 + 2) = *(p2 + 2); + *(p3 + 3) = *(p2 + 3); + p3 += 4; p2 += 8; } - - s32 = ay[(int)y] + rv[(int)v]; - r = (255 < s32) ? 255 : ((0 > s32) ? \ - 0 : (__u8)s32); - s32 = ay[(int)y] - gu[(int)u] - gv[(int)v]; - g = (255 < s32) ? 255 : ((0 > s32) ? \ - 0 : (__u8)s32); - s32 = ay[(int)y] + bu[(int)u]; - b = (255 < s32) ? 255 : ((0 > s32) ? \ - 0 : (__u8)s32); - - if ((true == last) && rump) { - pcache = &peasycap->cache[0]; - switch (bytesperpixel - rump) { - case 1: { - *p3 = b; - *pcache++ = g; - *pcache++ = r; - break; - } - case 2: { - *p3 = b; - *(p3 + 1) = g; - *pcache++ = r; - break; - } - default: { - SAM("MISTAKE: %i=rump\n", \ - bytesperpixel - rump); - return -EFAULT; - } - } - } else { - *p3 = b; - *(p3 + 1) = g; - *(p3 + 2) = r; - } - p2 += 2; - if (true == isuy) - isuy = false; - else - isuy = true; - p3 += bytesperpixel; + return 0; + } else { + /* YUYV DECIMATED */ + p2 = (u8 *)pex; p3 = (u8 *)pad; pz = p2 + much; + while (pz > p2) { + *p3 = *(p2 + 1); + *(p3 + 1) = *p2; + *(p3 + 2) = *(p2 + 3); + *(p3 + 3) = *(p2 + 2); + p3 += 4; p2 += 8; } + return 0; } - return 0; - } else { - if (false == byteswaporder) { - /*---------------------------------------------------*/ - /* - ** RGB DECIMATED - */ - /*---------------------------------------------------*/ - while (pz > p2) { - if (pr <= (p3 + bytesperpixel)) - last = true; - else - last = false; - y = *p2; - if ((true == last) && (0x0C & mask)) { - if (0x04 & mask) { - if (true == isuy) - v = margin; - else - u = margin; - } else - if (0x08 & mask) - ; - } else { - if (true == isuy) - v = *(p2 + 1); + } + break; + } + case 3: + { + if (!decimatepixel) { + if (!byteswaporder) { + /* RGB */ + while (pz > p2) { + if (pr <= (p3 + bytesperpixel)) + last = true; else - u = *(p2 + 1); - } + last = false; + y = *p2; + if (last && (0x0C & mask)) { + if (0x04 & mask) { + if (isuy) + v = margin; + else + u = margin; + } else + if (0x08 & mask) + ; + } else { + if (isuy) + v = *(p2 + 1); + else + u = *(p2 + 1); + } - if (true == isuy) { - s32 = ay[(int)y] + rv[(int)v]; - r = (255 < s32) ? 255 : ((0 > s32) ? \ - 0 : (__u8)s32); - s32 = ay[(int)y] - gu[(int)u] - \ - gv[(int)v]; - g = (255 < s32) ? 255 : ((0 > s32) ? \ - 0 : (__u8)s32); - s32 = ay[(int)y] + bu[(int)u]; - b = (255 < s32) ? 255 : ((0 > s32) ? \ - 0 : (__u8)s32); - - if ((true == last) && rump) { + tmp = ay[(int)y] + rv[(int)v]; + r = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; + g = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + tmp = ay[(int)y] + bu[(int)u]; + b = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + + if (last && rump) { pcache = &peasycap->cache[0]; switch (bytesperpixel - rump) { case 1: { @@ -2235,9 +1876,8 @@ case 3: break; } default: { - SAM("MISTAKE: " \ - "%i=rump\n", \ - bytesperpixel - rump); + SAM("MISTAKE: %i=rump\n", + bytesperpixel - rump); return -EFAULT; } } @@ -2246,56 +1886,50 @@ case 3: *(p3 + 1) = g; *(p3 + 2) = b; } - isuy = false; + p2 += 2; + if (isuy) + isuy = false; + else + isuy = true; p3 += bytesperpixel; - } else { - isuy = true; } - p2 += 2; - } - return 0; - } else { - /*---------------------------------------------------*/ - /* - * BGR DECIMATED - */ - /*---------------------------------------------------*/ - while (pz > p2) { - if (pr <= (p3 + bytesperpixel)) - last = true; - else - last = false; - y = *p2; - if ((true == last) && (0x0C & mask)) { - if (0x04 & mask) { - if (true == isuy) - v = margin; - else - u = margin; - } else + return 0; + } else { + /* BGR */ + while (pz > p2) { + if (pr <= (p3 + bytesperpixel)) + last = true; + else + last = false; + y = *p2; + if (last && (0x0C & mask)) { + if (0x04 & mask) { + if (isuy) + v = margin; + else + u = margin; + } + else if (0x08 & mask) ; - } else { - if (true == isuy) - v = *(p2 + 1); - else - u = *(p2 + 1); - } - - if (true == isuy) { - - s32 = ay[(int)y] + rv[(int)v]; - r = (255 < s32) ? 255 : ((0 > s32) ? \ - 0 : (__u8)s32); - s32 = ay[(int)y] - gu[(int)u] - \ - gv[(int)v]; - g = (255 < s32) ? 255 : ((0 > s32) ? \ - 0 : (__u8)s32); - s32 = ay[(int)y] + bu[(int)u]; - b = (255 < s32) ? 255 : ((0 > s32) ? \ - 0 : (__u8)s32); + } else { + if (isuy) + v = *(p2 + 1); + else + u = *(p2 + 1); + } - if ((true == last) && rump) { + tmp = ay[(int)y] + rv[(int)v]; + r = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; + g = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + tmp = ay[(int)y] + bu[(int)u]; + b = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + + if (last && rump) { pcache = &peasycap->cache[0]; switch (bytesperpixel - rump) { case 1: { @@ -2311,9 +1945,8 @@ case 3: break; } default: { - SAM("MISTAKE: " \ - "%i=rump\n", \ - bytesperpixel - rump); + SAM("MISTAKE: %i=rump\n", + bytesperpixel - rump); return -EFAULT; } } @@ -2322,229 +1955,201 @@ case 3: *(p3 + 1) = g; *(p3 + 2) = r; } - isuy = false; + p2 += 2; + if (isuy) + isuy = false; + else + isuy = true; p3 += bytesperpixel; } - else - isuy = true; - p2 += 2; } return 0; - } - } - break; - } -case 4: - { - if (false == decimatepixel) { - if (false == byteswaporder) { - /*---------------------------------------------------*/ - /* - ** RGBA - */ - /*---------------------------------------------------*/ - while (pz > p2) { - if (pr <= (p3 + bytesperpixel)) - last = true; - else - last = false; - y = *p2; - if ((true == last) && (0x0C & mask)) { - if (0x04 & mask) { - if (true == isuy) - v = margin; - else - u = margin; - } else - if (0x08 & mask) - ; - } else { - if (true == isuy) - v = *(p2 + 1); + } else { + if (!byteswaporder) { + /* RGB DECIMATED */ + while (pz > p2) { + if (pr <= (p3 + bytesperpixel)) + last = true; else - u = *(p2 + 1); - } - - s32 = ay[(int)y] + rv[(int)v]; - r = (255 < s32) ? 255 : ((0 > s32) ? \ - 0 : (__u8)s32); - s32 = ay[(int)y] - gu[(int)u] - gv[(int)v]; - g = (255 < s32) ? 255 : ((0 > s32) ? \ - 0 : (__u8)s32); - s32 = ay[(int)y] + bu[(int)u]; - b = (255 < s32) ? 255 : ((0 > s32) ? \ - 0 : (__u8)s32); - - if ((true == last) && rump) { - pcache = &peasycap->cache[0]; - switch (bytesperpixel - rump) { - case 1: { - *p3 = r; - *pcache++ = g; - *pcache++ = b; - *pcache++ = 0; - break; - } - case 2: { - *p3 = r; - *(p3 + 1) = g; - *pcache++ = b; - *pcache++ = 0; - break; - } - case 3: { - *p3 = r; - *(p3 + 1) = g; - *(p3 + 2) = b; - *pcache++ = 0; - break; - } - default: { - SAM("MISTAKE: %i=rump\n", \ - bytesperpixel - rump); - return -EFAULT; + last = false; + y = *p2; + if (last && (0x0C & mask)) { + if (0x04 & mask) { + if (isuy) + v = margin; + else + u = margin; + } else + if (0x08 & mask) + ; + } else { + if (isuy) + v = *(p2 + 1); + else + u = *(p2 + 1); } + + if (isuy) { + tmp = ay[(int)y] + rv[(int)v]; + r = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + tmp = ay[(int)y] - gu[(int)u] - + gv[(int)v]; + g = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + tmp = ay[(int)y] + bu[(int)u]; + b = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + + if (last && rump) { + pcache = &peasycap->cache[0]; + switch (bytesperpixel - rump) { + case 1: { + *p3 = r; + *pcache++ = g; + *pcache++ = b; + break; + } + case 2: { + *p3 = r; + *(p3 + 1) = g; + *pcache++ = b; + break; + } + default: { + SAM("MISTAKE: " + "%i=rump\n", + bytesperpixel - rump); + return -EFAULT; + } + } + } else { + *p3 = r; + *(p3 + 1) = g; + *(p3 + 2) = b; + } + isuy = false; + p3 += bytesperpixel; + } else { + isuy = true; } - } else { - *p3 = r; - *(p3 + 1) = g; - *(p3 + 2) = b; - *(p3 + 3) = 0; + p2 += 2; } - p2 += 2; - if (true == isuy) - isuy = false; - else - isuy = true; - p3 += bytesperpixel; - } - return 0; - } else { - /*---------------------------------------------------*/ - /* - ** BGRA - */ - /*---------------------------------------------------*/ - while (pz > p2) { - if (pr <= (p3 + bytesperpixel)) - last = true; - else - last = false; - y = *p2; - if ((true == last) && (0x0C & mask)) { - if (0x04 & mask) { - if (true == isuy) - v = margin; - else - u = margin; - } else - if (0x08 & mask) - ; - } else { - if (true == isuy) - v = *(p2 + 1); + return 0; + } else { + /* BGR DECIMATED */ + while (pz > p2) { + if (pr <= (p3 + bytesperpixel)) + last = true; else - u = *(p2 + 1); - } - - s32 = ay[(int)y] + rv[(int)v]; - r = (255 < s32) ? 255 : ((0 > s32) ? \ - 0 : (__u8)s32); - s32 = ay[(int)y] - gu[(int)u] - gv[(int)v]; - g = (255 < s32) ? 255 : ((0 > s32) ? \ - 0 : (__u8)s32); - s32 = ay[(int)y] + bu[(int)u]; - b = (255 < s32) ? 255 : ((0 > s32) ? \ - 0 : (__u8)s32); - - if ((true == last) && rump) { - pcache = &peasycap->cache[0]; - switch (bytesperpixel - rump) { - case 1: { - *p3 = b; - *pcache++ = g; - *pcache++ = r; - *pcache++ = 0; - break; - } - case 2: { - *p3 = b; - *(p3 + 1) = g; - *pcache++ = r; - *pcache++ = 0; - break; - } - case 3: { - *p3 = b; - *(p3 + 1) = g; - *(p3 + 2) = r; - *pcache++ = 0; - break; - } - default: { - SAM("MISTAKE: %i=rump\n", \ - bytesperpixel - rump); - return -EFAULT; + last = false; + y = *p2; + if (last && (0x0C & mask)) { + if (0x04 & mask) { + if (isuy) + v = margin; + else + u = margin; + } else + if (0x08 & mask) + ; + } else { + if (isuy) + v = *(p2 + 1); + else + u = *(p2 + 1); } + + if (isuy) { + + tmp = ay[(int)y] + rv[(int)v]; + r = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + tmp = ay[(int)y] - gu[(int)u] - + gv[(int)v]; + g = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + tmp = ay[(int)y] + bu[(int)u]; + b = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + + if (last && rump) { + pcache = &peasycap->cache[0]; + switch (bytesperpixel - rump) { + case 1: { + *p3 = b; + *pcache++ = g; + *pcache++ = r; + break; + } + case 2: { + *p3 = b; + *(p3 + 1) = g; + *pcache++ = r; + break; + } + default: { + SAM("MISTAKE: " + "%i=rump\n", + bytesperpixel - rump); + return -EFAULT; + } + } + } else { + *p3 = b; + *(p3 + 1) = g; + *(p3 + 2) = r; + } + isuy = false; + p3 += bytesperpixel; + } + else + isuy = true; + p2 += 2; } - } else { - *p3 = b; - *(p3 + 1) = g; - *(p3 + 2) = r; - *(p3 + 3) = 0; + return 0; } - p2 += 2; - if (true == isuy) - isuy = false; - else - isuy = true; - p3 += bytesperpixel; } + break; } - return 0; - } else { - if (false == byteswaporder) { - /*---------------------------------------------------*/ - /* - ** RGBA DECIMATED - */ - /*---------------------------------------------------*/ - while (pz > p2) { - if (pr <= (p3 + bytesperpixel)) - last = true; - else - last = false; - y = *p2; - if ((true == last) && (0x0C & mask)) { - if (0x04 & mask) { - if (true == isuy) - v = margin; - else - u = margin; - } else - if (0x08 & mask) - ; - } else { - if (true == isuy) - v = *(p2 + 1); + case 4: + { + if (!decimatepixel) { + if (!byteswaporder) { + /* RGBA */ + while (pz > p2) { + if (pr <= (p3 + bytesperpixel)) + last = true; else - u = *(p2 + 1); - } - - if (true == isuy) { - - s32 = ay[(int)y] + rv[(int)v]; - r = (255 < s32) ? 255 : ((0 > s32) ? \ - 0 : (__u8)s32); - s32 = ay[(int)y] - gu[(int)u] - \ - gv[(int)v]; - g = (255 < s32) ? 255 : ((0 > s32) ? \ - 0 : (__u8)s32); - s32 = ay[(int)y] + bu[(int)u]; - b = (255 < s32) ? 255 : ((0 > s32) ? \ - 0 : (__u8)s32); + last = false; + y = *p2; + if (last && (0x0C & mask)) { + if (0x04 & mask) { + if (isuy) + v = margin; + else + u = margin; + } else + if (0x08 & mask) + ; + } else { + if (isuy) + v = *(p2 + 1); + else + u = *(p2 + 1); + } - if ((true == last) && rump) { + tmp = ay[(int)y] + rv[(int)v]; + r = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; + g = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + tmp = ay[(int)y] + bu[(int)u]; + b = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + + if (last && rump) { pcache = &peasycap->cache[0]; switch (bytesperpixel - rump) { case 1: { @@ -2569,67 +2174,62 @@ case 4: break; } default: { - SAM("MISTAKE: " \ - "%i=rump\n", \ - bytesperpixel - \ - rump); + SAM("MISTAKE: %i=rump\n", + bytesperpixel - rump); return -EFAULT; - } + } } } else { *p3 = r; *(p3 + 1) = g; *(p3 + 2) = b; *(p3 + 3) = 0; - } - isuy = false; - p3 += bytesperpixel; - } else - isuy = true; - p2 += 2; - } - return 0; - } else { - /*---------------------------------------------------*/ - /* - ** BGRA DECIMATED - */ - /*---------------------------------------------------*/ - while (pz > p2) { - if (pr <= (p3 + bytesperpixel)) - last = true; - else - last = false; - y = *p2; - if ((true == last) && (0x0C & mask)) { - if (0x04 & mask) { - if (true == isuy) - v = margin; - else - u = margin; - } else - if (0x08 & mask) - ; - } else { - if (true == isuy) - v = *(p2 + 1); + } + p2 += 2; + if (isuy) + isuy = false; else - u = *(p2 + 1); + isuy = true; + p3 += bytesperpixel; } + return 0; + } else { + /* + * BGRA + */ + while (pz > p2) { + if (pr <= (p3 + bytesperpixel)) + last = true; + else + last = false; + y = *p2; + if (last && (0x0C & mask)) { + if (0x04 & mask) { + if (isuy) + v = margin; + else + u = margin; + } else + if (0x08 & mask) + ; + } else { + if (isuy) + v = *(p2 + 1); + else + u = *(p2 + 1); + } - if (true == isuy) { - s32 = ay[(int)y] + rv[(int)v]; - r = (255 < s32) ? 255 : ((0 > s32) ? \ - 0 : (__u8)s32); - s32 = ay[(int)y] - gu[(int)u] - \ - gv[(int)v]; - g = (255 < s32) ? 255 : ((0 > s32) ? \ - 0 : (__u8)s32); - s32 = ay[(int)y] + bu[(int)u]; - b = (255 < s32) ? 255 : ((0 > s32) ? \ - 0 : (__u8)s32); - - if ((true == last) && rump) { + tmp = ay[(int)y] + rv[(int)v]; + r = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; + g = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + tmp = ay[(int)y] + bu[(int)u]; + b = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + + if (last && rump) { pcache = &peasycap->cache[0]; switch (bytesperpixel - rump) { case 1: { @@ -2653,157 +2253,322 @@ case 4: *pcache++ = 0; break; } - default: { - SAM("MISTAKE: " \ - "%i=rump\n", \ - bytesperpixel - rump); + default: + SAM("MISTAKE: %i=rump\n", + bytesperpixel - rump); return -EFAULT; } - } } else { *p3 = b; *(p3 + 1) = g; *(p3 + 2) = r; *(p3 + 3) = 0; } - isuy = false; + p2 += 2; + if (isuy) + isuy = false; + else + isuy = true; p3 += bytesperpixel; - } else - isuy = true; + } + } + return 0; + } else { + if (!byteswaporder) { + /* + * RGBA DECIMATED + */ + while (pz > p2) { + if (pr <= (p3 + bytesperpixel)) + last = true; + else + last = false; + y = *p2; + if (last && (0x0C & mask)) { + if (0x04 & mask) { + if (isuy) + v = margin; + else + u = margin; + } else + if (0x08 & mask) + ; + } else { + if (isuy) + v = *(p2 + 1); + else + u = *(p2 + 1); + } + + if (isuy) { + + tmp = ay[(int)y] + rv[(int)v]; + r = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + tmp = ay[(int)y] - gu[(int)u] - + gv[(int)v]; + g = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + tmp = ay[(int)y] + bu[(int)u]; + b = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + + if (last && rump) { + pcache = &peasycap->cache[0]; + switch (bytesperpixel - rump) { + case 1: { + *p3 = r; + *pcache++ = g; + *pcache++ = b; + *pcache++ = 0; + break; + } + case 2: { + *p3 = r; + *(p3 + 1) = g; + *pcache++ = b; + *pcache++ = 0; + break; + } + case 3: { + *p3 = r; + *(p3 + 1) = g; + *(p3 + 2) = b; + *pcache++ = 0; + break; + } + default: { + SAM("MISTAKE: " + "%i=rump\n", + bytesperpixel - + rump); + return -EFAULT; + } + } + } else { + *p3 = r; + *(p3 + 1) = g; + *(p3 + 2) = b; + *(p3 + 3) = 0; + } + isuy = false; + p3 += bytesperpixel; + } else + isuy = true; p2 += 2; } return 0; + } else { + /* + * BGRA DECIMATED + */ + while (pz > p2) { + if (pr <= (p3 + bytesperpixel)) + last = true; + else + last = false; + y = *p2; + if (last && (0x0C & mask)) { + if (0x04 & mask) { + if (isuy) + v = margin; + else + u = margin; + } else + if (0x08 & mask) + ; + } else { + if (isuy) + v = *(p2 + 1); + else + u = *(p2 + 1); + } + + if (isuy) { + tmp = ay[(int)y] + rv[(int)v]; + r = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + tmp = ay[(int)y] - gu[(int)u] - + gv[(int)v]; + g = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + tmp = ay[(int)y] + bu[(int)u]; + b = (255 < tmp) ? 255 : ((0 > tmp) ? + 0 : (u8)tmp); + + if (last && rump) { + pcache = &peasycap->cache[0]; + switch (bytesperpixel - rump) { + case 1: { + *p3 = b; + *pcache++ = g; + *pcache++ = r; + *pcache++ = 0; + break; + } + case 2: { + *p3 = b; + *(p3 + 1) = g; + *pcache++ = r; + *pcache++ = 0; + break; + } + case 3: { + *p3 = b; + *(p3 + 1) = g; + *(p3 + 2) = r; + *pcache++ = 0; + break; + } + default: { + SAM("MISTAKE: " + "%i=rump\n", + bytesperpixel - rump); + return -EFAULT; + } + } + } else { + *p3 = b; + *(p3 + 1) = g; + *(p3 + 2) = r; + *(p3 + 3) = 0; + } + isuy = false; + p3 += bytesperpixel; + } else + isuy = true; + p2 += 2; + } + return 0; + } } + break; + } + default: { + SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel); + return -EFAULT; } - break; - } -default: { - SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel); - return -EFAULT; } -} -return 0; + return 0; } /*****************************************************************************/ -/*---------------------------------------------------------------------------*/ /* * SEE CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGES 430-434 */ -/*---------------------------------------------------------------------------*/ -int easycap_mmap(struct file *file, struct vm_area_struct *pvma) -{ - -JOT(8, "\n"); - -pvma->vm_ops = &easycap_vm_ops; -pvma->vm_flags |= VM_RESERVED; -if (NULL != file) - pvma->vm_private_data = file->private_data; -easycap_vma_open(pvma); -return 0; -} /*****************************************************************************/ -void -easycap_vma_open(struct vm_area_struct *pvma) +static void easycap_vma_open(struct vm_area_struct *pvma) { -struct easycap *peasycap; + struct easycap *peasycap; -peasycap = pvma->vm_private_data; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + peasycap = pvma->vm_private_data; + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: %p\n", peasycap); + return; + } + peasycap->vma_many++; + JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many); return; } -peasycap->vma_many++; -JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many); -return; -} /*****************************************************************************/ -void -easycap_vma_close(struct vm_area_struct *pvma) +static void easycap_vma_close(struct vm_area_struct *pvma) { -struct easycap *peasycap; + struct easycap *peasycap; -peasycap = pvma->vm_private_data; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + peasycap = pvma->vm_private_data; + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: %p\n", peasycap); + return; + } + peasycap->vma_many--; + JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many); return; } -peasycap->vma_many--; -JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many); -return; -} /*****************************************************************************/ -int -easycap_vma_fault(struct vm_area_struct *pvma, struct vm_fault *pvmf) +static int easycap_vma_fault(struct vm_area_struct *pvma, struct vm_fault *pvmf) { -int k, m, retcode; -void *pbuf; -struct page *page; -struct easycap *peasycap; + int k, m, retcode; + void *pbuf; + struct page *page; + struct easycap *peasycap; -retcode = VM_FAULT_NOPAGE; -pbuf = (void *)NULL; -page = (struct page *)NULL; + retcode = VM_FAULT_NOPAGE; -if (NULL == pvma) { - SAY("pvma is NULL\n"); - return retcode; -} -if (NULL == pvmf) { - SAY("pvmf is NULL\n"); - return retcode; -} + if (!pvma) { + SAY("pvma is NULL\n"); + return retcode; + } + if (!pvmf) { + SAY("pvmf is NULL\n"); + return retcode; + } -k = (pvmf->pgoff) / (FRAME_BUFFER_SIZE/PAGE_SIZE); -m = (pvmf->pgoff) % (FRAME_BUFFER_SIZE/PAGE_SIZE); + k = (pvmf->pgoff) / (FRAME_BUFFER_SIZE/PAGE_SIZE); + m = (pvmf->pgoff) % (FRAME_BUFFER_SIZE/PAGE_SIZE); -if (!m) - JOT(4, "%4i=k, %4i=m\n", k, m); -else - JOT(16, "%4i=k, %4i=m\n", k, m); + if (!m) + JOT(4, "%4i=k, %4i=m\n", k, m); + else + JOT(16, "%4i=k, %4i=m\n", k, m); -if ((0 > k) || (FRAME_BUFFER_MANY <= k)) { - SAY("ERROR: buffer index %i out of range\n", k); - return retcode; -} -if ((0 > m) || (FRAME_BUFFER_SIZE/PAGE_SIZE <= m)) { - SAY("ERROR: page number %i out of range\n", m); - return retcode; -} -peasycap = pvma->vm_private_data; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return retcode; -} + if ((0 > k) || (FRAME_BUFFER_MANY <= k)) { + SAY("ERROR: buffer index %i out of range\n", k); + return retcode; + } + if ((0 > m) || (FRAME_BUFFER_SIZE/PAGE_SIZE <= m)) { + SAY("ERROR: page number %i out of range\n", m); + return retcode; + } + peasycap = pvma->vm_private_data; + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return retcode; + } /*---------------------------------------------------------------------------*/ -pbuf = peasycap->frame_buffer[k][m].pgo; -if (NULL == pbuf) { - SAM("ERROR: pbuf is NULL\n"); - goto finish; -} -page = virt_to_page(pbuf); -if (NULL == page) { - SAM("ERROR: page is NULL\n"); - goto finish; -} -get_page(page); -/*---------------------------------------------------------------------------*/ -finish: -if (NULL == page) { - SAM("ERROR: page is NULL after get_page(page)\n"); -} else { - pvmf->page = page; - retcode = VM_FAULT_MINOR; + pbuf = peasycap->frame_buffer[k][m].pgo; + if (!pbuf) { + SAM("ERROR: pbuf is NULL\n"); + return retcode; + } + page = virt_to_page(pbuf); + if (!page) { + SAM("ERROR: page is NULL\n"); + return retcode; + } + get_page(page); +/*---------------------------------------------------------------------------*/ + if (!page) { + SAM("ERROR: page is NULL after get_page(page)\n"); + } else { + pvmf->page = page; + retcode = VM_FAULT_MINOR; + } + return retcode; } -return retcode; + +static const struct vm_operations_struct easycap_vm_ops = { + .open = easycap_vma_open, + .close = easycap_vma_close, + .fault = easycap_vma_fault, +}; + +static int easycap_mmap(struct file *file, struct vm_area_struct *pvma) +{ + JOT(8, "\n"); + + pvma->vm_ops = &easycap_vm_ops; + pvma->vm_flags |= VM_RESERVED; + if (file) + pvma->vm_private_data = file->private_data; + easycap_vma_open(pvma); + return 0; } /*****************************************************************************/ /*---------------------------------------------------------------------------*/ @@ -2832,291 +2597,128 @@ return retcode; * 0 != (kount & 0x0100) => BUFFER HAS TWO EXTRA BYTES - WHY? */ /*---------------------------------------------------------------------------*/ -void -easycap_complete(struct urb *purb) +static void easycap_complete(struct urb *purb) { -struct easycap *peasycap; -struct data_buffer *pfield_buffer; -char errbuf[16]; -int i, more, much, leap, rc, last; -int videofieldamount; -unsigned int override, bad; -int framestatus, framelength, frameactual, frameoffset; -__u8 *pu; - -if (NULL == purb) { - SAY("ERROR: easycap_complete(): purb is NULL\n"); - return; -} -peasycap = purb->context; -if (NULL == peasycap) { - SAY("ERROR: easycap_complete(): peasycap is NULL\n"); - return; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); - return; -} -if (peasycap->video_eof) - return; -for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++) - if (purb->transfer_buffer == peasycap->video_isoc_buffer[i].pgo) - break; -JOM(16, "%2i=urb\n", i); -last = peasycap->video_isoc_sequence; -if ((((VIDEO_ISOC_BUFFER_MANY - 1) == last) && \ - (0 != i)) || \ - (((VIDEO_ISOC_BUFFER_MANY - 1) != last) && \ - ((last + 1) != i))) { - JOM(16, "ERROR: out-of-order urbs %i,%i ... continuing\n", last, i); -} -peasycap->video_isoc_sequence = i; + struct easycap *peasycap; + struct data_buffer *pfield_buffer; + char errbuf[16]; + int i, more, much, leap, rc, last; + int videofieldamount; + unsigned int override, bad; + int framestatus, framelength, frameactual, frameoffset; + u8 *pu; + + if (!purb) { + SAY("ERROR: easycap_complete(): purb is NULL\n"); + return; + } + peasycap = purb->context; + if (!peasycap) { + SAY("ERROR: easycap_complete(): peasycap is NULL\n"); + return; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: %p\n", peasycap); + return; + } + if (peasycap->video_eof) + return; + for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++) + if (purb->transfer_buffer == peasycap->video_isoc_buffer[i].pgo) + break; + JOM(16, "%2i=urb\n", i); + last = peasycap->video_isoc_sequence; + if ((((VIDEO_ISOC_BUFFER_MANY - 1) == last) && (0 != i)) || + (((VIDEO_ISOC_BUFFER_MANY - 1) != last) && ((last + 1) != i))) { + JOM(16, "ERROR: out-of-order urbs %i,%i ... continuing\n", + last, i); + } + peasycap->video_isoc_sequence = i; -if (peasycap->video_idle) { - JOM(16, "%i=video_idle %i=video_isoc_streaming\n", \ - peasycap->video_idle, peasycap->video_isoc_streaming); - if (peasycap->video_isoc_streaming) { - rc = usb_submit_urb(purb, GFP_ATOMIC); - if (0 != rc) { - switch (rc) { - case -ENOMEM: { - SAM("ENOMEM\n"); - break; - } - case -ENODEV: { - SAM("ENODEV\n"); - break; - } - case -ENXIO: { - SAM("ENXIO\n"); - break; - } - case -EINVAL: { - SAM("EINVAL\n"); - break; - } - case -EAGAIN: { - SAM("EAGAIN\n"); - break; - } - case -EFBIG: { - SAM("EFBIG\n"); - break; - } - case -EPIPE: { - SAM("EPIPE\n"); - break; - } - case -EMSGSIZE: { - SAM("EMSGSIZE\n"); - break; - } - case -ENOSPC: { - SAM("ENOSPC\n"); - break; - } - default: { - SAM("0x%08X\n", rc); - break; - } + if (peasycap->video_idle) { + JOM(16, "%i=video_idle %i=video_isoc_streaming\n", + peasycap->video_idle, peasycap->video_isoc_streaming); + if (peasycap->video_isoc_streaming) { + rc = usb_submit_urb(purb, GFP_ATOMIC); + if (rc) { + SAM("%s:%d ENOMEM\n", strerror(rc), rc); + if (-ENODEV != rc) + SAM("ERROR: while %i=video_idle, " + "usb_submit_urb() " + "failed with rc:\n", + peasycap->video_idle); } - if (-ENODEV != rc) \ - SAM("ERROR: while %i=video_idle, " \ - "usb_submit_urb() " \ - "failed with rc:\n", \ - peasycap->video_idle); } + return; } -return; -} -override = 0; + override = 0; /*---------------------------------------------------------------------------*/ -if (FIELD_BUFFER_MANY <= peasycap->field_fill) { - SAM("ERROR: bad peasycap->field_fill\n"); - return; -} -if (purb->status) { - if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) { - JOM(8, "urb status -ESHUTDOWN or -ENOENT\n"); + if (FIELD_BUFFER_MANY <= peasycap->field_fill) { + SAM("ERROR: bad peasycap->field_fill\n"); return; } + if (purb->status) { + if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) { + JOM(8, "urb status -ESHUTDOWN or -ENOENT\n"); + return; + } - (peasycap->field_buffer[peasycap->field_fill][0].kount) |= 0x8000 ; - SAM("ERROR: bad urb status:\n"); - switch (purb->status) { - case -EINPROGRESS: { - SAM("-EINPROGRESS\n"); break; - } - case -ENOSR: { - SAM("-ENOSR\n"); break; - } - case -EPIPE: { - SAM("-EPIPE\n"); break; - } - case -EOVERFLOW: { - SAM("-EOVERFLOW\n"); break; - } - case -EPROTO: { - SAM("-EPROTO\n"); break; - } - case -EILSEQ: { - SAM("-EILSEQ\n"); break; - } - case -ETIMEDOUT: { - SAM("-ETIMEDOUT\n"); break; - } - case -EMSGSIZE: { - SAM("-EMSGSIZE\n"); break; - } - case -EOPNOTSUPP: { - SAM("-EOPNOTSUPP\n"); break; - } - case -EPFNOSUPPORT: { - SAM("-EPFNOSUPPORT\n"); break; - } - case -EAFNOSUPPORT: { - SAM("-EAFNOSUPPORT\n"); break; - } - case -EADDRINUSE: { - SAM("-EADDRINUSE\n"); break; - } - case -EADDRNOTAVAIL: { - SAM("-EADDRNOTAVAIL\n"); break; - } - case -ENOBUFS: { - SAM("-ENOBUFS\n"); break; - } - case -EISCONN: { - SAM("-EISCONN\n"); break; - } - case -ENOTCONN: { - SAM("-ENOTCONN\n"); break; - } - case -ESHUTDOWN: { - SAM("-ESHUTDOWN\n"); break; - } - case -ENOENT: { - SAM("-ENOENT\n"); break; - } - case -ECONNRESET: { - SAM("-ECONNRESET\n"); break; - } - case -ENOSPC: { - SAM("ENOSPC\n"); break; - } - default: { - SAM("unknown error code 0x%08X\n", purb->status); break; - } - } + (peasycap->field_buffer[peasycap->field_fill][0].kount) |= 0x8000 ; + SAM("ERROR: bad urb status -%s: %d\n", + strerror(purb->status), purb->status); /*---------------------------------------------------------------------------*/ -} else { - for (i = 0; i < purb->number_of_packets; i++) { - if (0 != purb->iso_frame_desc[i].status) { - (peasycap->field_buffer\ - [peasycap->field_fill][0].kount) |= 0x8000 ; - switch (purb->iso_frame_desc[i].status) { - case 0: { - strcpy(&errbuf[0], "OK"); break; - } - case -ENOENT: { - strcpy(&errbuf[0], "-ENOENT"); break; - } - case -EINPROGRESS: { - strcpy(&errbuf[0], "-EINPROGRESS"); break; - } - case -EPROTO: { - strcpy(&errbuf[0], "-EPROTO"); break; - } - case -EILSEQ: { - strcpy(&errbuf[0], "-EILSEQ"); break; - } - case -ETIME: { - strcpy(&errbuf[0], "-ETIME"); break; - } - case -ETIMEDOUT: { - strcpy(&errbuf[0], "-ETIMEDOUT"); break; - } - case -EPIPE: { - strcpy(&errbuf[0], "-EPIPE"); break; - } - case -ECOMM: { - strcpy(&errbuf[0], "-ECOMM"); break; - } - case -ENOSR: { - strcpy(&errbuf[0], "-ENOSR"); break; - } - case -EOVERFLOW: { - strcpy(&errbuf[0], "-EOVERFLOW"); break; - } - case -EREMOTEIO: { - strcpy(&errbuf[0], "-EREMOTEIO"); break; - } - case -ENODEV: { - strcpy(&errbuf[0], "-ENODEV"); break; - } - case -EXDEV: { - strcpy(&errbuf[0], "-EXDEV"); break; - } - case -EINVAL: { - strcpy(&errbuf[0], "-EINVAL"); break; - } - case -ECONNRESET: { - strcpy(&errbuf[0], "-ECONNRESET"); break; - } - case -ENOSPC: { - SAM("ENOSPC\n"); break; - } - case -ESHUTDOWN: { - strcpy(&errbuf[0], "-ESHUTDOWN"); break; - } - default: { - strcpy(&errbuf[0], "unknown error"); break; - } - } - } - framestatus = purb->iso_frame_desc[i].status; - framelength = purb->iso_frame_desc[i].length; - frameactual = purb->iso_frame_desc[i].actual_length; - frameoffset = purb->iso_frame_desc[i].offset; - - JOM(16, "frame[%2i]:" \ - "%4i=status " \ - "%4i=actual " \ - "%4i=length " \ - "%5i=offset\n", \ - i, framestatus, frameactual, framelength, frameoffset); - if (!purb->iso_frame_desc[i].status) { - more = purb->iso_frame_desc[i].actual_length; - pfield_buffer = &peasycap->field_buffer\ - [peasycap->field_fill][peasycap->field_page]; - videofieldamount = (peasycap->field_page * \ - PAGE_SIZE) + \ - (int)(pfield_buffer->pto - pfield_buffer->pgo); - if (4 == more) - peasycap->video_mt++; - if (4 < more) { - if (peasycap->video_mt) { - JOM(8, "%4i empty video urb frames\n", \ - peasycap->video_mt); - peasycap->video_mt = 0; - } - if (FIELD_BUFFER_MANY <= peasycap->field_fill) { - SAM("ERROR: bad peasycap->field_fill\n"); - return; - } - if (FIELD_BUFFER_SIZE/PAGE_SIZE <= \ - peasycap->field_page) { - SAM("ERROR: bad peasycap->field_page\n"); - return; + } else { + for (i = 0; i < purb->number_of_packets; i++) { + if (0 != purb->iso_frame_desc[i].status) { + (peasycap->field_buffer + [peasycap->field_fill][0].kount) |= 0x8000 ; + /* FIXME: 1. missing '-' check boundaries */ + strcpy(&errbuf[0], + strerror(purb->iso_frame_desc[i].status)); } - pfield_buffer = &peasycap->field_buffer\ - [peasycap->field_fill][peasycap->field_page]; - pu = (__u8 *)(purb->transfer_buffer + \ - purb->iso_frame_desc[i].offset); - if (0x80 & *pu) - leap = 8; - else - leap = 4; + framestatus = purb->iso_frame_desc[i].status; + framelength = purb->iso_frame_desc[i].length; + frameactual = purb->iso_frame_desc[i].actual_length; + frameoffset = purb->iso_frame_desc[i].offset; + + JOM(16, "frame[%2i]:" + "%4i=status " + "%4i=actual " + "%4i=length " + "%5i=offset\n", + i, framestatus, frameactual, framelength, frameoffset); + if (!purb->iso_frame_desc[i].status) { + more = purb->iso_frame_desc[i].actual_length; + pfield_buffer = &peasycap->field_buffer + [peasycap->field_fill][peasycap->field_page]; + videofieldamount = (peasycap->field_page * + PAGE_SIZE) + + (int)(pfield_buffer->pto - pfield_buffer->pgo); + if (4 == more) + peasycap->video_mt++; + if (4 < more) { + if (peasycap->video_mt) { + JOM(8, "%4i empty video urb frames\n", + peasycap->video_mt); + peasycap->video_mt = 0; + } + if (FIELD_BUFFER_MANY <= peasycap->field_fill) { + SAM("ERROR: bad peasycap->field_fill\n"); + return; + } + if (FIELD_BUFFER_SIZE/PAGE_SIZE <= + peasycap->field_page) { + SAM("ERROR: bad peasycap->field_page\n"); + return; + } + pfield_buffer = &peasycap->field_buffer + [peasycap->field_fill][peasycap->field_page]; + pu = (u8 *)(purb->transfer_buffer + + purb->iso_frame_desc[i].offset); + if (0x80 & *pu) + leap = 8; + else + leap = 4; /*--------------------------------------------------------------------------*/ /* * EIGHT-BYTE END-OF-VIDEOFIELD MARKER. @@ -3134,196 +2736,195 @@ if (purb->status) { * RESTS WITH dqbuf(). */ /*---------------------------------------------------------------------------*/ - if ((8 == more) || override) { - if (videofieldamount > \ - peasycap->videofieldamount) { - if (2 == videofieldamount - \ - peasycap->\ - videofieldamount) { - (peasycap->field_buffer\ - [peasycap->field_fill]\ - [0].kount) |= 0x0100; - peasycap->video_junk += (1 + \ - VIDEO_JUNK_TOLERATE); - } else - (peasycap->field_buffer\ - [peasycap->field_fill]\ - [0].kount) |= 0x4000; - } else if (videofieldamount < \ - peasycap->\ - videofieldamount) { - (peasycap->field_buffer\ - [peasycap->field_fill]\ - [0].kount) |= 0x2000; - } - bad = 0xFF00 & peasycap->field_buffer\ - [peasycap->field_fill]\ - [0].kount; - if (!bad) { - (peasycap->video_junk)--; - if (-VIDEO_JUNK_TOLERATE > \ - peasycap->video_junk) \ - peasycap->video_junk =\ - -VIDEO_JUNK_TOLERATE; - peasycap->field_read = \ - (peasycap->\ - field_fill)++; - if (FIELD_BUFFER_MANY <= \ - peasycap->\ - field_fill) - peasycap->\ - field_fill = 0; + if ((8 == more) || override) { + if (videofieldamount > + peasycap->videofieldamount) { + if (2 == videofieldamount - + peasycap-> + videofieldamount) { + (peasycap->field_buffer + [peasycap->field_fill] + [0].kount) |= 0x0100; + peasycap->video_junk += (1 + + VIDEO_JUNK_TOLERATE); + } else + (peasycap->field_buffer + [peasycap->field_fill] + [0].kount) |= 0x4000; + } else if (videofieldamount < + peasycap-> + videofieldamount) { + (peasycap->field_buffer + [peasycap->field_fill] + [0].kount) |= 0x2000; + } + bad = 0xFF00 & peasycap->field_buffer + [peasycap->field_fill] + [0].kount; + if (!bad) { + (peasycap->video_junk)--; + if (-VIDEO_JUNK_TOLERATE > + peasycap->video_junk) + peasycap->video_junk = + -VIDEO_JUNK_TOLERATE; + peasycap->field_read = + (peasycap-> + field_fill)++; + if (FIELD_BUFFER_MANY <= + peasycap-> + field_fill) + peasycap-> + field_fill = 0; + peasycap->field_page = 0; + pfield_buffer = &peasycap-> + field_buffer + [peasycap-> + field_fill] + [peasycap-> + field_page]; + pfield_buffer->pto = + pfield_buffer->pgo; + JOM(8, "bumped to: %i=" + "peasycap->" + "field_fill %i=" + "parity\n", + peasycap->field_fill, + 0x00FF & + pfield_buffer->kount); + JOM(8, "field buffer %i has " + "%i bytes fit to be " + "read\n", + peasycap->field_read, + videofieldamount); + JOM(8, "wakeup call to " + "wq_video, " + "%i=field_read " + "%i=field_fill " + "%i=parity\n", + peasycap->field_read, + peasycap->field_fill, + 0x00FF & peasycap-> + field_buffer + [peasycap-> + field_read][0].kount); + wake_up_interruptible + (&(peasycap-> + wq_video)); + do_gettimeofday + (&peasycap->timeval7); + } else { + peasycap->video_junk++; + if (bad & 0x0010) + peasycap->video_junk += + (1 + VIDEO_JUNK_TOLERATE/2); + JOM(8, "field buffer %i had %i " + "bytes, now discarded: " + "0x%04X\n", + peasycap->field_fill, + videofieldamount, + (0xFF00 & + peasycap->field_buffer + [peasycap->field_fill][0]. + kount)); + (peasycap->field_fill)++; + + if (FIELD_BUFFER_MANY <= + peasycap->field_fill) + peasycap->field_fill = 0; peasycap->field_page = 0; - pfield_buffer = &peasycap->\ - field_buffer\ - [peasycap->\ - field_fill]\ - [peasycap->\ - field_page]; - pfield_buffer->pto = \ - pfield_buffer->pgo; - JOM(8, "bumped to: %i="\ - "peasycap->" \ - "field_fill %i="\ - "parity\n", \ - peasycap->field_fill, \ - 0x00FF & \ - pfield_buffer->kount); - JOM(8, "field buffer %i has "\ - "%i bytes fit to be "\ - "read\n", \ - peasycap->field_read, \ - videofieldamount); - JOM(8, "wakeup call to "\ - "wq_video, " \ - "%i=field_read "\ - "%i=field_fill "\ - "%i=parity\n", \ - peasycap->field_read, \ - peasycap->field_fill, \ - 0x00FF & peasycap->\ - field_buffer\ - [peasycap->\ - field_read][0].kount); - wake_up_interruptible\ - (&(peasycap->\ - wq_video)); - do_gettimeofday\ - (&peasycap->timeval7); - } else { - peasycap->video_junk++; - if (bad & 0x0010) \ - peasycap->video_junk += \ - (1 + VIDEO_JUNK_TOLERATE/2); - JOM(8, "field buffer %i had %i " \ - "bytes, now discarded: "\ - "0x%04X\n", \ - peasycap->field_fill, \ - videofieldamount,\ - (0xFF00 & \ - peasycap->field_buffer\ - [peasycap->field_fill][0].\ - kount)); - (peasycap->field_fill)++; - - if (FIELD_BUFFER_MANY <= \ - peasycap->field_fill) - peasycap->field_fill = 0; - peasycap->field_page = 0; - pfield_buffer = \ - &peasycap->field_buffer\ - [peasycap->field_fill]\ - [peasycap->field_page]; - pfield_buffer->pto = \ - pfield_buffer->pgo; - - JOM(8, "bumped to: %i=peasycap->" \ - "field_fill %i=parity\n", \ - peasycap->field_fill, \ - 0x00FF & pfield_buffer->kount); - } - if (8 == more) { - JOM(8, "end-of-field: received " \ - "parity byte 0x%02X\n", \ - (0xFF & *pu)); - if (0x40 & *pu) - pfield_buffer->kount = 0x0000; - else - pfield_buffer->kount = 0x0001; - pfield_buffer->input = 0x08 | \ - (0x07 & peasycap->input); - JOM(8, "end-of-field: 0x%02X=kount\n",\ - 0xFF & pfield_buffer->kount); + pfield_buffer = + &peasycap->field_buffer + [peasycap->field_fill] + [peasycap->field_page]; + pfield_buffer->pto = + pfield_buffer->pgo; + + JOM(8, "bumped to: %i=peasycap->" + "field_fill %i=parity\n", + peasycap->field_fill, + 0x00FF & pfield_buffer->kount); + } + if (8 == more) { + JOM(8, "end-of-field: received " + "parity byte 0x%02X\n", + (0xFF & *pu)); + if (0x40 & *pu) + pfield_buffer->kount = 0x0000; + else + pfield_buffer->kount = 0x0001; + pfield_buffer->input = 0x08 | + (0x07 & peasycap->input); + JOM(8, "end-of-field: 0x%02X=kount\n", + 0xFF & pfield_buffer->kount); + } } - } /*---------------------------------------------------------------------------*/ /* * COPY more BYTES FROM ISOC BUFFER TO FIELD BUFFER */ /*---------------------------------------------------------------------------*/ - pu += leap; - more -= leap; + pu += leap; + more -= leap; - if (FIELD_BUFFER_MANY <= peasycap->field_fill) { - SAM("ERROR: bad peasycap->field_fill\n"); - return; - } - if (FIELD_BUFFER_SIZE/PAGE_SIZE <= \ - peasycap->field_page) { - SAM("ERROR: bad peasycap->field_page\n"); - return; - } - pfield_buffer = &peasycap->field_buffer\ - [peasycap->field_fill][peasycap->field_page]; - while (more) { - pfield_buffer = &peasycap->field_buffer\ - [peasycap->field_fill]\ - [peasycap->field_page]; - if (PAGE_SIZE < (pfield_buffer->pto - \ - pfield_buffer->pgo)) { - SAM("ERROR: bad pfield_buffer->pto\n"); + if (FIELD_BUFFER_MANY <= peasycap->field_fill) { + SAM("ERROR: bad peasycap->field_fill\n"); return; } - if (PAGE_SIZE == (pfield_buffer->pto - \ - pfield_buffer->pgo)) { - (peasycap->field_page)++; - if (FIELD_BUFFER_SIZE/PAGE_SIZE <= \ - peasycap->field_page) { - JOM(16, "wrapping peasycap->" \ - "field_page\n"); - peasycap->field_page = 0; - } - pfield_buffer = &peasycap->\ - field_buffer\ - [peasycap->field_fill]\ - [peasycap->field_page]; - pfield_buffer->pto = \ - pfield_buffer->pgo; - pfield_buffer->input = 0x08 | \ - (0x07 & peasycap->input); - if ((peasycap->field_buffer[peasycap->\ - field_fill][0]).\ - input != \ - pfield_buffer->input) - (peasycap->field_buffer\ - [peasycap->field_fill]\ - [0]).kount |= 0x1000; + if (FIELD_BUFFER_SIZE/PAGE_SIZE <= peasycap->field_page) { + SAM("ERROR: bad peasycap->field_page\n"); + return; } + pfield_buffer = &peasycap->field_buffer + [peasycap->field_fill][peasycap->field_page]; + while (more) { + pfield_buffer = &peasycap->field_buffer + [peasycap->field_fill] + [peasycap->field_page]; + if (PAGE_SIZE < (pfield_buffer->pto - + pfield_buffer->pgo)) { + SAM("ERROR: bad pfield_buffer->pto\n"); + return; + } + if (PAGE_SIZE == (pfield_buffer->pto - + pfield_buffer->pgo)) { + (peasycap->field_page)++; + if (FIELD_BUFFER_SIZE/PAGE_SIZE <= + peasycap->field_page) { + JOM(16, "wrapping peasycap->" + "field_page\n"); + peasycap->field_page = 0; + } + pfield_buffer = &peasycap-> + field_buffer + [peasycap->field_fill] + [peasycap->field_page]; + pfield_buffer->pto = pfield_buffer->pgo; + pfield_buffer->input = 0x08 | + (0x07 & peasycap->input); + if ((peasycap->field_buffer[peasycap-> + field_fill][0]). + input != + pfield_buffer->input) + (peasycap->field_buffer + [peasycap->field_fill] + [0]).kount |= 0x1000; + } - much = PAGE_SIZE - (int)(pfield_buffer->pto - \ + much = PAGE_SIZE - + (int)(pfield_buffer->pto - pfield_buffer->pgo); - if (much > more) - much = more; - memcpy(pfield_buffer->pto, pu, much); - pu += much; - (pfield_buffer->pto) += much; - more -= much; + if (much > more) + much = more; + memcpy(pfield_buffer->pto, pu, much); + pu += much; + (pfield_buffer->pto) += much; + more -= much; + } } } } } -} /*---------------------------------------------------------------------------*/ /* * RESUBMIT THIS URB, UNLESS A SEVERE PERSISTENT ERROR CONDITION EXISTS. @@ -3332,218 +2933,130 @@ if (purb->status) { * THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT. BEWARE. */ /*---------------------------------------------------------------------------*/ -if (VIDEO_ISOC_BUFFER_MANY <= peasycap->video_junk) { - SAM("easycap driver shutting down on condition green\n"); - peasycap->status = 1; - peasycap->video_eof = 1; - peasycap->video_junk = 0; - wake_up_interruptible(&peasycap->wq_video); + if (VIDEO_ISOC_BUFFER_MANY <= peasycap->video_junk) { + SAM("easycap driver shutting down on condition green\n"); + peasycap->status = 1; + peasycap->video_eof = 1; + peasycap->video_junk = 0; + wake_up_interruptible(&peasycap->wq_video); #if !defined(PERSEVERE) - peasycap->audio_eof = 1; - wake_up_interruptible(&peasycap->wq_audio); + peasycap->audio_eof = 1; + wake_up_interruptible(&peasycap->wq_audio); #endif /*PERSEVERE*/ - return; -} -if (peasycap->video_isoc_streaming) { - rc = usb_submit_urb(purb, GFP_ATOMIC); - if (0 != rc) { - switch (rc) { - case -ENOMEM: { - SAM("ENOMEM\n"); break; - } - case -ENODEV: { - SAM("ENODEV\n"); break; - } - case -ENXIO: { - SAM("ENXIO\n"); break; - } - case -EINVAL: { - SAM("EINVAL\n"); break; - } - case -EAGAIN: { - SAM("EAGAIN\n"); break; - } - case -EFBIG: { - SAM("EFBIG\n"); break; - } - case -EPIPE: { - SAM("EPIPE\n"); break; - } - case -EMSGSIZE: { - SAM("EMSGSIZE\n"); break; - } - case -ENOSPC: { - SAM("ENOSPC\n"); break; - } - default: { - SAM("0x%08X\n", rc); break; - } + return; + } + if (peasycap->video_isoc_streaming) { + rc = usb_submit_urb(purb, GFP_ATOMIC); + if (rc) { + SAM("%s: %d\n", strerror(rc), rc); + if (-ENODEV != rc) + SAM("ERROR: while %i=video_idle, " + "usb_submit_urb() " + "failed with rc:\n", + peasycap->video_idle); } - if (-ENODEV != rc) \ - SAM("ERROR: while %i=video_idle, " \ - "usb_submit_urb() " \ - "failed with rc:\n", \ - peasycap->video_idle); } + return; } -return; -} +static const struct file_operations easycap_fops = { + .owner = THIS_MODULE, + .open = easycap_open, + .unlocked_ioctl = easycap_unlocked_ioctl, + .poll = easycap_poll, + .mmap = easycap_mmap, + .llseek = no_llseek, +}; +static const struct usb_class_driver easycap_class = { + .name = "usb/easycap%d", + .fops = &easycap_fops, + .minor_base = USB_SKEL_MINOR_BASE, +}; +/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +static const struct v4l2_file_operations v4l2_fops = { + .owner = THIS_MODULE, + .open = easycap_open_noinode, + .unlocked_ioctl = easycap_unlocked_ioctl, + .poll = easycap_poll, + .mmap = easycap_mmap, +}; /*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* - * - * FIXME - * - * - * THIS FUNCTION ASSUMES THAT, ON EACH AND EVERY OCCASION THAT THE EasyCAP - * IS PHYSICALLY PLUGGED IN, INTERFACE 0 IS PROBED FIRST. - * IF THIS IS NOT TRUE, THERE IS THE POSSIBILITY OF AN Oops. - * - * THIS HAS NEVER BEEN A PROBLEM IN PRACTICE, BUT SOMETHING SEEMS WRONG HERE. + * WHEN THE EasyCAP IS PHYSICALLY PLUGGED IN, THIS FUNCTION IS CALLED THREE + * TIMES, ONCE FOR EACH OF THE THREE INTERFACES. BEWARE. */ /*---------------------------------------------------------------------------*/ -int -easycap_usb_probe(struct usb_interface *pusb_interface, \ - const struct usb_device_id *id) +static int easycap_usb_probe(struct usb_interface *pusb_interface, + const struct usb_device_id *pusb_device_id) { -struct usb_device *pusb_device, *pusb_device1; -struct usb_host_interface *pusb_host_interface; -struct usb_endpoint_descriptor *pepd; -struct usb_interface_descriptor *pusb_interface_descriptor; -struct usb_interface_assoc_descriptor *pusb_interface_assoc_descriptor; -struct urb *purb; -struct easycap *peasycap; -struct data_urb *pdata_urb; -size_t wMaxPacketSize; -int ISOCwMaxPacketSize; -int BULKwMaxPacketSize; -int INTwMaxPacketSize; -int CTRLwMaxPacketSize; -__u8 bEndpointAddress; -__u8 ISOCbEndpointAddress; -__u8 INTbEndpointAddress; -int isin, i, j, k, m, rc; -__u8 bInterfaceNumber; -__u8 bInterfaceClass; -__u8 bInterfaceSubClass; -void *pbuf; -int okalt[8], isokalt; -int okepn[8]; -int okmps[8]; -int maxpacketsize; -__u16 mask; -__s32 value; -struct easycap_format *peasycap_format; - -JOT(4, "\n"); - -if (!dongle_done) { - dongle_done = 1; - for (k = 0; k < DONGLE_MANY; k++) { - easycap_dongle[k].peasycap = (struct easycap *)NULL; - mutex_init(&easycap_dongle[k].mutex_video); - mutex_init(&easycap_dongle[k].mutex_audio); - } -} + struct usb_device *pusb_device; + struct usb_host_interface *pusb_host_interface; + struct usb_endpoint_descriptor *pepd; + struct usb_interface_descriptor *pusb_interface_descriptor; + struct urb *purb; + struct easycap *peasycap; + int ndong; + struct data_urb *pdata_urb; + size_t wMaxPacketSize; + int ISOCwMaxPacketSize; + int BULKwMaxPacketSize; + int INTwMaxPacketSize; + int CTRLwMaxPacketSize; + u8 bEndpointAddress; + u8 ISOCbEndpointAddress; + u8 INTbEndpointAddress; + int isin, i, j, k, m, rc; + u8 bInterfaceNumber; + u8 bInterfaceClass; + u8 bInterfaceSubClass; + void *pbuf; + int okalt[8], isokalt; + int okepn[8]; + int okmps[8]; + int maxpacketsize; + u16 mask; + s32 value; + struct easycap_format *peasycap_format; + int fmtidx; + struct inputset *inputset; + struct v4l2_device *pv4l2_device; -peasycap = (struct easycap *)NULL; - -if ((struct usb_interface *)NULL == pusb_interface) { - SAY("ERROR: pusb_interface is NULL\n"); - return -EFAULT; -} /*---------------------------------------------------------------------------*/ /* * GET POINTER TO STRUCTURE usb_device */ /*---------------------------------------------------------------------------*/ -pusb_device1 = container_of(pusb_interface->dev.parent, \ - struct usb_device, dev); -if ((struct usb_device *)NULL == pusb_device1) { - SAY("ERROR: pusb_device1 is NULL\n"); - return -EFAULT; -} -pusb_device = usb_get_dev(pusb_device1); -if ((struct usb_device *)NULL == pusb_device) { - SAY("ERROR: pusb_device is NULL\n"); - return -EFAULT; -} -if ((unsigned long int)pusb_device1 != (unsigned long int)pusb_device) { - JOT(4, "ERROR: pusb_device1 != pusb_device\n"); - return -EFAULT; -} - -JOT(4, "bNumConfigurations=%i\n", pusb_device->descriptor.bNumConfigurations); + pusb_device = interface_to_usbdev(pusb_interface); + JOT(4, "bNumConfigurations=%i\n", pusb_device->descriptor.bNumConfigurations); /*---------------------------------------------------------------------------*/ -pusb_host_interface = pusb_interface->cur_altsetting; -if (NULL == pusb_host_interface) { - SAY("ERROR: pusb_host_interface is NULL\n"); - return -EFAULT; -} -pusb_interface_descriptor = &(pusb_host_interface->desc); -if (NULL == pusb_interface_descriptor) { - SAY("ERROR: pusb_interface_descriptor is NULL\n"); - return -EFAULT; -} + pusb_host_interface = pusb_interface->cur_altsetting; + if (!pusb_host_interface) { + SAY("ERROR: pusb_host_interface is NULL\n"); + return -EFAULT; + } + pusb_interface_descriptor = &(pusb_host_interface->desc); + if (!pusb_interface_descriptor) { + SAY("ERROR: pusb_interface_descriptor is NULL\n"); + return -EFAULT; + } /*---------------------------------------------------------------------------*/ /* * GET PROPERTIES OF PROBED INTERFACE */ /*---------------------------------------------------------------------------*/ -bInterfaceNumber = pusb_interface_descriptor->bInterfaceNumber; -bInterfaceClass = pusb_interface_descriptor->bInterfaceClass; -bInterfaceSubClass = pusb_interface_descriptor->bInterfaceSubClass; + bInterfaceNumber = pusb_interface_descriptor->bInterfaceNumber; + bInterfaceClass = pusb_interface_descriptor->bInterfaceClass; + bInterfaceSubClass = pusb_interface_descriptor->bInterfaceSubClass; -JOT(4, "intf[%i]: pusb_interface->num_altsetting=%i\n", \ + JOT(4, "intf[%i]: num_altsetting=%i\n", bInterfaceNumber, pusb_interface->num_altsetting); -JOT(4, "intf[%i]: pusb_interface->cur_altsetting - " \ - "pusb_interface->altsetting=%li\n", bInterfaceNumber, \ - (long int)(pusb_interface->cur_altsetting - \ - pusb_interface->altsetting)); -switch (bInterfaceClass) { -case USB_CLASS_AUDIO: { - JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_AUDIO\n", \ - bInterfaceNumber, bInterfaceClass); break; - } -case USB_CLASS_VIDEO: { - JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_VIDEO\n", \ - bInterfaceNumber, bInterfaceClass); break; - } -case USB_CLASS_VENDOR_SPEC: { - JOT(4, "intf[%i]: bInterfaceClass=0x%02X=USB_CLASS_VENDOR_SPEC\n", \ - bInterfaceNumber, bInterfaceClass); break; - } -default: - break; -} -switch (bInterfaceSubClass) { -case 0x01: { - JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=AUDIOCONTROL\n", \ - bInterfaceNumber, bInterfaceSubClass); break; -} -case 0x02: { - JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=AUDIOSTREAMING\n", \ - bInterfaceNumber, bInterfaceSubClass); break; -} -case 0x03: { - JOT(4, "intf[%i]: bInterfaceSubClass=0x%02X=MIDISTREAMING\n", \ - bInterfaceNumber, bInterfaceSubClass); break; -} -default: - break; -} -/*---------------------------------------------------------------------------*/ -pusb_interface_assoc_descriptor = pusb_interface->intf_assoc; -if (NULL != pusb_interface_assoc_descriptor) { - JOT(4, "intf[%i]: bFirstInterface=0x%02X bInterfaceCount=0x%02X\n", \ - bInterfaceNumber, \ - pusb_interface_assoc_descriptor->bFirstInterface, \ - pusb_interface_assoc_descriptor->bInterfaceCount); -} else { -JOT(4, "intf[%i]: pusb_interface_assoc_descriptor is NULL\n", \ - bInterfaceNumber); -} + JOT(4, "intf[%i]: cur_altsetting - altsetting=%li\n", + bInterfaceNumber, + (long int)(pusb_interface->cur_altsetting - + pusb_interface->altsetting)); + JOT(4, "intf[%i]: bInterfaceClass=0x%02X bInterfaceSubClass=0x%02X\n", + bInterfaceNumber, bInterfaceClass, bInterfaceSubClass); /*---------------------------------------------------------------------------*/ /* * A NEW struct easycap IS ALWAYS ALLOCATED WHEN INTERFACE 0 IS PROBED. @@ -3553,788 +3066,785 @@ JOT(4, "intf[%i]: pusb_interface_assoc_descriptor is NULL\n", \ * * THE POINTER peasycap TO THE struct easycap IS REMEMBERED WHEN * INTERFACES 1 AND 2 ARE PROBED. - * - * IF TWO EasyCAPs ARE PLUGGED IN NEARLY SIMULTANEOUSLY THERE WILL - * BE TROUBLE. BEWARE. */ /*---------------------------------------------------------------------------*/ -if (0 == bInterfaceNumber) { - peasycap = kzalloc(sizeof(struct easycap), GFP_KERNEL); - if (NULL == peasycap) { - SAY("ERROR: Could not allocate peasycap\n"); - return -ENOMEM; - } - SAM("allocated 0x%08lX=peasycap\n", (unsigned long int) peasycap); -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if defined(EASYCAP_IS_VIDEODEV_CLIENT) - SAM("where 0x%08lX=&peasycap->video_device\n", \ - (unsigned long int) &peasycap->video_device); -#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) - SAM("and 0x%08lX=&peasycap->v4l2_device\n", \ - (unsigned long int) &peasycap->v4l2_device); -#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + if (0 == bInterfaceNumber) { + peasycap = kzalloc(sizeof(struct easycap), GFP_KERNEL); + if (!peasycap) { + SAY("ERROR: Could not allocate peasycap\n"); + return -ENOMEM; + } /*---------------------------------------------------------------------------*/ /* * PERFORM URGENT INTIALIZATIONS ... */ /*---------------------------------------------------------------------------*/ - strcpy(&peasycap->telltale[0], TELLTALE); - kref_init(&peasycap->kref); - JOM(8, "intf[%i]: after kref_init(..._video) " \ - "%i=peasycap->kref.refcount.counter\n", \ - bInterfaceNumber, peasycap->kref.refcount.counter); - - init_waitqueue_head(&peasycap->wq_video); - init_waitqueue_head(&peasycap->wq_audio); - - for (dongle_this = 0; dongle_this < DONGLE_MANY; dongle_this++) { - if (NULL == easycap_dongle[dongle_this].peasycap) { - if (0 == mutex_is_locked(&easycap_dongle\ - [dongle_this].mutex_video)) { - if (0 == mutex_is_locked(&easycap_dongle\ - [dongle_this].mutex_audio)) { - easycap_dongle\ - [dongle_this].peasycap = \ - peasycap; - JOM(8, "intf[%i]: peasycap-->easycap" \ - "_dongle[%i].peasycap\n", \ - bInterfaceNumber, dongle_this); + peasycap->minor = -1; + strcpy(&peasycap->telltale[0], TELLTALE); + kref_init(&peasycap->kref); + JOM(8, "intf[%i]: after kref_init(..._video) " + "%i=peasycap->kref.refcount.counter\n", + bInterfaceNumber, peasycap->kref.refcount.counter); + + /* module params */ + peasycap->gain = (s8)clamp(easycap_gain, 0, 31); + + init_waitqueue_head(&peasycap->wq_video); + init_waitqueue_head(&peasycap->wq_audio); + init_waitqueue_head(&peasycap->wq_trigger); + + if (mutex_lock_interruptible(&mutex_dongle)) { + SAY("ERROR: cannot down mutex_dongle\n"); + return -ERESTARTSYS; + } else { +/*---------------------------------------------------------------------------*/ + /* + * FOR INTERFACES 1 AND 2 THE POINTER peasycap WILL NEED TO + * TO BE THE SAME AS THAT ALLOCATED NOW FOR INTERFACE 0. + * + * NORMALLY ndong WILL NOT HAVE CHANGED SINCE INTERFACE 0 WAS + * PROBED, BUT THIS MAY NOT BE THE CASE IF, FOR EXAMPLE, TWO + * EASYCAPs ARE PLUGGED IN SIMULTANEOUSLY. + */ +/*---------------------------------------------------------------------------*/ + for (ndong = 0; ndong < DONGLE_MANY; ndong++) { + if ((!easycapdc60_dongle[ndong].peasycap) && + (!mutex_is_locked(&easycapdc60_dongle + [ndong].mutex_video)) && + (!mutex_is_locked(&easycapdc60_dongle + [ndong].mutex_audio))) { + easycapdc60_dongle[ndong].peasycap = peasycap; + peasycap->isdongle = ndong; + JOM(8, "intf[%i]: peasycap-->easycap" + "_dongle[%i].peasycap\n", + bInterfaceNumber, ndong); break; } } + if (DONGLE_MANY <= ndong) { + SAM("ERROR: too many dongles\n"); + mutex_unlock(&mutex_dongle); + return -ENOMEM; + } + mutex_unlock(&mutex_dongle); } - } - if (DONGLE_MANY <= dongle_this) { - SAM("ERROR: too many dongles\n"); - return -ENOMEM; - } - - peasycap->allocation_video_struct = sizeof(struct easycap); - peasycap->allocation_video_page = 0; - peasycap->allocation_video_urb = 0; - peasycap->allocation_audio_struct = 0; - peasycap->allocation_audio_page = 0; - peasycap->allocation_audio_urb = 0; + peasycap->allocation_video_struct = sizeof(struct easycap); + peasycap->allocation_video_page = 0; + peasycap->allocation_video_urb = 0; + peasycap->allocation_audio_struct = 0; + peasycap->allocation_audio_page = 0; + peasycap->allocation_audio_urb = 0; /*---------------------------------------------------------------------------*/ /* * ... AND FURTHER INITIALIZE THE STRUCTURE */ /*---------------------------------------------------------------------------*/ - peasycap->pusb_device = pusb_device; - peasycap->pusb_interface = pusb_interface; + peasycap->pusb_device = pusb_device; + peasycap->pusb_interface = pusb_interface; - peasycap->ilk = 0; - peasycap->microphone = false; + peasycap->ilk = 0; + peasycap->microphone = false; - peasycap->video_interface = -1; - peasycap->video_altsetting_on = -1; - peasycap->video_altsetting_off = -1; - peasycap->video_endpointnumber = -1; - peasycap->video_isoc_maxframesize = -1; - peasycap->video_isoc_buffer_size = -1; + peasycap->video_interface = -1; + peasycap->video_altsetting_on = -1; + peasycap->video_altsetting_off = -1; + peasycap->video_endpointnumber = -1; + peasycap->video_isoc_maxframesize = -1; + peasycap->video_isoc_buffer_size = -1; - peasycap->audio_interface = -1; - peasycap->audio_altsetting_on = -1; - peasycap->audio_altsetting_off = -1; - peasycap->audio_endpointnumber = -1; - peasycap->audio_isoc_maxframesize = -1; - peasycap->audio_isoc_buffer_size = -1; + peasycap->audio_interface = -1; + peasycap->audio_altsetting_on = -1; + peasycap->audio_altsetting_off = -1; + peasycap->audio_endpointnumber = -1; + peasycap->audio_isoc_maxframesize = -1; + peasycap->audio_isoc_buffer_size = -1; - peasycap->frame_buffer_many = FRAME_BUFFER_MANY; + peasycap->frame_buffer_many = FRAME_BUFFER_MANY; - for (k = 0; k < INPUT_MANY; k++) - peasycap->lost[k] = 0; - peasycap->skip = 0; - peasycap->skipped = 0; - peasycap->offerfields = 0; + for (k = 0; k < INPUT_MANY; k++) + peasycap->lost[k] = 0; + peasycap->skip = 0; + peasycap->skipped = 0; + peasycap->offerfields = 0; /*---------------------------------------------------------------------------*/ /* * DYNAMICALLY FILL IN THE AVAILABLE FORMATS ... */ /*---------------------------------------------------------------------------*/ - rc = fillin_formats(); - if (0 > rc) { - SAM("ERROR: fillin_formats() returned %i\n", rc); - return -EFAULT; - } - JOM(4, "%i formats available\n", rc); + rc = fillin_formats(); + if (0 > rc) { + SAM("ERROR: fillin_formats() rc = %i\n", rc); + return -EFAULT; + } + JOM(4, "%i formats available\n", rc); /*---------------------------------------------------------------------------*/ /* * ... AND POPULATE easycap.inputset[] */ /*---------------------------------------------------------------------------*/ - for (k = 0; k < INPUT_MANY; k++) { - peasycap->inputset[k].input_ok = 0; - peasycap->inputset[k].standard_offset_ok = 0; - peasycap->inputset[k].format_offset_ok = 0; - peasycap->inputset[k].brightness_ok = 0; - peasycap->inputset[k].contrast_ok = 0; - peasycap->inputset[k].saturation_ok = 0; - peasycap->inputset[k].hue_ok = 0; - } - if (true == peasycap->ntsc) { - i = 0; + /* FIXME: maybe we just use memset 0 */ + inputset = peasycap->inputset; + for (k = 0; k < INPUT_MANY; k++) { + inputset[k].input_ok = 0; + inputset[k].standard_offset_ok = 0; + inputset[k].format_offset_ok = 0; + inputset[k].brightness_ok = 0; + inputset[k].contrast_ok = 0; + inputset[k].saturation_ok = 0; + inputset[k].hue_ok = 0; + } + + fmtidx = peasycap->ntsc ? NTSC_M : PAL_BGHIN; m = 0; mask = 0; - while (0xFFFF != easycap_standard[i].mask) { - if (NTSC_M == easycap_standard[i].\ - v4l2_standard.index) { + for (i = 0; 0xFFFF != easycap_standard[i].mask; i++) { + if (fmtidx == easycap_standard[i].v4l2_standard.index) { m++; - for (k = 0; k < INPUT_MANY; k++) { - peasycap->inputset[k].\ - standard_offset = i; - } - mask = easycap_standard[i].mask; + for (k = 0; k < INPUT_MANY; k++) + inputset[k].standard_offset = i; + + mask = easycap_standard[i].mask; } - i++; } - } else { - i = 0; + + if (1 != m) { + SAM("ERROR: " + "inputset->standard_offset unpopulated, %i=m\n", m); + return -ENOENT; + } + + peasycap_format = &easycap_format[0]; m = 0; - mask = 0; - while (0xFFFF != easycap_standard[i].mask) { - if (PAL_BGHIN == easycap_standard[i].\ - v4l2_standard.index) { + for (i = 0; peasycap_format->v4l2_format.fmt.pix.width; i++) { + struct v4l2_pix_format *pix = + &peasycap_format->v4l2_format.fmt.pix; + if (((peasycap_format->mask & 0x0F) == (mask & 0x0F)) && + pix->field == V4L2_FIELD_NONE && + pix->pixelformat == V4L2_PIX_FMT_UYVY && + pix->width == 640 && pix->height == 480) { m++; - for (k = 0; k < INPUT_MANY; k++) { - peasycap->inputset[k].\ - standard_offset = i; - } - mask = easycap_standard[i].mask; + for (k = 0; k < INPUT_MANY; k++) + inputset[k].format_offset = i; + break; } - i++; + peasycap_format++; + } + if (1 != m) { + SAM("ERROR: inputset[]->format_offset unpopulated\n"); + return -ENOENT; } - } - - if (1 != m) { - SAM("MISTAKE: easycap.inputset[].standard_offset " \ - "unpopulated, %i=m\n", m); - return -ENOENT; - } - peasycap_format = &easycap_format[0]; - i = 0; - m = 0; - while (0 != peasycap_format->v4l2_format.fmt.pix.width) { - if (((peasycap_format->mask & 0x0F) == (mask & 0x0F)) && \ - (peasycap_format->\ - v4l2_format.fmt.pix.field == \ - V4L2_FIELD_NONE) && \ - (peasycap_format->\ - v4l2_format.fmt.pix.pixelformat == \ - V4L2_PIX_FMT_UYVY) && \ - (peasycap_format->\ - v4l2_format.fmt.pix.width == \ - 640) && \ - (peasycap_format->\ - v4l2_format.fmt.pix.height == 480)) { - m++; - for (k = 0; k < INPUT_MANY; k++) - peasycap->inputset[k].format_offset = i; - break; + m = 0; + for (i = 0; 0xFFFFFFFF != easycap_control[i].id; i++) { + value = easycap_control[i].default_value; + if (V4L2_CID_BRIGHTNESS == easycap_control[i].id) { + m++; + for (k = 0; k < INPUT_MANY; k++) + inputset[k].brightness = value; + } else if (V4L2_CID_CONTRAST == easycap_control[i].id) { + m++; + for (k = 0; k < INPUT_MANY; k++) + inputset[k].contrast = value; + } else if (V4L2_CID_SATURATION == easycap_control[i].id) { + m++; + for (k = 0; k < INPUT_MANY; k++) + inputset[k].saturation = value; + } else if (V4L2_CID_HUE == easycap_control[i].id) { + m++; + for (k = 0; k < INPUT_MANY; k++) + inputset[k].hue = value; + } } - peasycap_format++; - i++; - } - if (1 != m) { - SAM("MISTAKE: easycap.inputset[].format_offset unpopulated\n"); - return -ENOENT; - } - i = 0; - m = 0; - while (0xFFFFFFFF != easycap_control[i].id) { - value = easycap_control[i].default_value; - if (V4L2_CID_BRIGHTNESS == easycap_control[i].id) { - m++; - for (k = 0; k < INPUT_MANY; k++) - peasycap->inputset[k].brightness = value; - } else if (V4L2_CID_CONTRAST == easycap_control[i].id) { - m++; - for (k = 0; k < INPUT_MANY; k++) - peasycap->inputset[k].contrast = value; - } else if (V4L2_CID_SATURATION == easycap_control[i].id) { - m++; - for (k = 0; k < INPUT_MANY; k++) - peasycap->inputset[k].saturation = value; - } else if (V4L2_CID_HUE == easycap_control[i].id) { - m++; - for (k = 0; k < INPUT_MANY; k++) - peasycap->inputset[k].hue = value; + if (4 != m) { + SAM("ERROR: inputset[]->brightness underpopulated\n"); + return -ENOENT; } - i++; - } - if (4 != m) { - SAM("MISTAKE: easycap.inputset[].brightness,... " \ - "underpopulated\n"); - return -ENOENT; - } - for (k = 0; k < INPUT_MANY; k++) - peasycap->inputset[k].input = k; - JOM(4, "populated easycap.inputset[]\n"); - JOM(4, "finished initialization\n"); -} else { + for (k = 0; k < INPUT_MANY; k++) + inputset[k].input = k; + JOM(4, "populated inputset[]\n"); + JOM(4, "finished initialization\n"); + } else { /*---------------------------------------------------------------------------*/ - /* - * FOR INTERFACES 1 AND 2 THE POINTER peasycap IS OBTAINED BY ASSUMING - * THAT dongle_this HAS NOT CHANGED SINCE INTERFACE 0 WAS PROBED. IF - * THIS IS NOT THE CASE, FOR EXAMPLE WHEN TWO EASYCAPs ARE PLUGGED IN - * SIMULTANEOUSLY, THERE WILL BE SERIOUS TROUBLE. - */ +/* + * FIXME + * + * IDENTIFY THE APPROPRIATE POINTER peasycap FOR INTERFACES 1 AND 2. + * THE ADDRESS OF peasycap->pusb_device IS RELUCTANTLY USED FOR THIS PURPOSE. + */ /*---------------------------------------------------------------------------*/ - if ((0 > dongle_this) || (DONGLE_MANY <= dongle_this)) { - SAY("ERROR: bad dongle count\n"); - return -EFAULT; - } - peasycap = easycap_dongle[dongle_this].peasycap; - JOT(8, "intf[%i]: easycap_dongle[%i].peasycap-->peasycap\n", \ - bInterfaceNumber, dongle_this); - - if ((struct easycap *)NULL == peasycap) { - SAY("ERROR: peasycap is NULL when probing interface %i\n", \ - bInterfaceNumber); - return -EFAULT; + for (ndong = 0; ndong < DONGLE_MANY; ndong++) { + if (pusb_device == easycapdc60_dongle[ndong].peasycap-> + pusb_device) { + peasycap = easycapdc60_dongle[ndong].peasycap; + JOT(8, "intf[%i]: dongle[%i].peasycap\n", + bInterfaceNumber, ndong); + break; + } + } + if (DONGLE_MANY <= ndong) { + SAY("ERROR: peasycap is unknown when probing interface %i\n", + bInterfaceNumber); + return -ENODEV; + } + if (!peasycap) { + SAY("ERROR: peasycap is NULL when probing interface %i\n", + bInterfaceNumber); + return -ENODEV; + } +/*---------------------------------------------------------------------------*/ +/* + * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS + * BEEN WRITTEN BY THE CALL TO usb_set_intfdata() IN easycap_usb_probe(), + * REPLACING IT WITH A POINTER TO THE EMBEDDED v4l2_device STRUCTURE. + * TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED. +*/ +/*---------------------------------------------------------------------------*/ + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + pv4l2_device = usb_get_intfdata(pusb_interface); + if (!pv4l2_device) { + SAY("ERROR: pv4l2_device is NULL\n"); + return -ENODEV; + } + peasycap = (struct easycap *) + container_of(pv4l2_device, struct easycap, v4l2_device); + } } -} /*---------------------------------------------------------------------------*/ -if ((USB_CLASS_VIDEO == bInterfaceClass) || \ - (USB_CLASS_VENDOR_SPEC == bInterfaceClass)) { - if (-1 == peasycap->video_interface) { - peasycap->video_interface = bInterfaceNumber; - JOM(4, "setting peasycap->video_interface=%i\n", \ + if ((USB_CLASS_VIDEO == bInterfaceClass) || + (USB_CLASS_VENDOR_SPEC == bInterfaceClass)) { + if (-1 == peasycap->video_interface) { + peasycap->video_interface = bInterfaceNumber; + JOM(4, "setting peasycap->video_interface=%i\n", + peasycap->video_interface); + } else { + if (peasycap->video_interface != bInterfaceNumber) { + SAM("ERROR: attempting to reset " + "peasycap->video_interface\n"); + SAM("...... continuing with " + "%i=peasycap->video_interface\n", peasycap->video_interface); - } else { - if (peasycap->video_interface != bInterfaceNumber) { - SAM("ERROR: attempting to reset " \ - "peasycap->video_interface\n"); - SAM("...... continuing with " \ - "%i=peasycap->video_interface\n", \ - peasycap->video_interface); + } } - } -} else if ((USB_CLASS_AUDIO == bInterfaceClass) && \ - (0x02 == bInterfaceSubClass)) { - if (-1 == peasycap->audio_interface) { - peasycap->audio_interface = bInterfaceNumber; - JOM(4, "setting peasycap->audio_interface=%i\n", \ - peasycap->audio_interface); - } else { - if (peasycap->audio_interface != bInterfaceNumber) { - SAM("ERROR: attempting to reset " \ - "peasycap->audio_interface\n"); - SAM("...... continuing with " \ - "%i=peasycap->audio_interface\n", \ - peasycap->audio_interface); + } else if ((USB_CLASS_AUDIO == bInterfaceClass) && + (USB_SUBCLASS_AUDIOSTREAMING == bInterfaceSubClass)) { + if (-1 == peasycap->audio_interface) { + peasycap->audio_interface = bInterfaceNumber; + JOM(4, "setting peasycap->audio_interface=%i\n", + peasycap->audio_interface); + } else { + if (peasycap->audio_interface != bInterfaceNumber) { + SAM("ERROR: attempting to reset " + "peasycap->audio_interface\n"); + SAM("...... continuing with " + "%i=peasycap->audio_interface\n", + peasycap->audio_interface); + } } } -} /*---------------------------------------------------------------------------*/ /* * INVESTIGATE ALL ALTSETTINGS. * DONE IN DETAIL BECAUSE USB DEVICE 05e1:0408 HAS DISPARATE INCARNATIONS. */ /*---------------------------------------------------------------------------*/ -isokalt = 0; - -for (i = 0; i < pusb_interface->num_altsetting; i++) { - pusb_host_interface = &(pusb_interface->altsetting[i]); - if ((struct usb_host_interface *)NULL == pusb_host_interface) { - SAM("ERROR: pusb_host_interface is NULL\n"); - return -EFAULT; - } - pusb_interface_descriptor = &(pusb_host_interface->desc); - if ((struct usb_interface_descriptor *)NULL == \ - pusb_interface_descriptor) { - SAM("ERROR: pusb_interface_descriptor is NULL\n"); - return -EFAULT; - } + isokalt = 0; - JOM(4, "intf[%i]alt[%i]: desc.bDescriptorType=0x%02X\n", \ - bInterfaceNumber, i, pusb_interface_descriptor->bDescriptorType); - JOM(4, "intf[%i]alt[%i]: desc.bInterfaceNumber=0x%02X\n", \ - bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceNumber); - JOM(4, "intf[%i]alt[%i]: desc.bAlternateSetting=0x%02X\n", \ - bInterfaceNumber, i, pusb_interface_descriptor->bAlternateSetting); - JOM(4, "intf[%i]alt[%i]: desc.bNumEndpoints=0x%02X\n", \ - bInterfaceNumber, i, pusb_interface_descriptor->bNumEndpoints); - JOM(4, "intf[%i]alt[%i]: desc.bInterfaceClass=0x%02X\n", \ - bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceClass); - JOM(4, "intf[%i]alt[%i]: desc.bInterfaceSubClass=0x%02X\n", \ - bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceSubClass); - JOM(4, "intf[%i]alt[%i]: desc.bInterfaceProtocol=0x%02X\n", \ - bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceProtocol); - JOM(4, "intf[%i]alt[%i]: desc.iInterface=0x%02X\n", \ - bInterfaceNumber, i, pusb_interface_descriptor->iInterface); - - ISOCwMaxPacketSize = -1; - BULKwMaxPacketSize = -1; - INTwMaxPacketSize = -1; - CTRLwMaxPacketSize = -1; - ISOCbEndpointAddress = 0; - INTbEndpointAddress = 0; - - if (0 == pusb_interface_descriptor->bNumEndpoints) - JOM(4, "intf[%i]alt[%i] has no endpoints\n", \ - bInterfaceNumber, i); -/*---------------------------------------------------------------------------*/ - for (j = 0; j < pusb_interface_descriptor->bNumEndpoints; j++) { - pepd = &(pusb_host_interface->endpoint[j].desc); - if ((struct usb_endpoint_descriptor *)NULL == pepd) { - SAM("ERROR: pepd is NULL.\n"); - SAM("...... skipping\n"); - continue; + for (i = 0; i < pusb_interface->num_altsetting; i++) { + pusb_host_interface = &(pusb_interface->altsetting[i]); + if (!pusb_host_interface) { + SAM("ERROR: pusb_host_interface is NULL\n"); + return -EFAULT; } - wMaxPacketSize = le16_to_cpu(pepd->wMaxPacketSize); - bEndpointAddress = pepd->bEndpointAddress; - - JOM(4, "intf[%i]alt[%i]end[%i]: bEndpointAddress=0x%X\n", \ - bInterfaceNumber, i, j, \ - pepd->bEndpointAddress); - JOM(4, "intf[%i]alt[%i]end[%i]: bmAttributes=0x%X\n", \ - bInterfaceNumber, i, j, \ - pepd->bmAttributes); - JOM(4, "intf[%i]alt[%i]end[%i]: wMaxPacketSize=%i\n", \ - bInterfaceNumber, i, j, \ - pepd->wMaxPacketSize); - JOM(4, "intf[%i]alt[%i]end[%i]: bInterval=%i\n", - bInterfaceNumber, i, j, \ - pepd->bInterval); - - if (pepd->bEndpointAddress & USB_DIR_IN) { - JOM(4, "intf[%i]alt[%i]end[%i] is an IN endpoint\n",\ - bInterfaceNumber, i, j); - isin = 1; - } else { - JOM(4, "intf[%i]alt[%i]end[%i] is an OUT endpoint\n",\ - bInterfaceNumber, i, j); - SAM("ERROR: OUT endpoint unexpected\n"); - SAM("...... continuing\n"); - isin = 0; + pusb_interface_descriptor = &(pusb_host_interface->desc); + if (!pusb_interface_descriptor) { + SAM("ERROR: pusb_interface_descriptor is NULL\n"); + return -EFAULT; } - if ((pepd->bmAttributes & \ - USB_ENDPOINT_XFERTYPE_MASK) == \ - USB_ENDPOINT_XFER_ISOC) { - JOM(4, "intf[%i]alt[%i]end[%i] is an ISOC endpoint\n",\ - bInterfaceNumber, i, j); - if (isin) { - switch (bInterfaceClass) { - case USB_CLASS_VIDEO: - case USB_CLASS_VENDOR_SPEC: { - if (!peasycap) { - SAM("MISTAKE: " \ - "peasycap is NULL\n"); - return -EFAULT; - } - if (pepd->wMaxPacketSize) { - if (8 > isokalt) { - okalt[isokalt] = i; - JOM(4,\ - "%i=okalt[%i]\n", \ - okalt[isokalt], \ - isokalt); - okepn[isokalt] = \ - pepd->\ - bEndpointAddress & \ - 0x0F; - JOM(4,\ - "%i=okepn[%i]\n", \ - okepn[isokalt], \ - isokalt); - okmps[isokalt] = \ - le16_to_cpu(pepd->\ - wMaxPacketSize); - JOM(4,\ - "%i=okmps[%i]\n", \ - okmps[isokalt], \ - isokalt); - isokalt++; + + JOM(4, "intf[%i]alt[%i]: desc.bDescriptorType=0x%02X\n", + bInterfaceNumber, i, pusb_interface_descriptor->bDescriptorType); + JOM(4, "intf[%i]alt[%i]: desc.bInterfaceNumber=0x%02X\n", + bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceNumber); + JOM(4, "intf[%i]alt[%i]: desc.bAlternateSetting=0x%02X\n", + bInterfaceNumber, i, pusb_interface_descriptor->bAlternateSetting); + JOM(4, "intf[%i]alt[%i]: desc.bNumEndpoints=0x%02X\n", + bInterfaceNumber, i, pusb_interface_descriptor->bNumEndpoints); + JOM(4, "intf[%i]alt[%i]: desc.bInterfaceClass=0x%02X\n", + bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceClass); + JOM(4, "intf[%i]alt[%i]: desc.bInterfaceSubClass=0x%02X\n", + bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceSubClass); + JOM(4, "intf[%i]alt[%i]: desc.bInterfaceProtocol=0x%02X\n", + bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceProtocol); + JOM(4, "intf[%i]alt[%i]: desc.iInterface=0x%02X\n", + bInterfaceNumber, i, pusb_interface_descriptor->iInterface); + + ISOCwMaxPacketSize = -1; + BULKwMaxPacketSize = -1; + INTwMaxPacketSize = -1; + CTRLwMaxPacketSize = -1; + ISOCbEndpointAddress = 0; + INTbEndpointAddress = 0; + + if (0 == pusb_interface_descriptor->bNumEndpoints) + JOM(4, "intf[%i]alt[%i] has no endpoints\n", + bInterfaceNumber, i); +/*---------------------------------------------------------------------------*/ + for (j = 0; j < pusb_interface_descriptor->bNumEndpoints; j++) { + pepd = &(pusb_host_interface->endpoint[j].desc); + if (!pepd) { + SAM("ERROR: pepd is NULL.\n"); + SAM("...... skipping\n"); + continue; + } + wMaxPacketSize = le16_to_cpu(pepd->wMaxPacketSize); + bEndpointAddress = pepd->bEndpointAddress; + + JOM(4, "intf[%i]alt[%i]end[%i]: bEndpointAddress=0x%X\n", + bInterfaceNumber, i, j, + pepd->bEndpointAddress); + JOM(4, "intf[%i]alt[%i]end[%i]: bmAttributes=0x%X\n", + bInterfaceNumber, i, j, + pepd->bmAttributes); + JOM(4, "intf[%i]alt[%i]end[%i]: wMaxPacketSize=%i\n", + bInterfaceNumber, i, j, + pepd->wMaxPacketSize); + JOM(4, "intf[%i]alt[%i]end[%i]: bInterval=%i\n", + bInterfaceNumber, i, j, + pepd->bInterval); + + if (pepd->bEndpointAddress & USB_DIR_IN) { + JOM(4, "intf[%i]alt[%i]end[%i] is an IN endpoint\n", + bInterfaceNumber, i, j); + isin = 1; + } else { + JOM(4, "intf[%i]alt[%i]end[%i] is an OUT endpoint\n", + bInterfaceNumber, i, j); + SAM("ERROR: OUT endpoint unexpected\n"); + SAM("...... continuing\n"); + isin = 0; + } + if ((pepd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_ISOC) { + JOM(4, "intf[%i]alt[%i]end[%i] is an ISOC endpoint\n", + bInterfaceNumber, i, j); + if (isin) { + switch (bInterfaceClass) { + case USB_CLASS_VIDEO: + case USB_CLASS_VENDOR_SPEC: { + if (!peasycap) { + SAM("MISTAKE: " + "peasycap is NULL\n"); + return -EFAULT; } - } else { - if (-1 == peasycap->\ - video_altsetting_off) { - peasycap->\ - video_altsetting_off =\ - i; - JOM(4, "%i=video_" \ - "altsetting_off " \ - "<====\n", \ - peasycap->\ - video_altsetting_off); + if (pepd->wMaxPacketSize) { + if (8 > isokalt) { + okalt[isokalt] = i; + JOM(4, + "%i=okalt[%i]\n", + okalt[isokalt], + isokalt); + okepn[isokalt] = + pepd-> + bEndpointAddress & + 0x0F; + JOM(4, + "%i=okepn[%i]\n", + okepn[isokalt], + isokalt); + okmps[isokalt] = + le16_to_cpu(pepd-> + wMaxPacketSize); + JOM(4, + "%i=okmps[%i]\n", + okmps[isokalt], + isokalt); + isokalt++; + } } else { - SAM("ERROR: peasycap" \ - "->video_altsetting_" \ - "off already set\n"); - SAM("...... " \ - "continuing with " \ - "%i=peasycap->video_" \ - "altsetting_off\n", \ - peasycap->\ - video_altsetting_off); + if (-1 == peasycap-> + video_altsetting_off) { + peasycap-> + video_altsetting_off = + i; + JOM(4, "%i=video_" + "altsetting_off " + "<====\n", + peasycap-> + video_altsetting_off); + } else { + SAM("ERROR: peasycap" + "->video_altsetting_" + "off already set\n"); + SAM("...... " + "continuing with " + "%i=peasycap->video_" + "altsetting_off\n", + peasycap-> + video_altsetting_off); + } } - } - break; - } - case USB_CLASS_AUDIO: { - if (0x02 != bInterfaceSubClass) break; - if (!peasycap) { - SAM("MISTAKE: " \ - "peasycap is NULL\n"); - return -EFAULT; } - if (pepd->wMaxPacketSize) { - if (8 > isokalt) { - okalt[isokalt] = i ; - JOM(4,\ - "%i=okalt[%i]\n", \ - okalt[isokalt], \ - isokalt); - okepn[isokalt] = \ - pepd->\ - bEndpointAddress & \ - 0x0F; - JOM(4,\ - "%i=okepn[%i]\n", \ - okepn[isokalt], \ - isokalt); - okmps[isokalt] = \ - le16_to_cpu(pepd->\ - wMaxPacketSize); - JOM(4,\ - "%i=okmps[%i]\n",\ - okmps[isokalt], \ - isokalt); - isokalt++; + case USB_CLASS_AUDIO: { + if (bInterfaceSubClass != + USB_SUBCLASS_AUDIOSTREAMING) + break; + if (!peasycap) { + SAM("MISTAKE: " + "peasycap is NULL\n"); + return -EFAULT; } - } else { - if (-1 == peasycap->\ - audio_altsetting_off) { - peasycap->\ - audio_altsetting_off =\ - i; - JOM(4, "%i=audio_" \ - "altsetting_off " \ - "<====\n", \ - peasycap->\ - audio_altsetting_off); + if (pepd->wMaxPacketSize) { + if (8 > isokalt) { + okalt[isokalt] = i ; + JOM(4, + "%i=okalt[%i]\n", + okalt[isokalt], + isokalt); + okepn[isokalt] = + pepd-> + bEndpointAddress & + 0x0F; + JOM(4, + "%i=okepn[%i]\n", + okepn[isokalt], + isokalt); + okmps[isokalt] = + le16_to_cpu(pepd-> + wMaxPacketSize); + JOM(4, + "%i=okmps[%i]\n", + okmps[isokalt], + isokalt); + isokalt++; + } } else { - SAM("ERROR: peasycap" \ - "->audio_altsetting_" \ - "off already set\n"); - SAM("...... " \ - "continuing with " \ - "%i=peasycap->\ - audio_altsetting_" \ - "off\n", - peasycap->\ - audio_altsetting_off); + if (-1 == peasycap-> + audio_altsetting_off) { + peasycap-> + audio_altsetting_off = + i; + JOM(4, "%i=audio_" + "altsetting_off " + "<====\n", + peasycap-> + audio_altsetting_off); + } else { + SAM("ERROR: peasycap" + "->audio_altsetting_" + "off already set\n"); + SAM("...... " + "continuing with " + "%i=peasycap->" + "audio_altsetting_" + "off\n", + peasycap-> + audio_altsetting_off); + } } - } - break; - } - default: break; + } + default: + break; + } } + } else if ((pepd->bmAttributes & + USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_BULK) { + JOM(4, "intf[%i]alt[%i]end[%i] is a BULK endpoint\n", + bInterfaceNumber, i, j); + } else if ((pepd->bmAttributes & + USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_INT) { + JOM(4, "intf[%i]alt[%i]end[%i] is an INT endpoint\n", + bInterfaceNumber, i, j); + } else { + JOM(4, "intf[%i]alt[%i]end[%i] is a CTRL endpoint\n", + bInterfaceNumber, i, j); + } + if (0 == pepd->wMaxPacketSize) { + JOM(4, "intf[%i]alt[%i]end[%i] " + "has zero packet size\n", + bInterfaceNumber, i, j); } - } else if ((pepd->bmAttributes & \ - USB_ENDPOINT_XFERTYPE_MASK) ==\ - USB_ENDPOINT_XFER_BULK) { - JOM(4, "intf[%i]alt[%i]end[%i] is a BULK endpoint\n",\ - bInterfaceNumber, i, j); - } else if ((pepd->bmAttributes & \ - USB_ENDPOINT_XFERTYPE_MASK) ==\ - USB_ENDPOINT_XFER_INT) { - JOM(4, "intf[%i]alt[%i]end[%i] is an INT endpoint\n",\ - bInterfaceNumber, i, j); - } else { - JOM(4, "intf[%i]alt[%i]end[%i] is a CTRL endpoint\n",\ - bInterfaceNumber, i, j); - } - if (0 == pepd->wMaxPacketSize) { - JOM(4, "intf[%i]alt[%i]end[%i] " \ - "has zero packet size\n", \ - bInterfaceNumber, i, j); } } -} /*---------------------------------------------------------------------------*/ /* * PERFORM INITIALIZATION OF THE PROBED INTERFACE */ /*---------------------------------------------------------------------------*/ -JOM(4, "initialization begins for interface %i\n", \ - pusb_interface_descriptor->bInterfaceNumber); -switch (bInterfaceNumber) { + JOM(4, "initialization begins for interface %i\n", + pusb_interface_descriptor->bInterfaceNumber); + switch (bInterfaceNumber) { /*---------------------------------------------------------------------------*/ /* * INTERFACE 0 IS THE VIDEO INTERFACE */ /*---------------------------------------------------------------------------*/ -case 0: { - if (!peasycap) { - SAM("MISTAKE: peasycap is NULL\n"); - return -EFAULT; - } - if (!isokalt) { - SAM("ERROR: no viable video_altsetting_on\n"); - return -ENOENT; - } else { - peasycap->video_altsetting_on = okalt[isokalt - 1]; - JOM(4, "%i=video_altsetting_on <====\n", \ - peasycap->video_altsetting_on); - } + case 0: { + if (!peasycap) { + SAM("MISTAKE: peasycap is NULL\n"); + return -EFAULT; + } + if (!isokalt) { + SAM("ERROR: no viable video_altsetting_on\n"); + return -ENOENT; + } else { + peasycap->video_altsetting_on = okalt[isokalt - 1]; + JOM(4, "%i=video_altsetting_on <====\n", + peasycap->video_altsetting_on); + } /*---------------------------------------------------------------------------*/ /* * DECIDE THE VIDEO STREAMING PARAMETERS */ /*---------------------------------------------------------------------------*/ - peasycap->video_endpointnumber = okepn[isokalt - 1]; - JOM(4, "%i=video_endpointnumber\n", peasycap->video_endpointnumber); - maxpacketsize = okmps[isokalt - 1]; - if (USB_2_0_MAXPACKETSIZE > maxpacketsize) { - peasycap->video_isoc_maxframesize = maxpacketsize; - } else { - peasycap->video_isoc_maxframesize = \ - USB_2_0_MAXPACKETSIZE; - } - JOM(4, "%i=video_isoc_maxframesize\n", \ - peasycap->video_isoc_maxframesize); - if (0 >= peasycap->video_isoc_maxframesize) { - SAM("ERROR: bad video_isoc_maxframesize\n"); - SAM(" possibly because port is USB 1.1\n"); - return -ENOENT; - } - peasycap->video_isoc_framesperdesc = VIDEO_ISOC_FRAMESPERDESC; - JOM(4, "%i=video_isoc_framesperdesc\n", \ - peasycap->video_isoc_framesperdesc); - if (0 >= peasycap->video_isoc_framesperdesc) { - SAM("ERROR: bad video_isoc_framesperdesc\n"); - return -ENOENT; - } - peasycap->video_isoc_buffer_size = \ - peasycap->video_isoc_maxframesize * \ - peasycap->video_isoc_framesperdesc; - JOM(4, "%i=video_isoc_buffer_size\n", \ - peasycap->video_isoc_buffer_size); - if ((PAGE_SIZE << VIDEO_ISOC_ORDER) < \ - peasycap->video_isoc_buffer_size) { - SAM("MISTAKE: peasycap->video_isoc_buffer_size too big\n"); - return -EFAULT; - } + peasycap->video_endpointnumber = okepn[isokalt - 1]; + JOM(4, "%i=video_endpointnumber\n", peasycap->video_endpointnumber); + maxpacketsize = okmps[isokalt - 1]; + + peasycap->video_isoc_maxframesize = + min(maxpacketsize, USB_2_0_MAXPACKETSIZE); + if (0 >= peasycap->video_isoc_maxframesize) { + SAM("ERROR: bad video_isoc_maxframesize\n"); + SAM(" possibly because port is USB 1.1\n"); + return -ENOENT; + } + JOM(4, "%i=video_isoc_maxframesize\n", + peasycap->video_isoc_maxframesize); + + peasycap->video_isoc_framesperdesc = VIDEO_ISOC_FRAMESPERDESC; + JOM(4, "%i=video_isoc_framesperdesc\n", + peasycap->video_isoc_framesperdesc); + if (0 >= peasycap->video_isoc_framesperdesc) { + SAM("ERROR: bad video_isoc_framesperdesc\n"); + return -ENOENT; + } + peasycap->video_isoc_buffer_size = + peasycap->video_isoc_maxframesize * + peasycap->video_isoc_framesperdesc; + JOM(4, "%i=video_isoc_buffer_size\n", + peasycap->video_isoc_buffer_size); + if ((PAGE_SIZE << VIDEO_ISOC_ORDER) < + peasycap->video_isoc_buffer_size) { + SAM("MISTAKE: peasycap->video_isoc_buffer_size too big\n"); + return -EFAULT; + } /*---------------------------------------------------------------------------*/ - if (-1 == peasycap->video_interface) { - SAM("MISTAKE: video_interface is unset\n"); - return -EFAULT; - } - if (-1 == peasycap->video_altsetting_on) { - SAM("MISTAKE: video_altsetting_on is unset\n"); - return -EFAULT; - } - if (-1 == peasycap->video_altsetting_off) { - SAM("MISTAKE: video_interface_off is unset\n"); - return -EFAULT; - } - if (-1 == peasycap->video_endpointnumber) { - SAM("MISTAKE: video_endpointnumber is unset\n"); - return -EFAULT; - } - if (-1 == peasycap->video_isoc_maxframesize) { - SAM("MISTAKE: video_isoc_maxframesize is unset\n"); - return -EFAULT; - } - if (-1 == peasycap->video_isoc_buffer_size) { - SAM("MISTAKE: video_isoc_buffer_size is unset\n"); - return -EFAULT; - } + if (-1 == peasycap->video_interface) { + SAM("MISTAKE: video_interface is unset\n"); + return -EFAULT; + } + if (-1 == peasycap->video_altsetting_on) { + SAM("MISTAKE: video_altsetting_on is unset\n"); + return -EFAULT; + } + if (-1 == peasycap->video_altsetting_off) { + SAM("MISTAKE: video_interface_off is unset\n"); + return -EFAULT; + } + if (-1 == peasycap->video_endpointnumber) { + SAM("MISTAKE: video_endpointnumber is unset\n"); + return -EFAULT; + } + if (-1 == peasycap->video_isoc_maxframesize) { + SAM("MISTAKE: video_isoc_maxframesize is unset\n"); + return -EFAULT; + } + if (-1 == peasycap->video_isoc_buffer_size) { + SAM("MISTAKE: video_isoc_buffer_size is unset\n"); + return -EFAULT; + } /*---------------------------------------------------------------------------*/ /* * ALLOCATE MEMORY FOR VIDEO BUFFERS. LISTS MUST BE INITIALIZED FIRST. */ /*---------------------------------------------------------------------------*/ - INIT_LIST_HEAD(&(peasycap->urb_video_head)); - peasycap->purb_video_head = &(peasycap->urb_video_head); -/*---------------------------------------------------------------------------*/ - JOM(4, "allocating %i frame buffers of size %li\n", \ - FRAME_BUFFER_MANY, (long int)FRAME_BUFFER_SIZE); - JOM(4, ".... each scattered over %li pages\n", \ - FRAME_BUFFER_SIZE/PAGE_SIZE); - - for (k = 0; k < FRAME_BUFFER_MANY; k++) { - for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) { - if ((void *)NULL != peasycap->frame_buffer[k][m].pgo) - SAM("attempting to reallocate frame " \ - " buffers\n"); - else { - pbuf = (void *)__get_free_page(GFP_KERNEL); - if ((void *)NULL == pbuf) { - SAM("ERROR: Could not allocate frame "\ - "buffer %i page %i\n", k, m); - return -ENOMEM; - } else - peasycap->allocation_video_page += 1; - peasycap->frame_buffer[k][m].pgo = pbuf; + INIT_LIST_HEAD(&(peasycap->urb_video_head)); + peasycap->purb_video_head = &(peasycap->urb_video_head); +/*---------------------------------------------------------------------------*/ + JOM(4, "allocating %i frame buffers of size %li\n", + FRAME_BUFFER_MANY, (long int)FRAME_BUFFER_SIZE); + JOM(4, ".... each scattered over %li pages\n", + FRAME_BUFFER_SIZE/PAGE_SIZE); + + for (k = 0; k < FRAME_BUFFER_MANY; k++) { + for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) { + if (peasycap->frame_buffer[k][m].pgo) + SAM("attempting to reallocate frame " + " buffers\n"); + else { + pbuf = (void *)__get_free_page(GFP_KERNEL); + if (!pbuf) { + SAM("ERROR: Could not allocate frame " + "buffer %i page %i\n", k, m); + return -ENOMEM; + } else + peasycap->allocation_video_page += 1; + peasycap->frame_buffer[k][m].pgo = pbuf; + } + peasycap->frame_buffer[k][m].pto = + peasycap->frame_buffer[k][m].pgo; } - peasycap->frame_buffer[k][m].pto = \ - peasycap->frame_buffer[k][m].pgo; } - } - - peasycap->frame_fill = 0; - peasycap->frame_read = 0; - JOM(4, "allocation of frame buffers done: %i pages\n", k * \ - m); -/*---------------------------------------------------------------------------*/ - JOM(4, "allocating %i field buffers of size %li\n", \ - FIELD_BUFFER_MANY, (long int)FIELD_BUFFER_SIZE); - JOM(4, ".... each scattered over %li pages\n", \ - FIELD_BUFFER_SIZE/PAGE_SIZE); - for (k = 0; k < FIELD_BUFFER_MANY; k++) { - for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) { - if ((void *)NULL != peasycap->field_buffer[k][m].pgo) { - SAM("ERROR: attempting to reallocate " \ - "field buffers\n"); - } else { - pbuf = (void *) __get_free_page(GFP_KERNEL); - if ((void *)NULL == pbuf) { - SAM("ERROR: Could not allocate field" \ - " buffer %i page %i\n", k, m); - return -ENOMEM; + peasycap->frame_fill = 0; + peasycap->frame_read = 0; + JOM(4, "allocation of frame buffers done: %i pages\n", k * + m); +/*---------------------------------------------------------------------------*/ + JOM(4, "allocating %i field buffers of size %li\n", + FIELD_BUFFER_MANY, (long int)FIELD_BUFFER_SIZE); + JOM(4, ".... each scattered over %li pages\n", + FIELD_BUFFER_SIZE/PAGE_SIZE); + + for (k = 0; k < FIELD_BUFFER_MANY; k++) { + for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) { + if (peasycap->field_buffer[k][m].pgo) { + SAM("ERROR: attempting to reallocate " + "field buffers\n"); + } else { + pbuf = (void *) __get_free_page(GFP_KERNEL); + if (!pbuf) { + SAM("ERROR: Could not allocate field" + " buffer %i page %i\n", k, m); + return -ENOMEM; + } + else + peasycap->allocation_video_page += 1; + peasycap->field_buffer[k][m].pgo = pbuf; } - else - peasycap->allocation_video_page += 1; - peasycap->field_buffer[k][m].pgo = pbuf; - } - peasycap->field_buffer[k][m].pto = \ - peasycap->field_buffer[k][m].pgo; + peasycap->field_buffer[k][m].pto = + peasycap->field_buffer[k][m].pgo; + } + peasycap->field_buffer[k][0].kount = 0x0200; } - peasycap->field_buffer[k][0].kount = 0x0200; - } - peasycap->field_fill = 0; - peasycap->field_page = 0; - peasycap->field_read = 0; - JOM(4, "allocation of field buffers done: %i pages\n", k * \ - m); -/*---------------------------------------------------------------------------*/ - JOM(4, "allocating %i isoc video buffers of size %i\n", \ - VIDEO_ISOC_BUFFER_MANY, \ - peasycap->video_isoc_buffer_size); - JOM(4, ".... each occupying contiguous memory pages\n"); - - for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { - pbuf = (void *)__get_free_pages(GFP_KERNEL, VIDEO_ISOC_ORDER); - if (NULL == pbuf) { - SAM("ERROR: Could not allocate isoc video buffer " \ - "%i\n", k); - return -ENOMEM; - } else - peasycap->allocation_video_page += \ - ((unsigned int)(0x01 << VIDEO_ISOC_ORDER)); + peasycap->field_fill = 0; + peasycap->field_page = 0; + peasycap->field_read = 0; + JOM(4, "allocation of field buffers done: %i pages\n", k * + m); +/*---------------------------------------------------------------------------*/ + JOM(4, "allocating %i isoc video buffers of size %i\n", + VIDEO_ISOC_BUFFER_MANY, + peasycap->video_isoc_buffer_size); + JOM(4, ".... each occupying contiguous memory pages\n"); + + for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { + pbuf = (void *)__get_free_pages(GFP_KERNEL, + VIDEO_ISOC_ORDER); + if (!pbuf) { + SAM("ERROR: Could not allocate isoc video buffer " + "%i\n", k); + return -ENOMEM; + } else + peasycap->allocation_video_page += + BIT(VIDEO_ISOC_ORDER); - peasycap->video_isoc_buffer[k].pgo = pbuf; - peasycap->video_isoc_buffer[k].pto = pbuf + \ - peasycap->video_isoc_buffer_size; - peasycap->video_isoc_buffer[k].kount = k; - } - JOM(4, "allocation of isoc video buffers done: %i pages\n", \ - k * (0x01 << VIDEO_ISOC_ORDER)); + peasycap->video_isoc_buffer[k].pgo = pbuf; + peasycap->video_isoc_buffer[k].pto = + pbuf + peasycap->video_isoc_buffer_size; + peasycap->video_isoc_buffer[k].kount = k; + } + JOM(4, "allocation of isoc video buffers done: %i pages\n", + k * (0x01 << VIDEO_ISOC_ORDER)); /*---------------------------------------------------------------------------*/ /* * ALLOCATE AND INITIALIZE MULTIPLE struct urb ... */ /*---------------------------------------------------------------------------*/ - JOM(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY); - JOM(4, "using %i=peasycap->video_isoc_framesperdesc\n", \ - peasycap->video_isoc_framesperdesc); - JOM(4, "using %i=peasycap->video_isoc_maxframesize\n", \ - peasycap->video_isoc_maxframesize); - JOM(4, "using %i=peasycap->video_isoc_buffer_sizen", \ - peasycap->video_isoc_buffer_size); - - for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { - purb = usb_alloc_urb(peasycap->video_isoc_framesperdesc, \ - GFP_KERNEL); - if (NULL == purb) { - SAM("ERROR: usb_alloc_urb returned NULL for buffer " \ - "%i\n", k); - return -ENOMEM; - } else - peasycap->allocation_video_urb += 1; + JOM(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY); + JOM(4, "using %i=peasycap->video_isoc_framesperdesc\n", + peasycap->video_isoc_framesperdesc); + JOM(4, "using %i=peasycap->video_isoc_maxframesize\n", + peasycap->video_isoc_maxframesize); + JOM(4, "using %i=peasycap->video_isoc_buffer_sizen", + peasycap->video_isoc_buffer_size); + + for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { + purb = usb_alloc_urb(peasycap->video_isoc_framesperdesc, + GFP_KERNEL); + if (!purb) { + SAM("ERROR: usb_alloc_urb returned NULL for buffer " + "%i\n", k); + return -ENOMEM; + } else + peasycap->allocation_video_urb += 1; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL); - if (NULL == pdata_urb) { - SAM("ERROR: Could not allocate struct data_urb.\n"); - return -ENOMEM; - } else - peasycap->allocation_video_struct += \ - sizeof(struct data_urb); + pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL); + if (!pdata_urb) { + SAM("ERROR: Could not allocate struct data_urb.\n"); + return -ENOMEM; + } else + peasycap->allocation_video_struct += + sizeof(struct data_urb); - pdata_urb->purb = purb; - pdata_urb->isbuf = k; - pdata_urb->length = 0; - list_add_tail(&(pdata_urb->list_head), \ - peasycap->purb_video_head); + pdata_urb->purb = purb; + pdata_urb->isbuf = k; + pdata_urb->length = 0; + list_add_tail(&(pdata_urb->list_head), + peasycap->purb_video_head); /*---------------------------------------------------------------------------*/ /* * ... AND INITIALIZE THEM */ /*---------------------------------------------------------------------------*/ - if (!k) { - JOM(4, "initializing video urbs thus:\n"); - JOM(4, " purb->interval = 1;\n"); - JOM(4, " purb->dev = peasycap->pusb_device;\n"); - JOM(4, " purb->pipe = usb_rcvisocpipe" \ - "(peasycap->pusb_device,%i);\n", \ - peasycap->video_endpointnumber); - JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n"); - JOM(4, " purb->transfer_buffer = peasycap->" \ - "video_isoc_buffer[.].pgo;\n"); - JOM(4, " purb->transfer_buffer_length = %i;\n", \ - peasycap->video_isoc_buffer_size); - JOM(4, " purb->complete = easycap_complete;\n"); - JOM(4, " purb->context = peasycap;\n"); - JOM(4, " purb->start_frame = 0;\n"); - JOM(4, " purb->number_of_packets = %i;\n", \ - peasycap->video_isoc_framesperdesc); - JOM(4, " for (j = 0; j < %i; j++)\n", \ - peasycap->video_isoc_framesperdesc); - JOM(4, " {\n"); - JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n",\ - peasycap->video_isoc_maxframesize); - JOM(4, " purb->iso_frame_desc[j].length = %i;\n", \ - peasycap->video_isoc_maxframesize); - JOM(4, " }\n"); - } + if (!k) { + JOM(4, "initializing video urbs thus:\n"); + JOM(4, " purb->interval = 1;\n"); + JOM(4, " purb->dev = peasycap->pusb_device;\n"); + JOM(4, " purb->pipe = usb_rcvisocpipe" + "(peasycap->pusb_device,%i);\n", + peasycap->video_endpointnumber); + JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n"); + JOM(4, " purb->transfer_buffer = peasycap->" + "video_isoc_buffer[.].pgo;\n"); + JOM(4, " purb->transfer_buffer_length = %i;\n", + peasycap->video_isoc_buffer_size); + JOM(4, " purb->complete = easycap_complete;\n"); + JOM(4, " purb->context = peasycap;\n"); + JOM(4, " purb->start_frame = 0;\n"); + JOM(4, " purb->number_of_packets = %i;\n", + peasycap->video_isoc_framesperdesc); + JOM(4, " for (j = 0; j < %i; j++)\n", + peasycap->video_isoc_framesperdesc); + JOM(4, " {\n"); + JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n", + peasycap->video_isoc_maxframesize); + JOM(4, " purb->iso_frame_desc[j].length = %i;\n", + peasycap->video_isoc_maxframesize); + JOM(4, " }\n"); + } - purb->interval = 1; - purb->dev = peasycap->pusb_device; - purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, \ - peasycap->video_endpointnumber); - purb->transfer_flags = URB_ISO_ASAP; - purb->transfer_buffer = peasycap->video_isoc_buffer[k].pgo; - purb->transfer_buffer_length = \ - peasycap->video_isoc_buffer_size; - purb->complete = easycap_complete; - purb->context = peasycap; - purb->start_frame = 0; - purb->number_of_packets = peasycap->video_isoc_framesperdesc; - for (j = 0; j < peasycap->video_isoc_framesperdesc; j++) { - purb->iso_frame_desc[j].offset = j * \ - peasycap->video_isoc_maxframesize; - purb->iso_frame_desc[j].length = \ - peasycap->video_isoc_maxframesize; + purb->interval = 1; + purb->dev = peasycap->pusb_device; + purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, + peasycap->video_endpointnumber); + purb->transfer_flags = URB_ISO_ASAP; + purb->transfer_buffer = peasycap->video_isoc_buffer[k].pgo; + purb->transfer_buffer_length = + peasycap->video_isoc_buffer_size; + purb->complete = easycap_complete; + purb->context = peasycap; + purb->start_frame = 0; + purb->number_of_packets = peasycap->video_isoc_framesperdesc; + for (j = 0; j < peasycap->video_isoc_framesperdesc; j++) { + purb->iso_frame_desc[j].offset = j * + peasycap->video_isoc_maxframesize; + purb->iso_frame_desc[j].length = + peasycap->video_isoc_maxframesize; + } } - } - JOM(4, "allocation of %i struct urb done.\n", k); + JOM(4, "allocation of %i struct urb done.\n", k); /*--------------------------------------------------------------------------*/ /* * SAVE POINTER peasycap IN THIS INTERFACE. */ /*--------------------------------------------------------------------------*/ - usb_set_intfdata(pusb_interface, peasycap); + usb_set_intfdata(pusb_interface, peasycap); /*---------------------------------------------------------------------------*/ /* * IT IS ESSENTIAL TO INITIALIZE THE HARDWARE BEFORE, RATHER THAN AFTER, @@ -4343,448 +3853,435 @@ case 0: { * BEWARE. */ /*---------------------------------------------------------------------------*/ -#if defined(PREFER_NTSC) - peasycap->ntsc = true; - JOM(8, "defaulting initially to NTSC\n"); -#else - peasycap->ntsc = false; - JOM(8, "defaulting initially to PAL\n"); -#endif /*PREFER_NTSC*/ - rc = reset(peasycap); - if (0 != rc) { - SAM("ERROR: reset() returned %i\n", rc); - return -EFAULT; - } + peasycap->ntsc = easycap_ntsc; + JOM(8, "defaulting initially to %s\n", + easycap_ntsc ? "NTSC" : "PAL"); + rc = reset(peasycap); + if (rc) { + SAM("ERROR: reset() rc = %i\n", rc); + return -EFAULT; + } /*--------------------------------------------------------------------------*/ /* * THE VIDEO DEVICE CAN BE REGISTERED NOW, AS IT IS READY. */ /*--------------------------------------------------------------------------*/ -#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) - if (0 != (usb_register_dev(pusb_interface, &easycap_class))) { - err("Not able to get a minor for this device"); - usb_set_intfdata(pusb_interface, NULL); - return -ENODEV; - } else { - (peasycap->registered_video)++; - SAM("easycap attached to minor #%d\n", pusb_interface->minor); - break; - } -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#else -#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) - if (0 != (v4l2_device_register(&(pusb_interface->dev), \ - &(peasycap->v4l2_device)))) { - SAM("v4l2_device_register() failed\n"); - return -ENODEV; - } else { - JOM(4, "registered device instance: %s\n", \ - &(peasycap->v4l2_device.name[0])); - } + if (0 != (v4l2_device_register(&(pusb_interface->dev), + &(peasycap->v4l2_device)))) { + SAM("v4l2_device_register() failed\n"); + return -ENODEV; + } else { + JOM(4, "registered device instance: %s\n", + &(peasycap->v4l2_device.name[0])); + } /*---------------------------------------------------------------------------*/ /* - * FIXME + * FIXME * * * THIS IS BELIEVED TO BE HARMLESS, BUT MAY WELL BE UNNECESSARY OR WRONG: */ /*---------------------------------------------------------------------------*/ - peasycap->video_device.v4l2_dev = (struct v4l2_device *)NULL; + peasycap->video_device.v4l2_dev = NULL; /*---------------------------------------------------------------------------*/ -#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ - strcpy(&peasycap->video_device.name[0], "easycapdc60"); -#if defined(EASYCAP_NEEDS_V4L2_FOPS) - peasycap->video_device.fops = &v4l2_fops; -#else - peasycap->video_device.fops = &easycap_fops; -#endif /*EASYCAP_NEEDS_V4L2_FOPS*/ - peasycap->video_device.minor = -1; - peasycap->video_device.release = (void *)(&videodev_release); + strcpy(&peasycap->video_device.name[0], "easycapdc60"); + peasycap->video_device.fops = &v4l2_fops; + peasycap->video_device.minor = -1; + peasycap->video_device.release = (void *)(&videodev_release); - video_set_drvdata(&(peasycap->video_device), (void *)peasycap); + video_set_drvdata(&(peasycap->video_device), (void *)peasycap); - if (0 != (video_register_device(&(peasycap->video_device), \ - VFL_TYPE_GRABBER, -1))) { - err("Not able to register with videodev"); - videodev_release(&(peasycap->video_device)); - return -ENODEV; - } else { - (peasycap->registered_video)++; - SAM("registered with videodev: %i=minor\n", \ - peasycap->video_device.minor); - } -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ + if (0 != (video_register_device(&(peasycap->video_device), + VFL_TYPE_GRABBER, -1))) { + err("Not able to register with videodev"); + videodev_release(&(peasycap->video_device)); + return -ENODEV; + } else { + (peasycap->registered_video)++; + SAM("registered with videodev: %i=minor\n", + peasycap->video_device.minor); + peasycap->minor = peasycap->video_device.minor; + } /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - break; -} + + break; + } /*--------------------------------------------------------------------------*/ /* * INTERFACE 1 IS THE AUDIO CONTROL INTERFACE * INTERFACE 2 IS THE AUDIO STREAMING INTERFACE */ /*--------------------------------------------------------------------------*/ -case 1: { - if (!peasycap) { - SAM("ERROR: peasycap is NULL\n"); - return -EFAULT; - } + case 1: { + if (!peasycap) { + SAM("MISTAKE: peasycap is NULL\n"); + return -EFAULT; + } /*--------------------------------------------------------------------------*/ /* * SAVE POINTER peasycap IN INTERFACE 1 */ /*--------------------------------------------------------------------------*/ - usb_set_intfdata(pusb_interface, peasycap); - JOM(4, "no initialization required for interface %i\n", \ - pusb_interface_descriptor->bInterfaceNumber); - break; -} -/*--------------------------------------------------------------------------*/ -case 2: { - if (!peasycap) { - SAM("MISTAKE: peasycap is NULL\n"); - return -EFAULT; - } - if (!isokalt) { - SAM("ERROR: no viable audio_altsetting_on\n"); - return -ENOENT; - } else { - peasycap->audio_altsetting_on = okalt[isokalt - 1]; - JOM(4, "%i=audio_altsetting_on <====\n", \ - peasycap->audio_altsetting_on); - } - - peasycap->audio_endpointnumber = okepn[isokalt - 1]; - JOM(4, "%i=audio_endpointnumber\n", peasycap->audio_endpointnumber); - - peasycap->audio_isoc_maxframesize = okmps[isokalt - 1]; - JOM(4, "%i=audio_isoc_maxframesize\n", \ - peasycap->audio_isoc_maxframesize); - if (0 >= peasycap->audio_isoc_maxframesize) { - SAM("ERROR: bad audio_isoc_maxframesize\n"); - return -ENOENT; - } - if (9 == peasycap->audio_isoc_maxframesize) { - peasycap->ilk |= 0x02; - SAM("hardware is FOUR-CVBS\n"); - peasycap->microphone = true; - peasycap->audio_pages_per_fragment = 4; - } else if (256 == peasycap->audio_isoc_maxframesize) { - peasycap->ilk &= ~0x02; - SAM("hardware is CVBS+S-VIDEO\n"); - peasycap->microphone = false; - peasycap->audio_pages_per_fragment = 4; - } else { - SAM("hardware is unidentified:\n"); - SAM("%i=audio_isoc_maxframesize\n", \ - peasycap->audio_isoc_maxframesize); - return -ENOENT; + usb_set_intfdata(pusb_interface, peasycap); + JOM(4, "no initialization required for interface %i\n", + pusb_interface_descriptor->bInterfaceNumber); + break; } +/*--------------------------------------------------------------------------*/ + case 2: { + if (!peasycap) { + SAM("MISTAKE: peasycap is NULL\n"); + return -EFAULT; + } + if (!isokalt) { + SAM("ERROR: no viable audio_altsetting_on\n"); + return -ENOENT; + } else { + peasycap->audio_altsetting_on = okalt[isokalt - 1]; + JOM(4, "%i=audio_altsetting_on <====\n", + peasycap->audio_altsetting_on); + } - peasycap->audio_bytes_per_fragment = \ - peasycap->audio_pages_per_fragment * \ - PAGE_SIZE ; - peasycap->audio_buffer_page_many = (AUDIO_FRAGMENT_MANY * \ - peasycap->audio_pages_per_fragment); - - JOM(4, "%6i=AUDIO_FRAGMENT_MANY\n", AUDIO_FRAGMENT_MANY); - JOM(4, "%6i=audio_pages_per_fragment\n", \ - peasycap->audio_pages_per_fragment); - JOM(4, "%6i=audio_bytes_per_fragment\n", \ - peasycap->audio_bytes_per_fragment); - JOM(4, "%6i=audio_buffer_page_many\n", \ - peasycap->audio_buffer_page_many); + peasycap->audio_endpointnumber = okepn[isokalt - 1]; + JOM(4, "%i=audio_endpointnumber\n", peasycap->audio_endpointnumber); - peasycap->audio_isoc_framesperdesc = 128; + peasycap->audio_isoc_maxframesize = okmps[isokalt - 1]; + JOM(4, "%i=audio_isoc_maxframesize\n", + peasycap->audio_isoc_maxframesize); + if (0 >= peasycap->audio_isoc_maxframesize) { + SAM("ERROR: bad audio_isoc_maxframesize\n"); + return -ENOENT; + } + if (9 == peasycap->audio_isoc_maxframesize) { + peasycap->ilk |= 0x02; + SAM("audio hardware is microphone\n"); + peasycap->microphone = true; + peasycap->audio_pages_per_fragment = + PAGES_PER_AUDIO_FRAGMENT; + } else if (256 == peasycap->audio_isoc_maxframesize) { + peasycap->ilk &= ~0x02; + SAM("audio hardware is AC'97\n"); + peasycap->microphone = false; + peasycap->audio_pages_per_fragment = + PAGES_PER_AUDIO_FRAGMENT; + } else { + SAM("hardware is unidentified:\n"); + SAM("%i=audio_isoc_maxframesize\n", + peasycap->audio_isoc_maxframesize); + return -ENOENT; + } - JOM(4, "%i=audio_isoc_framesperdesc\n", \ - peasycap->audio_isoc_framesperdesc); - if (0 >= peasycap->audio_isoc_framesperdesc) { - SAM("ERROR: bad audio_isoc_framesperdesc\n"); - return -ENOENT; - } + peasycap->audio_bytes_per_fragment = + peasycap->audio_pages_per_fragment * PAGE_SIZE; + peasycap->audio_buffer_page_many = (AUDIO_FRAGMENT_MANY * + peasycap->audio_pages_per_fragment); + + JOM(4, "%6i=AUDIO_FRAGMENT_MANY\n", AUDIO_FRAGMENT_MANY); + JOM(4, "%6i=audio_pages_per_fragment\n", + peasycap->audio_pages_per_fragment); + JOM(4, "%6i=audio_bytes_per_fragment\n", + peasycap->audio_bytes_per_fragment); + JOM(4, "%6i=audio_buffer_page_many\n", + peasycap->audio_buffer_page_many); + + peasycap->audio_isoc_framesperdesc = AUDIO_ISOC_FRAMESPERDESC; + + JOM(4, "%i=audio_isoc_framesperdesc\n", + peasycap->audio_isoc_framesperdesc); + if (0 >= peasycap->audio_isoc_framesperdesc) { + SAM("ERROR: bad audio_isoc_framesperdesc\n"); + return -ENOENT; + } - peasycap->audio_isoc_buffer_size = \ - peasycap->audio_isoc_maxframesize * \ - peasycap->audio_isoc_framesperdesc; - JOM(4, "%i=audio_isoc_buffer_size\n", \ - peasycap->audio_isoc_buffer_size); - if (AUDIO_ISOC_BUFFER_SIZE < peasycap->audio_isoc_buffer_size) { - SAM("MISTAKE: audio_isoc_buffer_size bigger " - "than %li=AUDIO_ISOC_BUFFER_SIZE\n", \ - AUDIO_ISOC_BUFFER_SIZE); - return -EFAULT; - } - if (-1 == peasycap->audio_interface) { - SAM("MISTAKE: audio_interface is unset\n"); - return -EFAULT; - } - if (-1 == peasycap->audio_altsetting_on) { - SAM("MISTAKE: audio_altsetting_on is unset\n"); - return -EFAULT; - } - if (-1 == peasycap->audio_altsetting_off) { - SAM("MISTAKE: audio_interface_off is unset\n"); - return -EFAULT; - } - if (-1 == peasycap->audio_endpointnumber) { - SAM("MISTAKE: audio_endpointnumber is unset\n"); - return -EFAULT; - } - if (-1 == peasycap->audio_isoc_maxframesize) { - SAM("MISTAKE: audio_isoc_maxframesize is unset\n"); - return -EFAULT; - } - if (-1 == peasycap->audio_isoc_buffer_size) { - SAM("MISTAKE: audio_isoc_buffer_size is unset\n"); - return -EFAULT; - } + peasycap->audio_isoc_buffer_size = + peasycap->audio_isoc_maxframesize * + peasycap->audio_isoc_framesperdesc; + JOM(4, "%i=audio_isoc_buffer_size\n", + peasycap->audio_isoc_buffer_size); + if (AUDIO_ISOC_BUFFER_SIZE < peasycap->audio_isoc_buffer_size) { + SAM("MISTAKE: audio_isoc_buffer_size bigger " + "than %li=AUDIO_ISOC_BUFFER_SIZE\n", + AUDIO_ISOC_BUFFER_SIZE); + return -EFAULT; + } + if (-1 == peasycap->audio_interface) { + SAM("MISTAKE: audio_interface is unset\n"); + return -EFAULT; + } + if (-1 == peasycap->audio_altsetting_on) { + SAM("MISTAKE: audio_altsetting_on is unset\n"); + return -EFAULT; + } + if (-1 == peasycap->audio_altsetting_off) { + SAM("MISTAKE: audio_interface_off is unset\n"); + return -EFAULT; + } + if (-1 == peasycap->audio_endpointnumber) { + SAM("MISTAKE: audio_endpointnumber is unset\n"); + return -EFAULT; + } + if (-1 == peasycap->audio_isoc_maxframesize) { + SAM("MISTAKE: audio_isoc_maxframesize is unset\n"); + return -EFAULT; + } + if (-1 == peasycap->audio_isoc_buffer_size) { + SAM("MISTAKE: audio_isoc_buffer_size is unset\n"); + return -EFAULT; + } /*---------------------------------------------------------------------------*/ /* * ALLOCATE MEMORY FOR AUDIO BUFFERS. LISTS MUST BE INITIALIZED FIRST. */ /*---------------------------------------------------------------------------*/ - INIT_LIST_HEAD(&(peasycap->urb_audio_head)); - peasycap->purb_audio_head = &(peasycap->urb_audio_head); + INIT_LIST_HEAD(&(peasycap->urb_audio_head)); + peasycap->purb_audio_head = &(peasycap->urb_audio_head); - JOM(4, "allocating an audio buffer\n"); - JOM(4, ".... scattered over %i pages\n", \ - peasycap->audio_buffer_page_many); +#ifdef CONFIG_EASYCAP_OSS + JOM(4, "allocating an audio buffer\n"); + JOM(4, ".... scattered over %i pages\n", + peasycap->audio_buffer_page_many); - for (k = 0; k < peasycap->audio_buffer_page_many; k++) { - if ((void *)NULL != peasycap->audio_buffer[k].pgo) { - SAM("ERROR: attempting to reallocate audio buffers\n"); - } else { - pbuf = (void *) __get_free_page(GFP_KERNEL); - if ((void *)NULL == pbuf) { - SAM("ERROR: Could not allocate audio " \ - "buffer page %i\n", k); - return -ENOMEM; - } else - peasycap->allocation_audio_page += 1; + for (k = 0; k < peasycap->audio_buffer_page_many; k++) { + if (peasycap->audio_buffer[k].pgo) { + SAM("ERROR: attempting to reallocate audio buffers\n"); + } else { + pbuf = (void *) __get_free_page(GFP_KERNEL); + if (!pbuf) { + SAM("ERROR: Could not allocate audio " + "buffer page %i\n", k); + return -ENOMEM; + } else + peasycap->allocation_audio_page += 1; - peasycap->audio_buffer[k].pgo = pbuf; + peasycap->audio_buffer[k].pgo = pbuf; + } + peasycap->audio_buffer[k].pto = peasycap->audio_buffer[k].pgo; } - peasycap->audio_buffer[k].pto = peasycap->audio_buffer[k].pgo; - } - - peasycap->audio_fill = 0; - peasycap->audio_read = 0; - JOM(4, "allocation of audio buffer done: %i pages\n", k); -/*---------------------------------------------------------------------------*/ - JOM(4, "allocating %i isoc audio buffers of size %i\n", \ - AUDIO_ISOC_BUFFER_MANY, peasycap->audio_isoc_buffer_size); - JOM(4, ".... each occupying contiguous memory pages\n"); - for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { - pbuf = (void *)__get_free_pages(GFP_KERNEL, AUDIO_ISOC_ORDER); - if (NULL == pbuf) { - SAM("ERROR: Could not allocate isoc audio buffer " \ - "%i\n", k); - return -ENOMEM; - } else - peasycap->allocation_audio_page += \ - ((unsigned int)(0x01 << AUDIO_ISOC_ORDER)); + peasycap->audio_fill = 0; + peasycap->audio_read = 0; + JOM(4, "allocation of audio buffer done: %i pages\n", k); +#endif /* CONFIG_EASYCAP_OSS */ +/*---------------------------------------------------------------------------*/ + JOM(4, "allocating %i isoc audio buffers of size %i\n", + AUDIO_ISOC_BUFFER_MANY, + peasycap->audio_isoc_buffer_size); + JOM(4, ".... each occupying contiguous memory pages\n"); + + for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { + pbuf = (void *)__get_free_pages(GFP_KERNEL, + AUDIO_ISOC_ORDER); + if (!pbuf) { + SAM("ERROR: Could not allocate isoc audio buffer " + "%i\n", k); + return -ENOMEM; + } else + peasycap->allocation_audio_page += + BIT(AUDIO_ISOC_ORDER); - peasycap->audio_isoc_buffer[k].pgo = pbuf; - peasycap->audio_isoc_buffer[k].pto = pbuf + \ - peasycap->audio_isoc_buffer_size; - peasycap->audio_isoc_buffer[k].kount = k; - } - JOM(4, "allocation of isoc audio buffers done.\n"); + peasycap->audio_isoc_buffer[k].pgo = pbuf; + peasycap->audio_isoc_buffer[k].pto = pbuf + + peasycap->audio_isoc_buffer_size; + peasycap->audio_isoc_buffer[k].kount = k; + } + JOM(4, "allocation of isoc audio buffers done.\n"); /*---------------------------------------------------------------------------*/ /* * ALLOCATE AND INITIALIZE MULTIPLE struct urb ... */ /*---------------------------------------------------------------------------*/ - JOM(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY); - JOM(4, "using %i=peasycap->audio_isoc_framesperdesc\n", \ + JOM(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY); + JOM(4, "using %i=peasycap->audio_isoc_framesperdesc\n", peasycap->audio_isoc_framesperdesc); - JOM(4, "using %i=peasycap->audio_isoc_maxframesize\n", \ + JOM(4, "using %i=peasycap->audio_isoc_maxframesize\n", peasycap->audio_isoc_maxframesize); - JOM(4, "using %i=peasycap->audio_isoc_buffer_size\n", \ + JOM(4, "using %i=peasycap->audio_isoc_buffer_size\n", peasycap->audio_isoc_buffer_size); - for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { - purb = usb_alloc_urb(peasycap->audio_isoc_framesperdesc, \ + for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { + purb = usb_alloc_urb(peasycap->audio_isoc_framesperdesc, GFP_KERNEL); - if (NULL == purb) { - SAM("ERROR: usb_alloc_urb returned NULL for buffer " \ - "%i\n", k); - return -ENOMEM; - } else + if (!purb) { + SAM("ERROR: usb_alloc_urb returned NULL for buffer " + "%i\n", k); + return -ENOMEM; + } peasycap->allocation_audio_urb += 1 ; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL); - if (NULL == pdata_urb) { - SAM("ERROR: Could not allocate struct data_urb.\n"); - return -ENOMEM; - } else - peasycap->allocation_audio_struct += \ + pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL); + if (!pdata_urb) { + SAM("ERROR: Could not allocate struct data_urb.\n"); + return -ENOMEM; + } + peasycap->allocation_audio_struct += sizeof(struct data_urb); - pdata_urb->purb = purb; - pdata_urb->isbuf = k; - pdata_urb->length = 0; - list_add_tail(&(pdata_urb->list_head), \ - peasycap->purb_audio_head); + pdata_urb->purb = purb; + pdata_urb->isbuf = k; + pdata_urb->length = 0; + list_add_tail(&(pdata_urb->list_head), + peasycap->purb_audio_head); /*---------------------------------------------------------------------------*/ /* * ... AND INITIALIZE THEM */ /*---------------------------------------------------------------------------*/ - if (!k) { - JOM(4, "initializing audio urbs thus:\n"); - JOM(4, " purb->interval = 1;\n"); - JOM(4, " purb->dev = peasycap->pusb_device;\n"); - JOM(4, " purb->pipe = usb_rcvisocpipe(peasycap->" \ - "pusb_device,%i);\n", \ - peasycap->audio_endpointnumber); - JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n"); - JOM(4, " purb->transfer_buffer = " \ - "peasycap->audio_isoc_buffer[.].pgo;\n"); - JOM(4, " purb->transfer_buffer_length = %i;\n", \ + if (!k) { + JOM(4, "initializing audio urbs thus:\n"); + JOM(4, " purb->interval = 1;\n"); + JOM(4, " purb->dev = peasycap->pusb_device;\n"); + JOM(4, " purb->pipe = usb_rcvisocpipe(peasycap->" + "pusb_device,%i);\n", + peasycap->audio_endpointnumber); + JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n"); + JOM(4, " purb->transfer_buffer = " + "peasycap->audio_isoc_buffer[.].pgo;\n"); + JOM(4, " purb->transfer_buffer_length = %i;\n", peasycap->audio_isoc_buffer_size); - JOM(4, " purb->complete = easysnd_complete;\n"); - JOM(4, " purb->context = peasycap;\n"); - JOM(4, " purb->start_frame = 0;\n"); - JOM(4, " purb->number_of_packets = %i;\n", \ - peasycap->audio_isoc_framesperdesc); - JOM(4, " for (j = 0; j < %i; j++)\n", \ - peasycap->audio_isoc_framesperdesc); - JOM(4, " {\n"); - JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n",\ +#ifdef CONFIG_EASYCAP_OSS + JOM(4, " purb->complete = easyoss_complete;\n"); +#else /* CONFIG_EASYCAP_OSS */ + JOM(4, " purb->complete = easycap_alsa_complete;\n"); +#endif /* CONFIG_EASYCAP_OSS */ + JOM(4, " purb->context = peasycap;\n"); + JOM(4, " purb->start_frame = 0;\n"); + JOM(4, " purb->number_of_packets = %i;\n", + peasycap->audio_isoc_framesperdesc); + JOM(4, " for (j = 0; j < %i; j++)\n", + peasycap->audio_isoc_framesperdesc); + JOM(4, " {\n"); + JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n", peasycap->audio_isoc_maxframesize); - JOM(4, " purb->iso_frame_desc[j].length = %i;\n", \ + JOM(4, " purb->iso_frame_desc[j].length = %i;\n", peasycap->audio_isoc_maxframesize); - JOM(4, " }\n"); + JOM(4, " }\n"); } - purb->interval = 1; - purb->dev = peasycap->pusb_device; - purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, \ - peasycap->audio_endpointnumber); - purb->transfer_flags = URB_ISO_ASAP; - purb->transfer_buffer = peasycap->audio_isoc_buffer[k].pgo; - purb->transfer_buffer_length = \ - peasycap->audio_isoc_buffer_size; - purb->complete = easysnd_complete; - purb->context = peasycap; - purb->start_frame = 0; - purb->number_of_packets = peasycap->audio_isoc_framesperdesc; - for (j = 0; j < peasycap->audio_isoc_framesperdesc; j++) { - purb->iso_frame_desc[j].offset = j * \ - peasycap->audio_isoc_maxframesize; - purb->iso_frame_desc[j].length = \ - peasycap->audio_isoc_maxframesize; + purb->interval = 1; + purb->dev = peasycap->pusb_device; + purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, + peasycap->audio_endpointnumber); + purb->transfer_flags = URB_ISO_ASAP; + purb->transfer_buffer = peasycap->audio_isoc_buffer[k].pgo; + purb->transfer_buffer_length = + peasycap->audio_isoc_buffer_size; +#ifdef CONFIG_EASYCAP_OSS + purb->complete = easyoss_complete; +#else /* CONFIG_EASYCAP_OSS */ + purb->complete = easycap_alsa_complete; +#endif /* CONFIG_EASYCAP_OSS */ + purb->context = peasycap; + purb->start_frame = 0; + purb->number_of_packets = peasycap->audio_isoc_framesperdesc; + for (j = 0; j < peasycap->audio_isoc_framesperdesc; j++) { + purb->iso_frame_desc[j].offset = j * + peasycap->audio_isoc_maxframesize; + purb->iso_frame_desc[j].length = + peasycap->audio_isoc_maxframesize; + } } - } - JOM(4, "allocation of %i struct urb done.\n", k); + JOM(4, "allocation of %i struct urb done.\n", k); /*---------------------------------------------------------------------------*/ /* * SAVE POINTER peasycap IN THIS INTERFACE. */ /*---------------------------------------------------------------------------*/ - usb_set_intfdata(pusb_interface, peasycap); + usb_set_intfdata(pusb_interface, peasycap); /*---------------------------------------------------------------------------*/ /* * THE AUDIO DEVICE CAN BE REGISTERED NOW, AS IT IS READY. */ /*---------------------------------------------------------------------------*/ - rc = usb_register_dev(pusb_interface, &easysnd_class); - if (0 != rc) { - err("Not able to get a minor for this device."); - usb_set_intfdata(pusb_interface, NULL); - return -ENODEV; - } else { - JOM(8, "kref_get() with %i=peasycap->kref.refcount.counter\n",\ - (int)peasycap->kref.refcount.counter); - kref_get(&peasycap->kref); - (peasycap->registered_audio)++; +#ifndef CONFIG_EASYCAP_OSS + JOM(4, "initializing ALSA card\n"); + + rc = easycap_alsa_probe(peasycap); + if (rc) { + err("easycap_alsa_probe() rc = %i\n", rc); + return -ENODEV; + } else { + JOM(8, "kref_get() with %i=kref.refcount.counter\n", + peasycap->kref.refcount.counter); + kref_get(&peasycap->kref); + peasycap->registered_audio++; + } + +#else /* CONFIG_EASYCAP_OSS */ + rc = usb_register_dev(pusb_interface, &easyoss_class); + if (rc) { + SAY("ERROR: usb_register_dev() failed\n"); + usb_set_intfdata(pusb_interface, NULL); + return -ENODEV; + } else { + JOM(8, "kref_get() with %i=kref.refcount.counter\n", + peasycap->kref.refcount.counter); + kref_get(&peasycap->kref); + peasycap->registered_audio++; + } + SAM("easyoss attached to minor #%d\n", pusb_interface->minor); +#endif /* CONFIG_EASYCAP_OSS */ + + break; } /*---------------------------------------------------------------------------*/ /* - * LET THE USER KNOW WHAT NODE THE AUDIO DEVICE IS ATTACHED TO. - */ -/*---------------------------------------------------------------------------*/ - SAM("easysnd attached to minor #%d\n", pusb_interface->minor); - break; -} -/*---------------------------------------------------------------------------*/ -/* * INTERFACES OTHER THAN 0, 1 AND 2 ARE UNEXPECTED */ /*---------------------------------------------------------------------------*/ -default: { - JOM(4, "ERROR: unexpected interface %i\n", bInterfaceNumber); - return -EINVAL; -} -} -JOM(4, "ends successfully for interface %i\n", \ - pusb_interface_descriptor->bInterfaceNumber); -return 0; + default: + JOM(4, "ERROR: unexpected interface %i\n", bInterfaceNumber); + return -EINVAL; + } + SAM("ends successfully for interface %i\n", bInterfaceNumber); + return 0; } /*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* * WHEN THIS FUNCTION IS CALLED THE EasyCAP HAS ALREADY BEEN PHYSICALLY * UNPLUGGED. HENCE peasycap->pusb_device IS NO LONGER VALID. + * + * THIS FUNCTION AFFECTS BOTH OSS AND ALSA. BEWARE. */ /*---------------------------------------------------------------------------*/ -void -easycap_usb_disconnect(struct usb_interface *pusb_interface) +static void easycap_usb_disconnect(struct usb_interface *pusb_interface) { -struct usb_host_interface *pusb_host_interface; -struct usb_interface_descriptor *pusb_interface_descriptor; -__u8 bInterfaceNumber; -struct easycap *peasycap; - -struct list_head *plist_head; -struct data_urb *pdata_urb; -int minor, m, kd; -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if defined(EASYCAP_IS_VIDEODEV_CLIENT) -#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) -struct v4l2_device *pv4l2_device; -#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + struct usb_host_interface *pusb_host_interface; + struct usb_interface_descriptor *pusb_interface_descriptor; + u8 bInterfaceNumber; + struct easycap *peasycap; -JOT(4, "\n"); + struct list_head *plist_head; + struct data_urb *pdata_urb; + int minor, m, kd; + struct v4l2_device *pv4l2_device; -if ((struct usb_interface *)NULL == pusb_interface) { - JOT(4, "ERROR: pusb_interface is NULL\n"); - return; -} -pusb_host_interface = pusb_interface->cur_altsetting; -if ((struct usb_host_interface *)NULL == pusb_host_interface) { - JOT(4, "ERROR: pusb_host_interface is NULL\n"); - return; -} -pusb_interface_descriptor = &(pusb_host_interface->desc); -if ((struct usb_interface_descriptor *)NULL == pusb_interface_descriptor) { - JOT(4, "ERROR: pusb_interface_descriptor is NULL\n"); - return; -} -bInterfaceNumber = pusb_interface_descriptor->bInterfaceNumber; -minor = pusb_interface->minor; -JOT(4, "intf[%i]: minor=%i\n", bInterfaceNumber, minor); + JOT(4, "\n"); -if (1 == bInterfaceNumber) - return; + pusb_host_interface = pusb_interface->cur_altsetting; + if (!pusb_host_interface) { + JOT(4, "ERROR: pusb_host_interface is NULL\n"); + return; + } + pusb_interface_descriptor = &(pusb_host_interface->desc); + if (!pusb_interface_descriptor) { + JOT(4, "ERROR: pusb_interface_descriptor is NULL\n"); + return; + } + bInterfaceNumber = pusb_interface_descriptor->bInterfaceNumber; + minor = pusb_interface->minor; + JOT(4, "intf[%i]: minor=%i\n", bInterfaceNumber, minor); -peasycap = usb_get_intfdata(pusb_interface); -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return; -} -/*---------------------------------------------------------------------------*/ -#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) -# -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#else -#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) + if (1 == bInterfaceNumber) + return; + + peasycap = usb_get_intfdata(pusb_interface); + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return; + } /*---------------------------------------------------------------------------*/ /* * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS @@ -4793,80 +4290,72 @@ if (NULL == peasycap) { * TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED. */ /*---------------------------------------------------------------------------*/ -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - pv4l2_device = usb_get_intfdata(pusb_interface); - if ((struct v4l2_device *)NULL == pv4l2_device) { - SAY("ERROR: pv4l2_device is NULL\n"); - return; + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + pv4l2_device = usb_get_intfdata(pusb_interface); + if (!pv4l2_device) { + SAY("ERROR: pv4l2_device is NULL\n"); + return; + } + peasycap = (struct easycap *) + container_of(pv4l2_device, struct easycap, v4l2_device); } - peasycap = (struct easycap *) \ - container_of(pv4l2_device, struct easycap, v4l2_device); -} -#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ -# -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*---------------------------------------------------------------------------*/ -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); - return; -} + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: %p\n", peasycap); + return; + } /*---------------------------------------------------------------------------*/ /* * IF THE WAIT QUEUES ARE NOT CLEARED A DEADLOCK IS POSSIBLE. BEWARE. */ /*---------------------------------------------------------------------------*/ -peasycap->video_eof = 1; -peasycap->audio_eof = 1; -wake_up_interruptible(&(peasycap->wq_video)); -wake_up_interruptible(&(peasycap->wq_audio)); -/*---------------------------------------------------------------------------*/ -switch (bInterfaceNumber) { -case 0: { - if ((struct list_head *)NULL != peasycap->purb_video_head) { - JOM(4, "killing video urbs\n"); - m = 0; - list_for_each(plist_head, (peasycap->purb_video_head)) - { - pdata_urb = list_entry(plist_head, \ - struct data_urb, list_head); - if ((struct data_urb *)NULL != pdata_urb) { - if ((struct urb *)NULL != \ - pdata_urb->purb) { - usb_kill_urb(pdata_urb->purb); - m++; + peasycap->video_eof = 1; + peasycap->audio_eof = 1; + wake_up_interruptible(&(peasycap->wq_video)); + wake_up_interruptible(&(peasycap->wq_audio)); +/*---------------------------------------------------------------------------*/ + switch (bInterfaceNumber) { + case 0: { + if (peasycap->purb_video_head) { + JOM(4, "killing video urbs\n"); + m = 0; + list_for_each(plist_head, peasycap->purb_video_head) { + pdata_urb = list_entry(plist_head, + struct data_urb, list_head); + if (pdata_urb) { + if (pdata_urb->purb) { + usb_kill_urb(pdata_urb->purb); + m++; + } } } + JOM(4, "%i video urbs killed\n", m); } - JOM(4, "%i video urbs killed\n", m); + break; } - break; -} /*---------------------------------------------------------------------------*/ -case 2: { - if ((struct list_head *)NULL != peasycap->purb_audio_head) { - JOM(4, "killing audio urbs\n"); - m = 0; - list_for_each(plist_head, \ - (peasycap->purb_audio_head)) { - pdata_urb = list_entry(plist_head, \ - struct data_urb, list_head); - if ((struct data_urb *)NULL != pdata_urb) { - if ((struct urb *)NULL != \ - pdata_urb->purb) { - usb_kill_urb(pdata_urb->purb); - m++; + case 2: { + if (peasycap->purb_audio_head) { + JOM(4, "killing audio urbs\n"); + m = 0; + list_for_each(plist_head, peasycap->purb_audio_head) { + pdata_urb = list_entry(plist_head, + struct data_urb, list_head); + if (pdata_urb) { + if (pdata_urb->purb) { + usb_kill_urb(pdata_urb->purb); + m++; + } } } + JOM(4, "%i audio urbs killed\n", m); } - JOM(4, "%i audio urbs killed\n", m); + break; + } + default: + break; } - break; -} -/*---------------------------------------------------------------------------*/ -default: - break; -} /*--------------------------------------------------------------------------*/ /* * DEREGISTER @@ -4876,183 +4365,174 @@ default: * AN EasyCAP IS UNPLUGGED WHILE THE URBS ARE RUNNING. BEWARE. */ /*--------------------------------------------------------------------------*/ -kd = isdongle(peasycap); -switch (bInterfaceNumber) { -case 0: { - if (0 <= kd && DONGLE_MANY > kd) { - wake_up_interruptible(&peasycap->wq_video); - JOM(4, "about to lock easycap_dongle[%i].mutex_video\n", kd); - if (mutex_lock_interruptible(&easycap_dongle[kd].\ + kd = isdongle(peasycap); + switch (bInterfaceNumber) { + case 0: { + if (0 <= kd && DONGLE_MANY > kd) { + wake_up_interruptible(&peasycap->wq_video); + JOM(4, "about to lock dongle[%i].mutex_video\n", kd); + if (mutex_lock_interruptible(&easycapdc60_dongle[kd]. mutex_video)) { - SAY("ERROR: cannot lock easycap_dongle[%i]." \ - "mutex_video\n", kd); - return; + SAY("ERROR: " + "cannot lock dongle[%i].mutex_video\n", kd); + return; + } + JOM(4, "locked dongle[%i].mutex_video\n", kd); + } else { + SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd); } - JOM(4, "locked easycap_dongle[%i].mutex_video\n", kd); - } else - SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd); /*---------------------------------------------------------------------------*/ -#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) - if ((struct easycap *)NULL == peasycap) { - SAM("ERROR: peasycap has become NULL\n"); - } else { - usb_deregister_dev(pusb_interface, &easycap_class); - (peasycap->registered_video)--; - JOM(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber); - SAM("easycap detached from minor #%d\n", minor); - } -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#else -#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) - if (!peasycap->v4l2_device.name[0]) { - SAM("ERROR: peasycap->v4l2_device.name is empty\n"); - if (0 <= kd && DONGLE_MANY > kd) - mutex_unlock(&easycap_dongle[kd].mutex_video); - return; - } - v4l2_device_disconnect(&peasycap->v4l2_device); - JOM(4, "v4l2_device_disconnect() OK\n"); - v4l2_device_unregister(&peasycap->v4l2_device); - JOM(4, "v4l2_device_unregister() OK\n"); -#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ - - video_unregister_device(&peasycap->video_device); - JOM(4, "intf[%i]: video_unregister_device() OK\n", bInterfaceNumber); - (peasycap->registered_video)--; - JOM(4, "unregistered with videodev: %i=minor\n", minor); -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ + if (!peasycap->v4l2_device.name[0]) { + SAM("ERROR: peasycap->v4l2_device.name is empty\n"); + if (0 <= kd && DONGLE_MANY > kd) + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + return; + } + v4l2_device_disconnect(&peasycap->v4l2_device); + JOM(4, "v4l2_device_disconnect() OK\n"); + v4l2_device_unregister(&peasycap->v4l2_device); + JOM(4, "v4l2_device_unregister() OK\n"); + + video_unregister_device(&peasycap->video_device); + JOM(4, "intf[%i]: video_unregister_device() minor=%i\n", + bInterfaceNumber, minor); + peasycap->registered_video--; /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - if (0 <= kd && DONGLE_MANY > kd) { - mutex_unlock(&easycap_dongle[kd].mutex_video); - JOM(4, "unlocked easycap_dongle[%i].mutex_video\n", kd); + if (0 <= kd && DONGLE_MANY > kd) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + JOM(4, "unlocked dongle[%i].mutex_video\n", kd); + } + break; } - break; -} -case 2: { - if (0 <= kd && DONGLE_MANY > kd) { - wake_up_interruptible(&peasycap->wq_audio); - JOM(4, "about to lock easycap_dongle[%i].mutex_audio\n", kd); - if (mutex_lock_interruptible(&easycap_dongle[kd].\ + case 2: { + if (0 <= kd && DONGLE_MANY > kd) { + wake_up_interruptible(&peasycap->wq_audio); + JOM(4, "about to lock dongle[%i].mutex_audio\n", kd); + if (mutex_lock_interruptible(&easycapdc60_dongle[kd]. mutex_audio)) { - SAY("ERROR: cannot lock easycap_dongle[%i]." \ - "mutex_audio\n", kd); - return; + SAY("ERROR: " + "cannot lock dongle[%i].mutex_audio\n", kd); + return; + } + JOM(4, "locked dongle[%i].mutex_audio\n", kd); + } else + SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd); +#ifndef CONFIG_EASYCAP_OSS + if (0 != snd_card_free(peasycap->psnd_card)) { + SAY("ERROR: snd_card_free() failed\n"); + } else { + peasycap->psnd_card = NULL; + (peasycap->registered_audio)--; } - JOM(4, "locked easycap_dongle[%i].mutex_audio\n", kd); - } else - SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd); - - usb_deregister_dev(pusb_interface, &easysnd_class); - (peasycap->registered_audio)--; - - JOM(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber); - SAM("easysnd detached from minor #%d\n", minor); - - if (0 <= kd && DONGLE_MANY > kd) { - mutex_unlock(&easycap_dongle[kd].mutex_audio); - JOM(4, "unlocked easycap_dongle[%i].mutex_audio\n", kd); +#else /* CONFIG_EASYCAP_OSS */ + usb_deregister_dev(pusb_interface, &easyoss_class); + peasycap->registered_audio--; + JOM(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber); + SAM("easyoss detached from minor #%d\n", minor); +#endif /* CONFIG_EASYCAP_OSS */ + if (0 <= kd && DONGLE_MANY > kd) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + JOM(4, "unlocked dongle[%i].mutex_audio\n", kd); + } + break; + } + default: + break; } - break; -} -default: - break; -} /*---------------------------------------------------------------------------*/ /* * CALL easycap_delete() IF NO REMAINING REFERENCES TO peasycap + * (ALSO WHEN ALSA HAS BEEN IN USE) */ /*---------------------------------------------------------------------------*/ -if (!peasycap->kref.refcount.counter) { - SAM("ERROR: peasycap->kref.refcount.counter is zero " - "so cannot call kref_put()\n"); - SAM("ending unsuccessfully: may cause memory leak\n"); - return; -} -if (0 <= kd && DONGLE_MANY > kd) { - JOM(4, "about to lock easycap_dongle[%i].mutex_video\n", kd); - if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_video)) { - SAY("ERROR: cannot down easycap_dongle[%i].mutex_video\n", kd); - SAM("ending unsuccessfully: may cause memory leak\n"); - return; - } - JOM(4, "locked easycap_dongle[%i].mutex_video\n", kd); - JOM(4, "about to lock easycap_dongle[%i].mutex_audio\n", kd); - if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_audio)) { - SAY("ERROR: cannot down easycap_dongle[%i].mutex_audio\n", kd); - mutex_unlock(&(easycap_dongle[kd].mutex_video)); - JOM(4, "unlocked easycap_dongle[%i].mutex_video\n", kd); + if (!peasycap->kref.refcount.counter) { + SAM("ERROR: peasycap->kref.refcount.counter is zero " + "so cannot call kref_put()\n"); SAM("ending unsuccessfully: may cause memory leak\n"); return; } - JOM(4, "locked easycap_dongle[%i].mutex_audio\n", kd); -} -JOM(4, "intf[%i]: %i=peasycap->kref.refcount.counter\n", \ - bInterfaceNumber, (int)peasycap->kref.refcount.counter); -kref_put(&peasycap->kref, easycap_delete); -JOT(4, "intf[%i]: kref_put() done.\n", bInterfaceNumber); -if (0 <= kd && DONGLE_MANY > kd) { - mutex_unlock(&(easycap_dongle[kd].mutex_audio)); - JOT(4, "unlocked easycap_dongle[%i].mutex_audio\n", kd); - mutex_unlock(&easycap_dongle[kd].mutex_video); - JOT(4, "unlocked easycap_dongle[%i].mutex_video\n", kd); -} + if (0 <= kd && DONGLE_MANY > kd) { + JOM(4, "about to lock dongle[%i].mutex_video\n", kd); + if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) { + SAY("ERROR: cannot lock dongle[%i].mutex_video\n", kd); + SAM("ending unsuccessfully: may cause memory leak\n"); + return; + } + JOM(4, "locked dongle[%i].mutex_video\n", kd); + JOM(4, "about to lock dongle[%i].mutex_audio\n", kd); + if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_audio)) { + SAY("ERROR: cannot lock dongle[%i].mutex_audio\n", kd); + mutex_unlock(&(easycapdc60_dongle[kd].mutex_video)); + JOM(4, "unlocked dongle[%i].mutex_video\n", kd); + SAM("ending unsuccessfully: may cause memory leak\n"); + return; + } + JOM(4, "locked dongle[%i].mutex_audio\n", kd); + } + JOM(4, "intf[%i]: %i=peasycap->kref.refcount.counter\n", + bInterfaceNumber, (int)peasycap->kref.refcount.counter); + kref_put(&peasycap->kref, easycap_delete); + JOT(4, "intf[%i]: kref_put() done.\n", bInterfaceNumber); + if (0 <= kd && DONGLE_MANY > kd) { + mutex_unlock(&(easycapdc60_dongle[kd].mutex_audio)); + JOT(4, "unlocked dongle[%i].mutex_audio\n", kd); + mutex_unlock(&easycapdc60_dongle[kd].mutex_video); + JOT(4, "unlocked dongle[%i].mutex_video\n", kd); + } /*---------------------------------------------------------------------------*/ -JOM(4, "ends\n"); -return; + JOM(4, "ends\n"); + return; } /*****************************************************************************/ -int __init -easycap_module_init(void) -{ -int result; -SAY("========easycap=======\n"); -JOT(4, "begins. %i=debug %i=bars %i=gain\n", easycap_debug, easycap_bars, \ - easycap_gain); -SAY("version: " EASYCAP_DRIVER_VERSION "\n"); /*---------------------------------------------------------------------------*/ /* - * REGISTER THIS DRIVER WITH THE USB SUBSYTEM. + * PARAMETERS APPLICABLE TO ENTIRE DRIVER, I.E. BOTH VIDEO AND AUDIO */ /*---------------------------------------------------------------------------*/ -JOT(4, "registering driver easycap\n"); +static struct usb_device_id easycap_usb_device_id_table[] = { + {USB_DEVICE(USB_EASYCAP_VENDOR_ID, USB_EASYCAP_PRODUCT_ID)}, + { } +}; -result = usb_register(&easycap_usb_driver); -if (0 != result) - SAY("ERROR: usb_register returned %i\n", result); +MODULE_DEVICE_TABLE(usb, easycap_usb_device_id_table); +struct usb_driver easycap_usb_driver = { + .name = "easycap", + .id_table = easycap_usb_device_id_table, + .probe = easycap_usb_probe, + .disconnect = easycap_usb_disconnect, +}; -JOT(4, "ends\n"); -return result; -} -/*****************************************************************************/ -void __exit -easycap_module_exit(void) +static int __init easycap_module_init(void) { -JOT(4, "begins\n"); + int k, rc; -/*---------------------------------------------------------------------------*/ -/* - * DEREGISTER THIS DRIVER WITH THE USB SUBSYTEM. - */ -/*---------------------------------------------------------------------------*/ -usb_deregister(&easycap_usb_driver); + printk(KERN_INFO "Easycap version: "EASYCAP_DRIVER_VERSION "\n"); + + JOT(4, "begins. %i=debug %i=bars %i=gain\n", + easycap_debug, easycap_bars, easycap_gain); + + mutex_init(&mutex_dongle); + for (k = 0; k < DONGLE_MANY; k++) { + easycapdc60_dongle[k].peasycap = NULL; + mutex_init(&easycapdc60_dongle[k].mutex_video); + mutex_init(&easycapdc60_dongle[k].mutex_audio); + } + rc = usb_register(&easycap_usb_driver); + if (rc) + printk(KERN_ERR "Easycap: usb_register failed rc=%d\n", rc); -JOT(4, "ends\n"); + return rc; +} +/*****************************************************************************/ +static void __exit easycap_module_exit(void) +{ + usb_deregister(&easycap_usb_driver); } /*****************************************************************************/ module_init(easycap_module_init); module_exit(easycap_module_exit); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("R.M. Thomas <rmthomas@sciolus.org>"); -MODULE_DESCRIPTION(EASYCAP_DRIVER_DESCRIPTION); -MODULE_VERSION(EASYCAP_DRIVER_VERSION); -#if defined(EASYCAP_DEBUG) -MODULE_PARM_DESC(debug, "Debug level: 0(default),1,2,...,9"); -#endif /*EASYCAP_DEBUG*/ -MODULE_PARM_DESC(bars, \ - "Testcard bars on input signal failure: 0=>no, 1=>yes(default)"); -MODULE_PARM_DESC(gain, "Audio gain: 0,...,16(default),...31"); /*****************************************************************************/ diff --git a/drivers/staging/easycap/easycap_settings.c b/drivers/staging/easycap/easycap_settings.c index df3f17d361b..898559dad70 100644 --- a/drivers/staging/easycap/easycap_settings.c +++ b/drivers/staging/easycap/easycap_settings.c @@ -26,7 +26,6 @@ /*****************************************************************************/ #include "easycap.h" -#include "easycap_debug.h" /*---------------------------------------------------------------------------*/ /* @@ -40,252 +39,255 @@ */ /*---------------------------------------------------------------------------*/ const struct easycap_standard easycap_standard[] = { -{ -.mask = 0x00FF & PAL_BGHIN , -.v4l2_standard = { - .index = PAL_BGHIN, - .id = (V4L2_STD_PAL_B | V4L2_STD_PAL_G | V4L2_STD_PAL_H | \ - V4L2_STD_PAL_I | V4L2_STD_PAL_N), - .name = "PAL_BGHIN", - .frameperiod = {1, 25}, - .framelines = 625, - .reserved = {0, 0, 0, 0} - } -}, + { + .mask = 0x00FF & PAL_BGHIN , + .v4l2_standard = { + .index = PAL_BGHIN, + .id = (V4L2_STD_PAL_B | + V4L2_STD_PAL_G | V4L2_STD_PAL_H | + V4L2_STD_PAL_I | V4L2_STD_PAL_N), + .name = "PAL_BGHIN", + .frameperiod = {1, 25}, + .framelines = 625, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x00FF & NTSC_N_443 , -.v4l2_standard = { - .index = NTSC_N_443, - .id = V4L2_STD_UNKNOWN, - .name = "NTSC_N_443", - .frameperiod = {1, 25}, - .framelines = 480, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x00FF & NTSC_N_443 , + .v4l2_standard = { + .index = NTSC_N_443, + .id = V4L2_STD_UNKNOWN, + .name = "NTSC_N_443", + .frameperiod = {1, 25}, + .framelines = 480, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x00FF & PAL_Nc , -.v4l2_standard = { - .index = PAL_Nc, - .id = V4L2_STD_PAL_Nc, - .name = "PAL_Nc", - .frameperiod = {1, 25}, - .framelines = 625, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x00FF & PAL_Nc , + .v4l2_standard = { + .index = PAL_Nc, + .id = V4L2_STD_PAL_Nc, + .name = "PAL_Nc", + .frameperiod = {1, 25}, + .framelines = 625, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x00FF & NTSC_N , -.v4l2_standard = { - .index = NTSC_N, - .id = V4L2_STD_UNKNOWN, - .name = "NTSC_N", - .frameperiod = {1, 25}, - .framelines = 525, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x00FF & NTSC_N , + .v4l2_standard = { + .index = NTSC_N, + .id = V4L2_STD_UNKNOWN, + .name = "NTSC_N", + .frameperiod = {1, 25}, + .framelines = 525, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x00FF & SECAM , -.v4l2_standard = { - .index = SECAM, - .id = V4L2_STD_SECAM, - .name = "SECAM", - .frameperiod = {1, 25}, - .framelines = 625, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x00FF & SECAM , + .v4l2_standard = { + .index = SECAM, + .id = V4L2_STD_SECAM, + .name = "SECAM", + .frameperiod = {1, 25}, + .framelines = 625, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x00FF & NTSC_M , -.v4l2_standard = { - .index = NTSC_M, - .id = V4L2_STD_NTSC_M, - .name = "NTSC_M", - .frameperiod = {1, 30}, - .framelines = 525, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x00FF & NTSC_M , + .v4l2_standard = { + .index = NTSC_M, + .id = V4L2_STD_NTSC_M, + .name = "NTSC_M", + .frameperiod = {1, 30}, + .framelines = 525, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x00FF & NTSC_M_JP , -.v4l2_standard = { - .index = NTSC_M_JP, - .id = V4L2_STD_NTSC_M_JP, - .name = "NTSC_M_JP", - .frameperiod = {1, 30}, - .framelines = 525, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x00FF & NTSC_M_JP , + .v4l2_standard = { + .index = NTSC_M_JP, + .id = V4L2_STD_NTSC_M_JP, + .name = "NTSC_M_JP", + .frameperiod = {1, 30}, + .framelines = 525, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x00FF & PAL_60 , -.v4l2_standard = { - .index = PAL_60, - .id = V4L2_STD_PAL_60, - .name = "PAL_60", - .frameperiod = {1, 30}, - .framelines = 525, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x00FF & PAL_60 , + .v4l2_standard = { + .index = PAL_60, + .id = V4L2_STD_PAL_60, + .name = "PAL_60", + .frameperiod = {1, 30}, + .framelines = 525, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x00FF & NTSC_443 , -.v4l2_standard = { - .index = NTSC_443, - .id = V4L2_STD_NTSC_443, - .name = "NTSC_443", - .frameperiod = {1, 30}, - .framelines = 525, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x00FF & NTSC_443 , + .v4l2_standard = { + .index = NTSC_443, + .id = V4L2_STD_NTSC_443, + .name = "NTSC_443", + .frameperiod = {1, 30}, + .framelines = 525, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x00FF & PAL_M , -.v4l2_standard = { - .index = PAL_M, - .id = V4L2_STD_PAL_M, - .name = "PAL_M", - .frameperiod = {1, 30}, - .framelines = 525, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x00FF & PAL_M , + .v4l2_standard = { + .index = PAL_M, + .id = V4L2_STD_PAL_M, + .name = "PAL_M", + .frameperiod = {1, 30}, + .framelines = 525, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x8000 | (0x00FF & PAL_BGHIN_SLOW), -.v4l2_standard = { - .index = PAL_BGHIN_SLOW, - .id = (V4L2_STD_PAL_B | V4L2_STD_PAL_G | V4L2_STD_PAL_H | \ - V4L2_STD_PAL_I | V4L2_STD_PAL_N | \ - (((v4l2_std_id)0x01) << 32)), - .name = "PAL_BGHIN_SLOW", - .frameperiod = {1, 5}, - .framelines = 625, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x8000 | (0x00FF & PAL_BGHIN_SLOW), + .v4l2_standard = { + .index = PAL_BGHIN_SLOW, + .id = (V4L2_STD_PAL_B | V4L2_STD_PAL_G | + V4L2_STD_PAL_H | + V4L2_STD_PAL_I | V4L2_STD_PAL_N | + (((v4l2_std_id)0x01) << 32)), + .name = "PAL_BGHIN_SLOW", + .frameperiod = {1, 5}, + .framelines = 625, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x8000 | (0x00FF & NTSC_N_443_SLOW), -.v4l2_standard = { - .index = NTSC_N_443_SLOW, - .id = (V4L2_STD_UNKNOWN | (((v4l2_std_id)0x11) << 32)), - .name = "NTSC_N_443_SLOW", - .frameperiod = {1, 5}, - .framelines = 480, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x8000 | (0x00FF & NTSC_N_443_SLOW), + .v4l2_standard = { + .index = NTSC_N_443_SLOW, + .id = (V4L2_STD_UNKNOWN | (((v4l2_std_id)0x11) << 32)), + .name = "NTSC_N_443_SLOW", + .frameperiod = {1, 5}, + .framelines = 480, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x8000 | (0x00FF & PAL_Nc_SLOW), -.v4l2_standard = { - .index = PAL_Nc_SLOW, - .id = (V4L2_STD_PAL_Nc | (((v4l2_std_id)0x01) << 32)), - .name = "PAL_Nc_SLOW", - .frameperiod = {1, 5}, - .framelines = 625, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x8000 | (0x00FF & PAL_Nc_SLOW), + .v4l2_standard = { + .index = PAL_Nc_SLOW, + .id = (V4L2_STD_PAL_Nc | (((v4l2_std_id)0x01) << 32)), + .name = "PAL_Nc_SLOW", + .frameperiod = {1, 5}, + .framelines = 625, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x8000 | (0x00FF & NTSC_N_SLOW), -.v4l2_standard = { - .index = NTSC_N_SLOW, - .id = (V4L2_STD_UNKNOWN | (((v4l2_std_id)0x21) << 32)), - .name = "NTSC_N_SLOW", - .frameperiod = {1, 5}, - .framelines = 525, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x8000 | (0x00FF & NTSC_N_SLOW), + .v4l2_standard = { + .index = NTSC_N_SLOW, + .id = (V4L2_STD_UNKNOWN | (((v4l2_std_id)0x21) << 32)), + .name = "NTSC_N_SLOW", + .frameperiod = {1, 5}, + .framelines = 525, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x8000 | (0x00FF & SECAM_SLOW), -.v4l2_standard = { - .index = SECAM_SLOW, - .id = (V4L2_STD_SECAM | (((v4l2_std_id)0x01) << 32)), - .name = "SECAM_SLOW", - .frameperiod = {1, 5}, - .framelines = 625, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x8000 | (0x00FF & SECAM_SLOW), + .v4l2_standard = { + .index = SECAM_SLOW, + .id = (V4L2_STD_SECAM | (((v4l2_std_id)0x01) << 32)), + .name = "SECAM_SLOW", + .frameperiod = {1, 5}, + .framelines = 625, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x8000 | (0x00FF & NTSC_M_SLOW), -.v4l2_standard = { - .index = NTSC_M_SLOW, - .id = (V4L2_STD_NTSC_M | (((v4l2_std_id)0x01) << 32)), - .name = "NTSC_M_SLOW", - .frameperiod = {1, 6}, - .framelines = 525, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x8000 | (0x00FF & NTSC_M_SLOW), + .v4l2_standard = { + .index = NTSC_M_SLOW, + .id = (V4L2_STD_NTSC_M | (((v4l2_std_id)0x01) << 32)), + .name = "NTSC_M_SLOW", + .frameperiod = {1, 6}, + .framelines = 525, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x8000 | (0x00FF & NTSC_M_JP_SLOW), -.v4l2_standard = { - .index = NTSC_M_JP_SLOW, - .id = (V4L2_STD_NTSC_M_JP | (((v4l2_std_id)0x01) << 32)), - .name = "NTSC_M_JP_SLOW", - .frameperiod = {1, 6}, - .framelines = 525, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x8000 | (0x00FF & NTSC_M_JP_SLOW), + .v4l2_standard = { + .index = NTSC_M_JP_SLOW, + .id = (V4L2_STD_NTSC_M_JP | + (((v4l2_std_id)0x01) << 32)), + .name = "NTSC_M_JP_SLOW", + .frameperiod = {1, 6}, + .framelines = 525, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x8000 | (0x00FF & PAL_60_SLOW), -.v4l2_standard = { - .index = PAL_60_SLOW, - .id = (V4L2_STD_PAL_60 | (((v4l2_std_id)0x01) << 32)), - .name = "PAL_60_SLOW", - .frameperiod = {1, 6}, - .framelines = 525, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x8000 | (0x00FF & PAL_60_SLOW), + .v4l2_standard = { + .index = PAL_60_SLOW, + .id = (V4L2_STD_PAL_60 | (((v4l2_std_id)0x01) << 32)), + .name = "PAL_60_SLOW", + .frameperiod = {1, 6}, + .framelines = 525, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x8000 | (0x00FF & NTSC_443_SLOW), -.v4l2_standard = { - .index = NTSC_443_SLOW, - .id = (V4L2_STD_NTSC_443 | (((v4l2_std_id)0x01) << 32)), - .name = "NTSC_443_SLOW", - .frameperiod = {1, 6}, - .framelines = 525, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x8000 | (0x00FF & NTSC_443_SLOW), + .v4l2_standard = { + .index = NTSC_443_SLOW, + .id = (V4L2_STD_NTSC_443 | (((v4l2_std_id)0x01) << 32)), + .name = "NTSC_443_SLOW", + .frameperiod = {1, 6}, + .framelines = 525, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0x8000 | (0x00FF & PAL_M_SLOW), -.v4l2_standard = { - .index = PAL_M_SLOW, - .id = (V4L2_STD_PAL_M | (((v4l2_std_id)0x01) << 32)), - .name = "PAL_M_SLOW", - .frameperiod = {1, 6}, - .framelines = 525, - .reserved = {0, 0, 0, 0} -} -}, + { + .mask = 0x8000 | (0x00FF & PAL_M_SLOW), + .v4l2_standard = { + .index = PAL_M_SLOW, + .id = (V4L2_STD_PAL_M | (((v4l2_std_id)0x01) << 32)), + .name = "PAL_M_SLOW", + .frameperiod = {1, 6}, + .framelines = 525, + .reserved = {0, 0, 0, 0} + } + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.mask = 0xFFFF -} + { + .mask = 0xFFFF + } }; /*---------------------------------------------------------------------------*/ /* @@ -311,371 +313,384 @@ const struct easycap_standard easycap_standard[] = { struct easycap_format easycap_format[1 + SETTINGS_MANY]; -int -fillin_formats(void) +int fillin_formats(void) { -int i, j, k, m, n; -__u32 width, height, pixelformat, bytesperline, sizeimage; -__u32 field, colorspace; -__u16 mask1, mask2, mask3, mask4; -char name1[32], name2[32], name3[32], name4[32]; + const char *name1, *name2, *name3, *name4; + struct v4l2_format *fmt; + int i, j, k, m, n; + u32 width, height, pixelformat, bytesperline, sizeimage; + u16 mask1, mask2, mask3, mask4; + enum v4l2_field field; + enum v4l2_colorspace colorspace; -for (i = 0, n = 0; i < STANDARD_MANY; i++) { - mask1 = 0x0000; - switch (i) { - case PAL_BGHIN: { - mask1 = 0x1F & PAL_BGHIN; - strcpy(&name1[0], "PAL_BGHIN"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; - break; - } - case SECAM: { - mask1 = 0x1F & SECAM; - strcpy(&name1[0], "SECAM"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; - break; - } - case PAL_Nc: { - mask1 = 0x1F & PAL_Nc; - strcpy(&name1[0], "PAL_Nc"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; - break; - } - case PAL_60: { - mask1 = 0x1F & PAL_60; - strcpy(&name1[0], "PAL_60"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; - break; - } - case PAL_M: { - mask1 = 0x1F & PAL_M; - strcpy(&name1[0], "PAL_M"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; - break; - } - case NTSC_M: { - mask1 = 0x1F & NTSC_M; - strcpy(&name1[0], "NTSC_M"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_M; - break; - } - case NTSC_443: { - mask1 = 0x1F & NTSC_443; - strcpy(&name1[0], "NTSC_443"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_M; - break; - } - case NTSC_M_JP: { - mask1 = 0x1F & NTSC_M_JP; - strcpy(&name1[0], "NTSC_M_JP"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_M; - break; - } - case NTSC_N: { - mask1 = 0x1F & NTSC_M; - strcpy(&name1[0], "NTSC_N"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_M; - break; - } - case NTSC_N_443: { - mask1 = 0x1F & NTSC_N_443; - strcpy(&name1[0], "NTSC_N_443"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_M; - break; - } - case PAL_BGHIN_SLOW: { - mask1 = 0x001F & PAL_BGHIN_SLOW; - mask1 |= 0x0200; - strcpy(&name1[0], "PAL_BGHIN_SLOW"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; - break; - } - case SECAM_SLOW: { - mask1 = 0x001F & SECAM_SLOW; - mask1 |= 0x0200; - strcpy(&name1[0], "SECAM_SLOW"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; - break; - } - case PAL_Nc_SLOW: { - mask1 = 0x001F & PAL_Nc_SLOW; - mask1 |= 0x0200; - strcpy(&name1[0], "PAL_Nc_SLOW"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; - break; - } - case PAL_60_SLOW: { - mask1 = 0x001F & PAL_60_SLOW; - mask1 |= 0x0200; - strcpy(&name1[0], "PAL_60_SLOW"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; - break; - } - case PAL_M_SLOW: { - mask1 = 0x001F & PAL_M_SLOW; - mask1 |= 0x0200; - strcpy(&name1[0], "PAL_M_SLOW"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; - break; - } - case NTSC_M_SLOW: { - mask1 = 0x001F & NTSC_M_SLOW; - mask1 |= 0x0200; - strcpy(&name1[0], "NTSC_M_SLOW"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_M; - break; - } - case NTSC_443_SLOW: { - mask1 = 0x001F & NTSC_443_SLOW; - mask1 |= 0x0200; - strcpy(&name1[0], "NTSC_443_SLOW"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_M; - break; - } - case NTSC_M_JP_SLOW: { - mask1 = 0x001F & NTSC_M_JP_SLOW; - mask1 |= 0x0200; - strcpy(&name1[0], "NTSC_M_JP_SLOW"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_M; - break; - } - case NTSC_N_SLOW: { - mask1 = 0x001F & NTSC_N_SLOW; - mask1 |= 0x0200; - strcpy(&name1[0], "NTSC_N_SLOW"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_M; - break; - } - case NTSC_N_443_SLOW: { - mask1 = 0x001F & NTSC_N_443_SLOW; - mask1 |= 0x0200; - strcpy(&name1[0], "NTSC_N_443_SLOW"); - colorspace = V4L2_COLORSPACE_470_SYSTEM_M; - break; - } - default: - return -1; - } - - for (j = 0; j < RESOLUTION_MANY; j++) { - mask2 = 0x0000; - switch (j) { - case AT_720x576: { - if (0x1 & mask1) - continue; - strcpy(&name2[0], "_AT_720x576"); - width = 720; height = 576; break; - } - case AT_704x576: { - if (0x1 & mask1) - continue; - strcpy(&name2[0], "_AT_704x576"); - width = 704; height = 576; break; - } - case AT_640x480: { - strcpy(&name2[0], "_AT_640x480"); - width = 640; height = 480; break; - } - case AT_720x480: { - if (!(0x1 & mask1)) - continue; - strcpy(&name2[0], "_AT_720x480"); - width = 720; height = 480; break; - } - case AT_360x288: { - if (0x1 & mask1) - continue; - strcpy(&name2[0], "_AT_360x288"); - width = 360; height = 288; mask2 = 0x0800; break; - } - case AT_320x240: { - strcpy(&name2[0], "_AT_320x240"); - width = 320; height = 240; mask2 = 0x0800; break; - } - case AT_360x240: { - if (!(0x1 & mask1)) - continue; - strcpy(&name2[0], "_AT_360x240"); - width = 360; height = 240; mask2 = 0x0800; break; + for (i = 0, n = 0; i < STANDARD_MANY; i++) { + mask1 = 0x0000; + switch (i) { + case PAL_BGHIN: { + mask1 = 0x1F & PAL_BGHIN; + name1 = "PAL_BGHIN"; + colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; + break; + } + case SECAM: { + mask1 = 0x1F & SECAM; + name1 = "SECAM"; + colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; + break; + } + case PAL_Nc: { + mask1 = 0x1F & PAL_Nc; + name1 = "PAL_Nc"; + colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; + break; + } + case PAL_60: { + mask1 = 0x1F & PAL_60; + name1 = "PAL_60"; + colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; + break; + } + case PAL_M: { + mask1 = 0x1F & PAL_M; + name1 = "PAL_M"; + colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; + break; + } + case NTSC_M: { + mask1 = 0x1F & NTSC_M; + name1 = "NTSC_M"; + colorspace = V4L2_COLORSPACE_470_SYSTEM_M; + break; + } + case NTSC_443: { + mask1 = 0x1F & NTSC_443; + name1 = "NTSC_443"; + colorspace = V4L2_COLORSPACE_470_SYSTEM_M; + break; + } + case NTSC_M_JP: { + mask1 = 0x1F & NTSC_M_JP; + name1 = "NTSC_M_JP"; + colorspace = V4L2_COLORSPACE_470_SYSTEM_M; + break; + } + case NTSC_N: { + mask1 = 0x1F & NTSC_M; + name1 = "NTSC_N"; + colorspace = V4L2_COLORSPACE_470_SYSTEM_M; + break; + } + case NTSC_N_443: { + mask1 = 0x1F & NTSC_N_443; + name1 = "NTSC_N_443"; + colorspace = V4L2_COLORSPACE_470_SYSTEM_M; + break; + } + case PAL_BGHIN_SLOW: { + mask1 = 0x001F & PAL_BGHIN_SLOW; + mask1 |= 0x0200; + name1 = "PAL_BGHIN_SLOW"; + colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; + break; + } + case SECAM_SLOW: { + mask1 = 0x001F & SECAM_SLOW; + mask1 |= 0x0200; + name1 = "SECAM_SLOW"; + colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; + break; + } + case PAL_Nc_SLOW: { + mask1 = 0x001F & PAL_Nc_SLOW; + mask1 |= 0x0200; + name1 = "PAL_Nc_SLOW"; + colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; + break; + } + case PAL_60_SLOW: { + mask1 = 0x001F & PAL_60_SLOW; + mask1 |= 0x0200; + name1 = "PAL_60_SLOW"; + colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; + break; + } + case PAL_M_SLOW: { + mask1 = 0x001F & PAL_M_SLOW; + mask1 |= 0x0200; + name1 = "PAL_M_SLOW"; + colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; + break; + } + case NTSC_M_SLOW: { + mask1 = 0x001F & NTSC_M_SLOW; + mask1 |= 0x0200; + name1 = "NTSC_M_SLOW"; + colorspace = V4L2_COLORSPACE_470_SYSTEM_M; + break; + } + case NTSC_443_SLOW: { + mask1 = 0x001F & NTSC_443_SLOW; + mask1 |= 0x0200; + name1 = "NTSC_443_SLOW"; + colorspace = V4L2_COLORSPACE_470_SYSTEM_M; + break; + } + case NTSC_M_JP_SLOW: { + mask1 = 0x001F & NTSC_M_JP_SLOW; + mask1 |= 0x0200; + name1 = "NTSC_M_JP_SLOW"; + colorspace = V4L2_COLORSPACE_470_SYSTEM_M; + break; + } + case NTSC_N_SLOW: { + mask1 = 0x001F & NTSC_N_SLOW; + mask1 |= 0x0200; + name1 = "NTSC_N_SLOW"; + colorspace = V4L2_COLORSPACE_470_SYSTEM_M; + break; + } + case NTSC_N_443_SLOW: { + mask1 = 0x001F & NTSC_N_443_SLOW; + mask1 |= 0x0200; + name1 = "NTSC_N_443_SLOW"; + colorspace = V4L2_COLORSPACE_470_SYSTEM_M; + break; } default: - return -2; + return -1; } - for (k = 0; k < PIXELFORMAT_MANY; k++) { - mask3 = 0x0000; - switch (k) { - case FMT_UYVY: { - strcpy(&name3[0], "_" STRINGIZE(FMT_UYVY)); - pixelformat = V4L2_PIX_FMT_UYVY; - mask3 |= (0x02 << 5); + for (j = 0; j < RESOLUTION_MANY; j++) { + mask2 = 0x0000; + switch (j) { + case AT_720x576: { + if (0x1 & mask1) + continue; + name2 = "_AT_720x576"; + width = 720; + height = 576; break; } - case FMT_YUY2: { - strcpy(&name3[0], "_" STRINGIZE(FMT_YUY2)); - pixelformat = V4L2_PIX_FMT_YUYV; - mask3 |= (0x02 << 5); - mask3 |= 0x0100; + case AT_704x576: { + if (0x1 & mask1) + continue; + name2 = "_AT_704x576"; + width = 704; + height = 576; break; } - case FMT_RGB24: { - strcpy(&name3[0], "_" STRINGIZE(FMT_RGB24)); - pixelformat = V4L2_PIX_FMT_RGB24; - mask3 |= (0x03 << 5); + case AT_640x480: { + name2 = "_AT_640x480"; + width = 640; + height = 480; break; } - case FMT_RGB32: { - strcpy(&name3[0], "_" STRINGIZE(FMT_RGB32)); - pixelformat = V4L2_PIX_FMT_RGB32; - mask3 |= (0x04 << 5); + case AT_720x480: { + if (!(0x1 & mask1)) + continue; + name2 = "_AT_720x480"; + width = 720; + height = 480; break; } - case FMT_BGR24: { - strcpy(&name3[0], "_" STRINGIZE(FMT_BGR24)); - pixelformat = V4L2_PIX_FMT_BGR24; - mask3 |= (0x03 << 5); - mask3 |= 0x0100; + case AT_360x288: { + if (0x1 & mask1) + continue; + name2 = "_AT_360x288"; + width = 360; + height = 288; + mask2 = 0x0800; break; } - case FMT_BGR32: { - strcpy(&name3[0], "_" STRINGIZE(FMT_BGR32)); - pixelformat = V4L2_PIX_FMT_BGR32; - mask3 |= (0x04 << 5); - mask3 |= 0x0100; + case AT_320x240: { + name2 = "_AT_320x240"; + width = 320; + height = 240; + mask2 = 0x0800; + break; + } + case AT_360x240: { + if (!(0x1 & mask1)) + continue; + name2 = "_AT_360x240"; + width = 360; + height = 240; + mask2 = 0x0800; break; } default: - return -3; + return -2; } - bytesperline = width * ((mask3 & 0x00F0) >> 4); - sizeimage = bytesperline * height; - for (m = 0; m < INTERLACE_MANY; m++) { - mask4 = 0x0000; - switch (m) { - case FIELD_NONE: { - strcpy(&name4[0], "-n"); - field = V4L2_FIELD_NONE; + for (k = 0; k < PIXELFORMAT_MANY; k++) { + mask3 = 0x0000; + switch (k) { + case FMT_UYVY: { + name3 = __stringify(FMT_UYVY); + pixelformat = V4L2_PIX_FMT_UYVY; + mask3 |= (0x02 << 5); + break; + } + case FMT_YUY2: { + name3 = __stringify(FMT_YUY2); + pixelformat = V4L2_PIX_FMT_YUYV; + mask3 |= (0x02 << 5); + mask3 |= 0x0100; + break; + } + case FMT_RGB24: { + name3 = __stringify(FMT_RGB24); + pixelformat = V4L2_PIX_FMT_RGB24; + mask3 |= (0x03 << 5); + break; + } + case FMT_RGB32: { + name3 = __stringify(FMT_RGB32); + pixelformat = V4L2_PIX_FMT_RGB32; + mask3 |= (0x04 << 5); break; } - case FIELD_INTERLACED: { - strcpy(&name4[0], "-i"); - mask4 |= 0x1000; - field = V4L2_FIELD_INTERLACED; + case FMT_BGR24: { + name3 = __stringify(FMT_BGR24); + pixelformat = V4L2_PIX_FMT_BGR24; + mask3 |= (0x03 << 5); + mask3 |= 0x0100; + break; + } + case FMT_BGR32: { + name3 = __stringify(FMT_BGR32); + pixelformat = V4L2_PIX_FMT_BGR32; + mask3 |= (0x04 << 5); + mask3 |= 0x0100; break; } default: - return -4; + return -3; } - if (SETTINGS_MANY <= n) - return -5; - strcpy(&easycap_format[n].name[0], &name1[0]); - strcat(&easycap_format[n].name[0], &name2[0]); - strcat(&easycap_format[n].name[0], &name3[0]); - strcat(&easycap_format[n].name[0], &name4[0]); - easycap_format[n].mask = \ + bytesperline = width * ((mask3 & 0x00F0) >> 4); + sizeimage = bytesperline * height; + + for (m = 0; m < INTERLACE_MANY; m++) { + mask4 = 0x0000; + switch (m) { + case FIELD_NONE: { + name4 = "-n"; + field = V4L2_FIELD_NONE; + break; + } + case FIELD_INTERLACED: { + name4 = "-i"; + mask4 |= 0x1000; + field = V4L2_FIELD_INTERLACED; + break; + } + default: + return -4; + } + if (SETTINGS_MANY <= n) + return -5; + + strcpy(easycap_format[n].name, name1); + strcat(easycap_format[n].name, name2); + strcat(easycap_format[n].name, "_"); + strcat(easycap_format[n].name, name3); + strcat(easycap_format[n].name, name4); + easycap_format[n].mask = mask1 | mask2 | mask3 | mask4; - easycap_format[n].v4l2_format\ - .type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - easycap_format[n].v4l2_format\ - .fmt.pix.width = width; - easycap_format[n].v4l2_format\ - .fmt.pix.height = height; - easycap_format[n].v4l2_format\ - .fmt.pix.pixelformat = pixelformat; - easycap_format[n].v4l2_format\ - .fmt.pix.field = field; - easycap_format[n].v4l2_format\ - .fmt.pix.bytesperline = bytesperline; - easycap_format[n].v4l2_format\ - .fmt.pix.sizeimage = sizeimage; - easycap_format[n].v4l2_format\ - .fmt.pix.colorspace = colorspace; - easycap_format[n].v4l2_format\ - .fmt.pix.priv = 0; - n++; + fmt = &easycap_format[n].v4l2_format; + + fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + fmt->fmt.pix.width = width; + fmt->fmt.pix.height = height; + fmt->fmt.pix.pixelformat = pixelformat; + fmt->fmt.pix.field = field; + fmt->fmt.pix.bytesperline = bytesperline; + fmt->fmt.pix.sizeimage = sizeimage; + fmt->fmt.pix.colorspace = colorspace; + fmt->fmt.pix.priv = 0; + n++; + } } } } -} -if ((1 + SETTINGS_MANY) <= n) - return -6; -easycap_format[n].mask = 0xFFFF; -return n; + if ((1 + SETTINGS_MANY) <= n) + return -6; + easycap_format[n].mask = 0xFFFF; + return n; } /*---------------------------------------------------------------------------*/ -struct v4l2_queryctrl easycap_control[] = \ -{{ -.id = V4L2_CID_BRIGHTNESS, -.type = V4L2_CTRL_TYPE_INTEGER, -.name = "Brightness", -.minimum = 0, -.maximum = 255, -.step = 1, -.default_value = SAA_0A_DEFAULT, -.flags = 0, -.reserved = {0, 0} -}, +struct v4l2_queryctrl easycap_control[] = { + { + .id = V4L2_CID_BRIGHTNESS, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Brightness", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = SAA_0A_DEFAULT, + .flags = 0, + .reserved = {0, 0} + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.id = V4L2_CID_CONTRAST, -.type = V4L2_CTRL_TYPE_INTEGER, -.name = "Contrast", -.minimum = 0, -.maximum = 255, -.step = 1, -.default_value = SAA_0B_DEFAULT + 128, -.flags = 0, -.reserved = {0, 0} -}, + { + .id = V4L2_CID_CONTRAST, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Contrast", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = SAA_0B_DEFAULT + 128, + .flags = 0, + .reserved = {0, 0} + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.id = V4L2_CID_SATURATION, -.type = V4L2_CTRL_TYPE_INTEGER, -.name = "Saturation", -.minimum = 0, -.maximum = 255, -.step = 1, -.default_value = SAA_0C_DEFAULT + 128, -.flags = 0, -.reserved = {0, 0} -}, + { + .id = V4L2_CID_SATURATION, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Saturation", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = SAA_0C_DEFAULT + 128, + .flags = 0, + .reserved = {0, 0} + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.id = V4L2_CID_HUE, -.type = V4L2_CTRL_TYPE_INTEGER, -.name = "Hue", -.minimum = 0, -.maximum = 255, -.step = 1, -.default_value = SAA_0D_DEFAULT + 128, -.flags = 0, -.reserved = {0, 0} -}, + { + .id = V4L2_CID_HUE, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Hue", + .minimum = 0, + .maximum = 255, + .step = 1, + .default_value = SAA_0D_DEFAULT + 128, + .flags = 0, + .reserved = {0, 0} + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.id = V4L2_CID_AUDIO_VOLUME, -.type = V4L2_CTRL_TYPE_INTEGER, -.name = "Volume", -.minimum = 0, -.maximum = 31, -.step = 1, -.default_value = 16, -.flags = 0, -.reserved = {0, 0} -}, + { + .id = V4L2_CID_AUDIO_VOLUME, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Volume", + .minimum = 0, + .maximum = 31, + .step = 1, + .default_value = 16, + .flags = 0, + .reserved = {0, 0} + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.id = V4L2_CID_AUDIO_MUTE, -.type = V4L2_CTRL_TYPE_BOOLEAN, -.name = "Mute", -.default_value = true, -.flags = 0, -.reserved = {0, 0} -}, + { + .id = V4L2_CID_AUDIO_MUTE, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Mute", + .default_value = true, + .flags = 0, + .reserved = {0, 0} + }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -{ -.id = 0xFFFFFFFF -} + { + .id = 0xFFFFFFFF + } }; /*****************************************************************************/ diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c index 24d8bb4e449..a3402b00a8b 100644 --- a/drivers/staging/easycap/easycap_sound.c +++ b/drivers/staging/easycap/easycap_sound.c @@ -29,1009 +29,681 @@ /*****************************************************************************/ #include "easycap.h" -#include "easycap_debug.h" -#include "easycap_sound.h" + +#ifndef CONFIG_EASYCAP_OSS +/*--------------------------------------------------------------------------*/ +/* + * PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE + */ +/*--------------------------------------------------------------------------*/ +static const struct snd_pcm_hardware alsa_hardware = { + .info = SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP_VALID, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000, + .rate_min = 32000, + .rate_max = 48000, + .channels_min = 2, + .channels_max = 2, + .buffer_bytes_max = PAGE_SIZE * + PAGES_PER_AUDIO_FRAGMENT * + AUDIO_FRAGMENT_MANY, + .period_bytes_min = PAGE_SIZE * PAGES_PER_AUDIO_FRAGMENT, + .period_bytes_max = PAGE_SIZE * PAGES_PER_AUDIO_FRAGMENT * 2, + .periods_min = AUDIO_FRAGMENT_MANY, + .periods_max = AUDIO_FRAGMENT_MANY * 2, +}; + /*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* - * ON COMPLETION OF AN AUDIO URB ITS DATA IS COPIED TO THE AUDIO BUFFERS + * ON COMPLETION OF AN AUDIO URB ITS DATA IS COPIED TO THE DAM BUFFER * PROVIDED peasycap->audio_idle IS ZERO. REGARDLESS OF THIS BEING TRUE, * IT IS RESUBMITTED PROVIDED peasycap->audio_isoc_streaming IS NOT ZERO. */ /*---------------------------------------------------------------------------*/ void -easysnd_complete(struct urb *purb) +easycap_alsa_complete(struct urb *purb) { -struct easycap *peasycap; -struct data_buffer *paudio_buffer; -__u8 *p1, *p2; -__s16 s16; -int i, j, more, much, leap, rc; -#if defined(UPSAMPLE) -int k; -__s16 oldaudio, newaudio, delta; + struct easycap *peasycap; + struct snd_pcm_substream *pss; + struct snd_pcm_runtime *prt; + int dma_bytes, fragment_bytes; + int isfragment; + u8 *p1, *p2; + s16 tmp; + int i, j, more, much, rc; +#ifdef UPSAMPLE + int k; + s16 oldaudio, newaudio, delta; #endif /*UPSAMPLE*/ -JOT(16, "\n"); - -if (NULL == purb) { - SAY("ERROR: purb is NULL\n"); - return; -} -peasycap = purb->context; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap\n"); - return; -} - -much = 0; + JOT(16, "\n"); -if (peasycap->audio_idle) { - JOM(16, "%i=audio_idle %i=audio_isoc_streaming\n", \ - peasycap->audio_idle, peasycap->audio_isoc_streaming); - if (peasycap->audio_isoc_streaming) { - rc = usb_submit_urb(purb, GFP_ATOMIC); - if (0 != rc) { - if (-ENODEV != rc) - SAM("ERROR: while %i=audio_idle, " \ - "usb_submit_urb() failed with rc:\n", \ - peasycap->audio_idle); - switch (rc) { - case -ENOMEM: { - SAM("-ENOMEM\n"); - break; - } - case -ENODEV: { - break; - } - case -ENXIO: { - SAM("-ENXIO\n"); - break; - } - case -EINVAL: { - SAM("-EINVAL\n"); - break; - } - case -EAGAIN: { - SAM("-EAGAIN\n"); - break; - } - case -EFBIG: { - SAM("-EFBIG\n"); - break; - } - case -EPIPE: { - SAM("-EPIPE\n"); - break; - } - case -EMSGSIZE: { - SAM("-EMSGSIZE\n"); - break; - } - case -ENOSPC: { - SAM("-ENOSPC\n"); - break; - } - default: { - SAM("unknown error: 0x%08X\n", rc); - break; - } - } - } - } -return; -} -/*---------------------------------------------------------------------------*/ -if (purb->status) { - if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) { - JOM(16, "urb status -ESHUTDOWN or -ENOENT\n"); + if (!purb) { + SAY("ERROR: purb is NULL\n"); return; } - SAM("ERROR: non-zero urb status:\n"); - switch (purb->status) { - case -EINPROGRESS: { - SAM("-EINPROGRESS\n"); - break; - } - case -ENOSR: { - SAM("-ENOSR\n"); - break; - } - case -EPIPE: { - SAM("-EPIPE\n"); - break; - } - case -EOVERFLOW: { - SAM("-EOVERFLOW\n"); - break; - } - case -EPROTO: { - SAM("-EPROTO\n"); - break; - } - case -EILSEQ: { - SAM("-EILSEQ\n"); - break; - } - case -ETIMEDOUT: { - SAM("-ETIMEDOUT\n"); - break; - } - case -EMSGSIZE: { - SAM("-EMSGSIZE\n"); - break; - } - case -EOPNOTSUPP: { - SAM("-EOPNOTSUPP\n"); - break; - } - case -EPFNOSUPPORT: { - SAM("-EPFNOSUPPORT\n"); - break; - } - case -EAFNOSUPPORT: { - SAM("-EAFNOSUPPORT\n"); - break; - } - case -EADDRINUSE: { - SAM("-EADDRINUSE\n"); - break; - } - case -EADDRNOTAVAIL: { - SAM("-EADDRNOTAVAIL\n"); - break; - } - case -ENOBUFS: { - SAM("-ENOBUFS\n"); - break; - } - case -EISCONN: { - SAM("-EISCONN\n"); - break; - } - case -ENOTCONN: { - SAM("-ENOTCONN\n"); - break; - } - case -ESHUTDOWN: { - SAM("-ESHUTDOWN\n"); - break; - } - case -ENOENT: { - SAM("-ENOENT\n"); - break; - } - case -ECONNRESET: { - SAM("-ECONNRESET\n"); - break; - } - case -ENOSPC: { - SAM("ENOSPC\n"); - break; - } - default: { - SAM("unknown error code 0x%08X\n", purb->status); - break; + peasycap = purb->context; + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return; } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return; } -/*---------------------------------------------------------------------------*/ -/* - * RESUBMIT THIS URB AFTER AN ERROR - * - * (THIS IS DUPLICATE CODE TO REDUCE INDENTATION OF THE NO-ERROR PATH) - */ -/*---------------------------------------------------------------------------*/ - if (peasycap->audio_isoc_streaming) { - rc = usb_submit_urb(purb, GFP_ATOMIC); - if (0 != rc) { - SAM("ERROR: while %i=audio_idle, usb_submit_urb() " - "failed with rc:\n", peasycap->audio_idle); - switch (rc) { - case -ENOMEM: { - SAM("-ENOMEM\n"); - break; - } - case -ENODEV: { - SAM("-ENODEV\n"); - break; - } - case -ENXIO: { - SAM("-ENXIO\n"); - break; - } - case -EINVAL: { - SAM("-EINVAL\n"); - break; - } - case -EAGAIN: { - SAM("-EAGAIN\n"); - break; - } - case -EFBIG: { - SAM("-EFBIG\n"); - break; - } - case -EPIPE: { - SAM("-EPIPE\n"); - break; - } - case -EMSGSIZE: { - SAM("-EMSGSIZE\n"); - break; - } - default: { - SAM("0x%08X\n", rc); break; - } - } + much = 0; + if (peasycap->audio_idle) { + JOM(16, "%i=audio_idle %i=audio_isoc_streaming\n", + peasycap->audio_idle, peasycap->audio_isoc_streaming); + if (peasycap->audio_isoc_streaming) + goto resubmit; + } +/*---------------------------------------------------------------------------*/ + pss = peasycap->psubstream; + if (!pss) + goto resubmit; + prt = pss->runtime; + if (!prt) + goto resubmit; + dma_bytes = (int)prt->dma_bytes; + if (0 == dma_bytes) + goto resubmit; + fragment_bytes = 4 * ((int)prt->period_size); + if (0 == fragment_bytes) + goto resubmit; +/* -------------------------------------------------------------------------*/ + if (purb->status) { + if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) { + JOM(16, "urb status -ESHUTDOWN or -ENOENT\n"); + return; } + SAM("ERROR: non-zero urb status: -%s: %d\n", + strerror(purb->status), purb->status); + goto resubmit; } - return; -} /*---------------------------------------------------------------------------*/ /* * PROCEED HERE WHEN NO ERROR */ /*---------------------------------------------------------------------------*/ -#if defined(UPSAMPLE) -oldaudio = peasycap->oldaudio; + +#ifdef UPSAMPLE + oldaudio = peasycap->oldaudio; #endif /*UPSAMPLE*/ -for (i = 0; i < purb->number_of_packets; i++) { - switch (purb->iso_frame_desc[i].status) { - case 0: { - break; - } - case -ENOENT: { - SAM("-ENOENT\n"); - break; - } - case -EINPROGRESS: { - SAM("-EINPROGRESS\n"); - break; - } - case -EPROTO: { - SAM("-EPROTO\n"); - break; - } - case -EILSEQ: { - SAM("-EILSEQ\n"); - break; - } - case -ETIME: { - SAM("-ETIME\n"); - break; - } - case -ETIMEDOUT: { - SAM("-ETIMEDOUT\n"); - break; - } - case -EPIPE: { - SAM("-EPIPE\n"); - break; - } - case -ECOMM: { - SAM("-ECOMM\n"); - break; - } - case -ENOSR: { - SAM("-ENOSR\n"); - break; - } - case -EOVERFLOW: { - SAM("-EOVERFLOW\n"); - break; - } - case -EREMOTEIO: { - SAM("-EREMOTEIO\n"); - break; - } - case -ENODEV: { - SAM("-ENODEV\n"); - break; - } - case -EXDEV: { - SAM("-EXDEV\n"); - break; - } - case -EINVAL: { - SAM("-EINVAL\n"); - break; - } - case -ECONNRESET: { - SAM("-ECONNRESET\n"); - break; - } - case -ENOSPC: { - SAM("-ENOSPC\n"); - break; - } - case -ESHUTDOWN: { - SAM("-ESHUTDOWN\n"); - break; - } - default: { - SAM("unknown error:0x%08X\n", purb->iso_frame_desc[i].status); - break; - } - } - if (!purb->iso_frame_desc[i].status) { + for (i = 0; i < purb->number_of_packets; i++) { + if (purb->iso_frame_desc[i].status < 0) { + SAM("-%s: %d\n", + strerror(purb->iso_frame_desc[i].status), + purb->iso_frame_desc[i].status); + } + if (purb->iso_frame_desc[i].status) { + JOM(12, "discarding audio samples because " + "%i=purb->iso_frame_desc[i].status\n", + purb->iso_frame_desc[i].status); + continue; + } more = purb->iso_frame_desc[i].actual_length; - -#if defined(TESTTONE) - if (!more) - more = purb->iso_frame_desc[i].length; -#endif - - if (!more) + if (more == 0) { peasycap->audio_mt++; - else { - if (peasycap->audio_mt) { - JOM(16, "%4i empty audio urb frames\n", \ - peasycap->audio_mt); - peasycap->audio_mt = 0; - } + continue; + } + if (0 > more) { + SAM("MISTAKE: more is negative\n"); + return; + } - p1 = (__u8 *)(purb->transfer_buffer + \ - purb->iso_frame_desc[i].offset); + if (peasycap->audio_mt) { + JOM(12, "%4i empty audio urb frames\n", + peasycap->audio_mt); + peasycap->audio_mt = 0; + } - leap = 0; - p1 += leap; - more -= leap; -/*---------------------------------------------------------------------------*/ -/* - * COPY more BYTES FROM ISOC BUFFER TO AUDIO BUFFER, - * CONVERTING 8-BIT MONO TO 16-BIT SIGNED LITTLE-ENDIAN SAMPLES IF NECESSARY - */ -/*---------------------------------------------------------------------------*/ - while (more) { - if (0 > more) { - SAM("easysnd_complete: MISTAKE: " \ - "more is negative\n"); - return; + p1 = (u8 *)(purb->transfer_buffer + + purb->iso_frame_desc[i].offset); + + /* + * COPY more BYTES FROM ISOC BUFFER + * TO THE DMA BUFFER, CONVERTING + * 8-BIT MONO TO 16-BIT SIGNED + * LITTLE-ENDIAN SAMPLES IF NECESSARY + */ + while (more) { + much = dma_bytes - peasycap->dma_fill; + if (0 > much) { + SAM("MISTAKE: much is negative\n"); + return; + } + if (0 == much) { + peasycap->dma_fill = 0; + peasycap->dma_next = fragment_bytes; + JOM(8, "wrapped dma buffer\n"); + } + if (!peasycap->microphone) { + if (much > more) + much = more; + memcpy(prt->dma_area + peasycap->dma_fill, + p1, much); + p1 += much; + more -= much; + } else { +#ifdef UPSAMPLE + if (much % 16) + JOM(8, "MISTAKE? much" + " is not divisible by 16\n"); + if (much > (16 * more)) + much = 16 * more; + p2 = (u8 *)(prt->dma_area + peasycap->dma_fill); + + for (j = 0; j < (much / 16); j++) { + newaudio = ((int) *p1) - 128; + newaudio = 128 * newaudio; + + delta = (newaudio - oldaudio) / 4; + tmp = oldaudio + delta; + + for (k = 0; k < 4; k++) { + *p2 = (0x00FF & tmp); + *(p2 + 1) = (0xFF00 & tmp) >> 8; + p2 += 2; + *p2 = (0x00FF & tmp); + *(p2 + 1) = (0xFF00 & tmp) >> 8; + p2 += 2; + tmp += delta; + } + p1++; + more--; + oldaudio = tmp; } - if (peasycap->audio_buffer_page_many <= \ - peasycap->audio_fill) { - SAM("ERROR: bad " \ - "peasycap->audio_fill\n"); - return; +#else /*!UPSAMPLE*/ + if (much > (2 * more)) + much = 2 * more; + p2 = (u8 *)(prt->dma_area + peasycap->dma_fill); + + for (j = 0; j < (much / 2); j++) { + tmp = ((int) *p1) - 128; + tmp = 128 * tmp; + *p2 = (0x00FF & tmp); + *(p2 + 1) = (0xFF00 & tmp) >> 8; + p1++; + p2 += 2; + more--; } - - paudio_buffer = &peasycap->audio_buffer\ - [peasycap->audio_fill]; - if (PAGE_SIZE < (paudio_buffer->pto - \ - paudio_buffer->pgo)) { - SAM("ERROR: bad paudio_buffer->pto\n"); +#endif /*UPSAMPLE*/ + } + peasycap->dma_fill += much; + if (peasycap->dma_fill >= peasycap->dma_next) { + isfragment = peasycap->dma_fill / fragment_bytes; + if (0 > isfragment) { + SAM("MISTAKE: isfragment is negative\n"); return; } - if (PAGE_SIZE == (paudio_buffer->pto - \ - paudio_buffer->pgo)) { - -#if defined(TESTTONE) - easysnd_testtone(peasycap, \ - peasycap->audio_fill); -#endif /*TESTTONE*/ - - paudio_buffer->pto = \ - paudio_buffer->pgo; - (peasycap->audio_fill)++; - if (peasycap->\ - audio_buffer_page_many <= \ - peasycap->audio_fill) - peasycap->audio_fill = 0; - - JOM(12, "bumped peasycap->" \ - "audio_fill to %i\n", \ - peasycap->audio_fill); - - paudio_buffer = &peasycap->\ - audio_buffer\ - [peasycap->audio_fill]; - paudio_buffer->pto = \ - paudio_buffer->pgo; - - if (!(peasycap->audio_fill % \ - peasycap->\ - audio_pages_per_fragment)) { - JOM(12, "wakeup call on wq_" \ - "audio, %i=frag reading %i" \ - "=fragment fill\n", \ - (peasycap->audio_read / \ - peasycap->\ - audio_pages_per_fragment), \ - (peasycap->audio_fill / \ - peasycap->\ - audio_pages_per_fragment)); - wake_up_interruptible\ - (&(peasycap->wq_audio)); - } + peasycap->dma_read = (isfragment - 1) * fragment_bytes; + peasycap->dma_next = (isfragment + 1) * fragment_bytes; + if (dma_bytes < peasycap->dma_next) + peasycap->dma_next = fragment_bytes; + + if (0 <= peasycap->dma_read) { + JOM(8, "snd_pcm_period_elapsed(), %i=" + "isfragment\n", isfragment); + snd_pcm_period_elapsed(pss); } - - much = PAGE_SIZE - (int)(paudio_buffer->pto -\ - paudio_buffer->pgo); - - if (false == peasycap->microphone) { - if (much > more) - much = more; - - memcpy(paudio_buffer->pto, p1, much); - p1 += much; - more -= much; - } else { -#if defined(UPSAMPLE) - if (much % 16) - JOM(8, "MISTAKE? much" \ - " is not divisible by 16\n"); - if (much > (16 * \ - more)) - much = 16 * \ - more; - p2 = (__u8 *)paudio_buffer->pto; - - for (j = 0; j < (much/16); j++) { - newaudio = ((int) *p1) - 128; - newaudio = 128 * \ - newaudio; - - delta = (newaudio - oldaudio) \ - / 4; - s16 = oldaudio + delta; - - for (k = 0; k < 4; k++) { - *p2 = (0x00FF & s16); - *(p2 + 1) = (0xFF00 & \ - s16) >> 8; - p2 += 2; - *p2 = (0x00FF & s16); - *(p2 + 1) = (0xFF00 & \ - s16) >> 8; - p2 += 2; - - s16 += delta; - } - p1++; - more--; - oldaudio = s16; - } -#else - if (much > (2 * more)) - much = 2 * more; - p2 = (__u8 *)paudio_buffer->pto; - - for (j = 0; j < (much / 2); j++) { - s16 = ((int) *p1) - 128; - s16 = 128 * \ - s16; - *p2 = (0x00FF & s16); - *(p2 + 1) = (0xFF00 & s16) >> \ - 8; - p1++; p2 += 2; - more--; - } -#endif /*UPSAMPLE*/ - } - (paudio_buffer->pto) += much; } } - } else { - JOM(12, "discarding audio samples because " \ - "%i=purb->iso_frame_desc[i].status\n", \ - purb->iso_frame_desc[i].status); - } -#if defined(UPSAMPLE) -peasycap->oldaudio = oldaudio; +#ifdef UPSAMPLE + peasycap->oldaudio = oldaudio; #endif /*UPSAMPLE*/ -} + } /*---------------------------------------------------------------------------*/ /* - * RESUBMIT THIS URB AFTER NO ERROR + * RESUBMIT THIS URB */ /*---------------------------------------------------------------------------*/ -if (peasycap->audio_isoc_streaming) { +resubmit: + if (peasycap->audio_isoc_streaming == 0) + return; + rc = usb_submit_urb(purb, GFP_ATOMIC); - if (0 != rc) { - if (-ENODEV != rc) { - SAM("ERROR: while %i=audio_idle, " \ - "usb_submit_urb() failed " \ - "with rc:\n", peasycap->audio_idle); - } - switch (rc) { - case -ENOMEM: { - SAM("-ENOMEM\n"); - break; - } - case -ENODEV: { - break; - } - case -ENXIO: { - SAM("-ENXIO\n"); - break; - } - case -EINVAL: { - SAM("-EINVAL\n"); - break; - } - case -EAGAIN: { - SAM("-EAGAIN\n"); - break; - } - case -EFBIG: { - SAM("-EFBIG\n"); - break; - } - case -EPIPE: { - SAM("-EPIPE\n"); - break; - } - case -EMSGSIZE: { - SAM("-EMSGSIZE\n"); - break; - } - case -ENOSPC: { - SAM("-ENOSPC\n"); - break; - } - default: { - SAM("unknown error: 0x%08X\n", rc); - break; - } + if (rc) { + if ((-ENODEV != rc) && (-ENOENT != rc)) { + SAM("ERROR: while %i=audio_idle, usb_submit_urb failed " + "with rc: -%s :%d\n", + peasycap->audio_idle, strerror(rc), rc); } + if (0 < peasycap->audio_isoc_streaming) + peasycap->audio_isoc_streaming--; } -} -return; + return; } /*****************************************************************************/ -/*---------------------------------------------------------------------------*/ -/* - * THE AUDIO URBS ARE SUBMITTED AT THIS EARLY STAGE SO THAT IT IS POSSIBLE TO - * STREAM FROM /dev/easysnd1 WITH SIMPLE PROGRAMS SUCH AS cat WHICH DO NOT - * HAVE AN IOCTL INTERFACE. - */ -/*---------------------------------------------------------------------------*/ -int -easysnd_open(struct inode *inode, struct file *file) +static int easycap_alsa_open(struct snd_pcm_substream *pss) { -struct usb_interface *pusb_interface; -struct easycap *peasycap; -int subminor, rc; -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if defined(EASYCAP_IS_VIDEODEV_CLIENT) -#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) -struct v4l2_device *pv4l2_device; -#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -JOT(4, "begins\n"); - -subminor = iminor(inode); - -pusb_interface = usb_find_interface(&easycap_usb_driver, subminor); -if (NULL == pusb_interface) { - SAY("ERROR: pusb_interface is NULL\n"); - SAY("ending unsuccessfully\n"); - return -1; -} -peasycap = usb_get_intfdata(pusb_interface); -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - SAY("ending unsuccessfully\n"); - return -1; -} -/*---------------------------------------------------------------------------*/ -#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) -# -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#else -#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) -/*---------------------------------------------------------------------------*/ -/* - * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS - * BEEN WRITTEN BY THE CALL TO usb_set_intfdata() IN easycap_usb_probe(), - * REPLACING IT WITH A POINTER TO THE EMBEDDED v4l2_device STRUCTURE. - * TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED. -*/ -/*---------------------------------------------------------------------------*/ -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - pv4l2_device = usb_get_intfdata(pusb_interface); - if ((struct v4l2_device *)NULL == pv4l2_device) { - SAY("ERROR: pv4l2_device is NULL\n"); + struct snd_pcm *psnd_pcm; + struct snd_card *psnd_card; + struct easycap *peasycap; + + JOT(4, "\n"); + if (!pss) { + SAY("ERROR: pss is NULL\n"); + return -EFAULT; + } + psnd_pcm = pss->pcm; + if (!psnd_pcm) { + SAY("ERROR: psnd_pcm is NULL\n"); + return -EFAULT; + } + psnd_card = psnd_pcm->card; + if (!psnd_card) { + SAY("ERROR: psnd_card is NULL\n"); return -EFAULT; } - peasycap = (struct easycap *) \ - container_of(pv4l2_device, struct easycap, v4l2_device); -} -#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ -# -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/*---------------------------------------------------------------------------*/ -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); - return -EFAULT; -} -/*---------------------------------------------------------------------------*/ - -file->private_data = peasycap; -/*---------------------------------------------------------------------------*/ -/* - * INITIALIZATION - */ -/*---------------------------------------------------------------------------*/ -JOM(4, "starting initialization\n"); + peasycap = psnd_card->private_data; + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return -EFAULT; + } + if (peasycap->psnd_card != psnd_card) { + SAM("ERROR: bad peasycap->psnd_card\n"); + return -EFAULT; + } + if (peasycap->psubstream) { + SAM("ERROR: bad peasycap->psubstream\n"); + return -EFAULT; + } + pss->private_data = peasycap; + peasycap->psubstream = pss; + pss->runtime->hw = peasycap->alsa_hardware; + pss->runtime->private_data = peasycap; + pss->private_data = peasycap; -if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -ENODEV; + if (0 != easycap_sound_setup(peasycap)) { + JOM(4, "ending unsuccessfully\n"); + return -EFAULT; + } + JOM(4, "ending successfully\n"); + return 0; } -JOM(16, "0x%08lX=peasycap->pusb_device\n", (long int)peasycap->pusb_device); - -rc = audio_setup(peasycap); -if (0 <= rc) - JOM(8, "audio_setup() returned %i\n", rc); -else - JOM(8, "easysnd open(): ERROR: audio_setup() returned %i\n", rc); +/*****************************************************************************/ +static int easycap_alsa_close(struct snd_pcm_substream *pss) +{ + struct easycap *peasycap; -if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device has become NULL\n"); - return -ENODEV; -} -/*---------------------------------------------------------------------------*/ -if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device has become NULL\n"); - return -ENODEV; + JOT(4, "\n"); + if (!pss) { + SAY("ERROR: pss is NULL\n"); + return -EFAULT; + } + peasycap = snd_pcm_substream_chip(pss); + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return -EFAULT; + } + pss->private_data = NULL; + peasycap->psubstream = NULL; + JOT(4, "ending successfully\n"); + return 0; } -rc = usb_set_interface(peasycap->pusb_device, peasycap->audio_interface, \ - peasycap->audio_altsetting_on); -JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", peasycap->audio_interface, \ - peasycap->audio_altsetting_on, rc); - -rc = wakeup_device(peasycap->pusb_device); -if (0 == rc) - JOM(8, "wakeup_device() returned %i\n", rc); -else - JOM(8, "ERROR: wakeup_device() returned %i\n", rc); - -peasycap->audio_eof = 0; -peasycap->audio_idle = 0; - -peasycap->timeval1.tv_sec = 0; -peasycap->timeval1.tv_usec = 0; - -submit_audio_urbs(peasycap); +/*****************************************************************************/ +static int easycap_alsa_vmalloc(struct snd_pcm_substream *pss, size_t sz) +{ + struct snd_pcm_runtime *prt; + JOT(4, "\n"); -JOM(4, "finished initialization\n"); -return 0; + if (!pss) { + SAY("ERROR: pss is NULL\n"); + return -EFAULT; + } + prt = pss->runtime; + if (!prt) { + SAY("ERROR: substream.runtime is NULL\n"); + return -EFAULT; + } + if (prt->dma_area) { + if (prt->dma_bytes > sz) + return 0; + vfree(prt->dma_area); + } + prt->dma_area = vmalloc(sz); + if (!prt->dma_area) + return -ENOMEM; + prt->dma_bytes = sz; + return 0; } /*****************************************************************************/ -int -easysnd_release(struct inode *inode, struct file *file) +static int easycap_alsa_hw_params(struct snd_pcm_substream *pss, + struct snd_pcm_hw_params *phw) { -struct easycap *peasycap; + int rc; -JOT(4, "begins\n"); - -peasycap = file->private_data; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL.\n"); - return -EFAULT; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); - return -EFAULT; -} -if (0 != kill_audio_urbs(peasycap)) { - SAM("ERROR: kill_audio_urbs() failed\n"); - return -EFAULT; -} -JOM(4, "ending successfully\n"); -return 0; + JOT(4, "%i\n", (params_buffer_bytes(phw))); + if (!pss) { + SAY("ERROR: pss is NULL\n"); + return -EFAULT; + } + rc = easycap_alsa_vmalloc(pss, params_buffer_bytes(phw)); + if (rc) + return rc; + return 0; } /*****************************************************************************/ -ssize_t -easysnd_read(struct file *file, char __user *puserspacebuffer, \ - size_t kount, loff_t *poff) +static int easycap_alsa_hw_free(struct snd_pcm_substream *pss) { -struct timeval timeval; -long long int above, below, mean; -struct signed_div_result sdr; -unsigned char *p0; -long int kount1, more, rc, l0, lm; -int fragment, kd; -struct easycap *peasycap; -struct data_buffer *pdata_buffer; -size_t szret; - -/*---------------------------------------------------------------------------*/ -/* - * DO A BLOCKING READ TO TRANSFER DATA TO USER SPACE. - * - ****************************************************************************** - ***** N.B. IF THIS FUNCTION RETURNS 0, NOTHING IS SEEN IN USER SPACE. ****** - ***** THIS CONDITION SIGNIFIES END-OF-FILE. ****** - ****************************************************************************** - */ -/*---------------------------------------------------------------------------*/ - -JOT(8, "===== easysnd_read(): kount=%i, *poff=%i\n", (int)kount, (int)(*poff)); + struct snd_pcm_runtime *prt; + JOT(4, "\n"); -if (NULL == file) { - SAY("ERROR: file is NULL\n"); - return -ERESTARTSYS; -} -peasycap = file->private_data; -if (NULL == peasycap) { - SAY("ERROR in easysnd_read(): peasycap is NULL\n"); - return -EFAULT; -} -if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); - return -EFAULT; -} -if (NULL == peasycap->pusb_device) { - SAY("ERROR in easysnd_read(): peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -kd = isdongle(peasycap); -if (0 <= kd && DONGLE_MANY > kd) { - if (mutex_lock_interruptible(&(easycap_dongle[kd].mutex_audio))) { - SAY("ERROR: cannot lock easycap_dongle[%i].mutex_audio\n", kd); - return -ERESTARTSYS; + if (!pss) { + SAY("ERROR: pss is NULL\n"); + return -EFAULT; } - JOM(4, "locked easycap_dongle[%i].mutex_audio\n", kd); -/*---------------------------------------------------------------------------*/ -/* - * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap, - * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. - * IF NECESSARY, BAIL OUT. -*/ -/*---------------------------------------------------------------------------*/ - if (kd != isdongle(peasycap)) - return -ERESTARTSYS; - if (NULL == file) { - SAY("ERROR: file is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -ERESTARTSYS; + prt = pss->runtime; + if (!prt) { + SAY("ERROR: substream.runtime is NULL\n"); + return -EFAULT; + } + if (prt->dma_area) { + JOT(8, "prt->dma_area = %p\n", prt->dma_area); + vfree(prt->dma_area); + prt->dma_area = NULL; + } else + JOT(8, "dma_area already freed\n"); + return 0; +} +/*****************************************************************************/ +static int easycap_alsa_prepare(struct snd_pcm_substream *pss) +{ + struct easycap *peasycap; + struct snd_pcm_runtime *prt; + + JOT(4, "\n"); + if (!pss) { + SAY("ERROR: pss is NULL\n"); + return -EFAULT; } - peasycap = file->private_data; - if (NULL == peasycap) { + prt = pss->runtime; + peasycap = snd_pcm_substream_chip(pss); + if (!peasycap) { SAY("ERROR: peasycap is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -ERESTARTSYS; + return -EFAULT; } if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { - SAY("ERROR: bad peasycap: 0x%08lX\n", \ - (unsigned long int) peasycap); - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -ERESTARTSYS; + SAY("ERROR: bad peasycap\n"); + return -EFAULT; } - if (NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -ERESTARTSYS; + + JOM(16, "ALSA decides %8i Hz=rate\n", pss->runtime->rate); + JOM(16, "ALSA decides %8ld =period_size\n", pss->runtime->period_size); + JOM(16, "ALSA decides %8i =periods\n", pss->runtime->periods); + JOM(16, "ALSA decides %8ld =buffer_size\n", pss->runtime->buffer_size); + JOM(16, "ALSA decides %8zd =dma_bytes\n", pss->runtime->dma_bytes); + JOM(16, "ALSA decides %8ld =boundary\n", pss->runtime->boundary); + JOM(16, "ALSA decides %8i =period_step\n", pss->runtime->period_step); + JOM(16, "ALSA decides %8i =sample_bits\n", pss->runtime->sample_bits); + JOM(16, "ALSA decides %8i =frame_bits\n", pss->runtime->frame_bits); + JOM(16, "ALSA decides %8ld =min_align\n", pss->runtime->min_align); + JOM(12, "ALSA decides %8ld =hw_ptr_base\n", pss->runtime->hw_ptr_base); + JOM(12, "ALSA decides %8ld =hw_ptr_interrupt\n", + pss->runtime->hw_ptr_interrupt); + + if (prt->dma_bytes != 4 * ((int)prt->period_size) * ((int)prt->periods)) { + SAY("MISTAKE: unexpected ALSA parameters\n"); + return -ENOENT; } -} else { -/*---------------------------------------------------------------------------*/ -/* - * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE - * ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED. BAIL OUT. -*/ -/*---------------------------------------------------------------------------*/ - return -ERESTARTSYS; + return 0; } -/*---------------------------------------------------------------------------*/ -if (file->f_flags & O_NONBLOCK) - JOT(16, "NONBLOCK kount=%i, *poff=%i\n", (int)kount, (int)(*poff)); -else - JOT(8, "BLOCKING kount=%i, *poff=%i\n", (int)kount, (int)(*poff)); - -if ((0 > peasycap->audio_read) || \ - (peasycap->audio_buffer_page_many <= peasycap->audio_read)) { - SAM("ERROR: peasycap->audio_read out of range\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -EFAULT; -} -pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read]; -if ((struct data_buffer *)NULL == pdata_buffer) { - SAM("ERROR: pdata_buffer is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -EFAULT; +/*****************************************************************************/ +static int easycap_alsa_ack(struct snd_pcm_substream *pss) +{ + return 0; } -JOM(12, "before wait, %i=frag read %i=frag fill\n", \ - (peasycap->audio_read / peasycap->audio_pages_per_fragment), \ - (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); -fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment); -while ((fragment == (peasycap->audio_fill / \ - peasycap->audio_pages_per_fragment)) || \ - (0 == (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))) { - if (file->f_flags & O_NONBLOCK) { - JOM(16, "returning -EAGAIN as instructed\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -EAGAIN; +/*****************************************************************************/ +static int easycap_alsa_trigger(struct snd_pcm_substream *pss, int cmd) +{ + struct easycap *peasycap; + int retval; + + JOT(4, "%i=cmd cf %i=START %i=STOP\n", cmd, SNDRV_PCM_TRIGGER_START, + SNDRV_PCM_TRIGGER_STOP); + if (!pss) { + SAY("ERROR: pss is NULL\n"); + return -EFAULT; } - rc = wait_event_interruptible(peasycap->wq_audio, \ - (peasycap->audio_idle || peasycap->audio_eof || \ - ((fragment != (peasycap->audio_fill / \ - peasycap->audio_pages_per_fragment)) && \ - (0 < (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))))); - if (0 != rc) { - SAM("aborted by signal\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -ERESTARTSYS; + peasycap = snd_pcm_substream_chip(pss); + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; } - if (peasycap->audio_eof) { - JOM(8, "returning 0 because %i=audio_eof\n", \ - peasycap->audio_eof); - kill_audio_urbs(peasycap); - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return 0; + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return -EFAULT; } - if (peasycap->audio_idle) { - JOM(16, "returning 0 because %i=audio_idle\n", \ - peasycap->audio_idle); - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return 0; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: { + peasycap->audio_idle = 0; + break; } - if (!peasycap->audio_isoc_streaming) { - JOM(16, "returning 0 because audio urbs not streaming\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return 0; + case SNDRV_PCM_TRIGGER_STOP: { + peasycap->audio_idle = 1; + break; } + default: + retval = -EINVAL; + } + return 0; } -JOM(12, "after wait, %i=frag read %i=frag fill\n", \ - (peasycap->audio_read / peasycap->audio_pages_per_fragment), \ - (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); -szret = (size_t)0; -while (fragment == (peasycap->audio_read / \ - peasycap->audio_pages_per_fragment)) { - if (NULL == pdata_buffer->pgo) { - SAM("ERROR: pdata_buffer->pgo is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); +/*****************************************************************************/ +static snd_pcm_uframes_t easycap_alsa_pointer(struct snd_pcm_substream *pss) +{ + struct easycap *peasycap; + snd_pcm_uframes_t offset; + + JOT(16, "\n"); + if (!pss) { + SAY("ERROR: pss is NULL\n"); return -EFAULT; } - if (NULL == pdata_buffer->pto) { - SAM("ERROR: pdata_buffer->pto is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); + peasycap = snd_pcm_substream_chip(pss); + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } - kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo); - if (0 > kount1) { - SAM("easysnd_read: MISTAKE: kount1 is negative\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -ERESTARTSYS; + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return -EFAULT; } - if (!kount1) { - (peasycap->audio_read)++; - if (peasycap->audio_buffer_page_many <= peasycap->audio_read) - peasycap->audio_read = 0; - JOM(12, "bumped peasycap->audio_read to %i\n", \ - peasycap->audio_read); - - if (fragment != (peasycap->audio_read / \ - peasycap->audio_pages_per_fragment)) - break; - - if ((0 > peasycap->audio_read) || \ - (peasycap->audio_buffer_page_many <= \ - peasycap->audio_read)) { - SAM("ERROR: peasycap->audio_read out of range\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -EFAULT; - } - pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read]; - if ((struct data_buffer *)NULL == pdata_buffer) { - SAM("ERROR: pdata_buffer is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -EFAULT; - } - if (NULL == pdata_buffer->pgo) { - SAM("ERROR: pdata_buffer->pgo is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -EFAULT; - } - if (NULL == pdata_buffer->pto) { - SAM("ERROR: pdata_buffer->pto is NULL\n"); - mutex_unlock(&easycap_dongle[kd].mutex_audio); - return -EFAULT; - } - kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo); + if ((0 != peasycap->audio_eof) || (0 != peasycap->audio_idle)) { + JOM(8, "returning -EIO because " + "%i=audio_idle %i=audio_eof\n", + peasycap->audio_idle, peasycap->audio_eof); + return -EIO; } - JOM(12, "ready to send %li bytes\n", (long int) kount1); - JOM(12, "still to send %li bytes\n", (long int) kount); - more = kount1; - if (more > kount) - more = kount; - JOM(12, "agreed to send %li bytes from page %i\n", \ - more, peasycap->audio_read); - if (!more) - break; +/*---------------------------------------------------------------------------*/ + if (0 > peasycap->dma_read) { + JOM(8, "returning -EBUSY\n"); + return -EBUSY; + } + offset = ((snd_pcm_uframes_t)peasycap->dma_read)/4; + JOM(8, "ALSA decides %8i =hw_ptr_base\n", (int)pss->runtime->hw_ptr_base); + JOM(8, "ALSA decides %8i =hw_ptr_interrupt\n", + (int)pss->runtime->hw_ptr_interrupt); + JOM(8, "%7i=offset %7i=dma_read %7i=dma_next\n", + (int)offset, peasycap->dma_read, peasycap->dma_next); + return offset; +} +/*****************************************************************************/ +static struct page * +easycap_alsa_page(struct snd_pcm_substream *pss, unsigned long offset) +{ + return vmalloc_to_page(pss->runtime->dma_area + offset); +} +/*****************************************************************************/ + +static struct snd_pcm_ops easycap_alsa_pcm_ops = { + .open = easycap_alsa_open, + .close = easycap_alsa_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = easycap_alsa_hw_params, + .hw_free = easycap_alsa_hw_free, + .prepare = easycap_alsa_prepare, + .ack = easycap_alsa_ack, + .trigger = easycap_alsa_trigger, + .pointer = easycap_alsa_pointer, + .page = easycap_alsa_page, +}; +/*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* - * ACCUMULATE DYNAMIC-RANGE INFORMATION - */ + * THE FUNCTION snd_card_create() HAS THIS_MODULE AS AN ARGUMENT. THIS + * MEANS MODULE easycap. BEWARE. +*/ /*---------------------------------------------------------------------------*/ - p0 = (unsigned char *)pdata_buffer->pgo; l0 = 0; lm = more/2; - while (l0 < lm) { - SUMMER(p0, &peasycap->audio_sample, &peasycap->audio_niveau, \ - &peasycap->audio_square); l0++; p0 += 2; +int easycap_alsa_probe(struct easycap *peasycap) +{ + int rc; + struct snd_card *psnd_card; + struct snd_pcm *psnd_pcm; + + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -ENODEV; } -/*---------------------------------------------------------------------------*/ - rc = copy_to_user(puserspacebuffer, pdata_buffer->pto, more); - if (0 != rc) { - SAM("ERROR: copy_to_user() returned %li\n", rc); - mutex_unlock(&easycap_dongle[kd].mutex_audio); + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); return -EFAULT; } - *poff += (loff_t)more; - szret += (size_t)more; - pdata_buffer->pto += more; - puserspacebuffer += more; - kount -= (size_t)more; -} -JOM(12, "after read, %i=frag read %i=frag fill\n", \ - (peasycap->audio_read / peasycap->audio_pages_per_fragment), \ - (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); -if (kount < 0) { - SAM("MISTAKE: %li=kount %li=szret\n", \ - (long int)kount, (long int)szret); + if (0 > peasycap->minor) { + SAY("ERROR: no minor\n"); + return -ENODEV; + } + + peasycap->alsa_hardware = alsa_hardware; + if (peasycap->microphone) { + peasycap->alsa_hardware.rates = SNDRV_PCM_RATE_32000; + peasycap->alsa_hardware.rate_min = 32000; + peasycap->alsa_hardware.rate_max = 32000; + } else { + peasycap->alsa_hardware.rates = SNDRV_PCM_RATE_48000; + peasycap->alsa_hardware.rate_min = 48000; + peasycap->alsa_hardware.rate_max = 48000; + } + + if (0 != snd_card_create(SNDRV_DEFAULT_IDX1, "easycap_alsa", + THIS_MODULE, 0, &psnd_card)) { + SAY("ERROR: Cannot do ALSA snd_card_create()\n"); + return -EFAULT; + } + + sprintf(&psnd_card->id[0], "EasyALSA%i", peasycap->minor); + strcpy(&psnd_card->driver[0], EASYCAP_DRIVER_DESCRIPTION); + strcpy(&psnd_card->shortname[0], "easycap_alsa"); + sprintf(&psnd_card->longname[0], "%s", &psnd_card->shortname[0]); + + psnd_card->dev = &peasycap->pusb_device->dev; + psnd_card->private_data = peasycap; + peasycap->psnd_card = psnd_card; + + rc = snd_pcm_new(psnd_card, "easycap_pcm", 0, 0, 1, &psnd_pcm); + if (rc) { + SAM("ERROR: Cannot do ALSA snd_pcm_new()\n"); + snd_card_free(psnd_card); + return -EFAULT; + } + + snd_pcm_set_ops(psnd_pcm, SNDRV_PCM_STREAM_CAPTURE, + &easycap_alsa_pcm_ops); + psnd_pcm->info_flags = 0; + strcpy(&psnd_pcm->name[0], &psnd_card->id[0]); + psnd_pcm->private_data = peasycap; + peasycap->psnd_pcm = psnd_pcm; + peasycap->psubstream = NULL; + + rc = snd_card_register(psnd_card); + if (rc) { + SAM("ERROR: Cannot do ALSA snd_card_register()\n"); + snd_card_free(psnd_card); + return -EFAULT; + } + + SAM("registered %s\n", &psnd_card->id[0]); + return 0; } +#endif /*! CONFIG_EASYCAP_OSS */ + +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ +/*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* - * CALCULATE DYNAMIC RANGE FOR (VAPOURWARE) AUTOMATIC VOLUME CONTROL + * COMMON AUDIO INITIALIZATION */ /*---------------------------------------------------------------------------*/ -if (peasycap->audio_sample) { - below = peasycap->audio_sample; - above = peasycap->audio_square; - sdr = signed_div(above, below); - above = sdr.quotient; - mean = peasycap->audio_niveau; - sdr = signed_div(mean, peasycap->audio_sample); - - JOM(8, "%8lli=mean %8lli=meansquare after %lli samples, =>\n", \ - sdr.quotient, above, peasycap->audio_sample); - - sdr = signed_div(above, 32768); - JOM(8, "audio dynamic range is roughly %lli\n", sdr.quotient); -} -/*---------------------------------------------------------------------------*/ -/* - * UPDATE THE AUDIO CLOCK - */ +int +easycap_sound_setup(struct easycap *peasycap) +{ + int rc; + + JOM(4, "starting initialization\n"); + + if (!peasycap) { + SAY("ERROR: peasycap is NULL.\n"); + return -EFAULT; + } + if (!peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -ENODEV; + } + JOM(16, "0x%08lX=peasycap->pusb_device\n", (long int)peasycap->pusb_device); + + rc = audio_setup(peasycap); + JOM(8, "audio_setup() returned %i\n", rc); + + if (!peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device has become NULL\n"); + return -ENODEV; + } /*---------------------------------------------------------------------------*/ -do_gettimeofday(&timeval); -if (!peasycap->timeval1.tv_sec) { - peasycap->audio_bytes = 0; - peasycap->timeval3 = timeval; - peasycap->timeval1 = peasycap->timeval3; - sdr.quotient = 192000; -} else { - peasycap->audio_bytes += (long long int) szret; - below = ((long long int)(1000000)) * \ - ((long long int)(timeval.tv_sec - \ - peasycap->timeval3.tv_sec)) + \ - (long long int)(timeval.tv_usec - peasycap->timeval3.tv_usec); - above = 1000000 * ((long long int) peasycap->audio_bytes); - - if (below) - sdr = signed_div(above, below); - else - sdr.quotient = 192000; -} -JOM(8, "audio streaming at %lli bytes/second\n", sdr.quotient); -peasycap->dnbydt = sdr.quotient; + if (!peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device has become NULL\n"); + return -ENODEV; + } + rc = usb_set_interface(peasycap->pusb_device, peasycap->audio_interface, + peasycap->audio_altsetting_on); + JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", peasycap->audio_interface, + peasycap->audio_altsetting_on, rc); -JOM(8, "returning %li\n", (long int)szret); -mutex_unlock(&easycap_dongle[kd].mutex_audio); -return szret; + rc = wakeup_device(peasycap->pusb_device); + JOM(8, "wakeup_device() returned %i\n", rc); + + peasycap->audio_eof = 0; + peasycap->audio_idle = 0; + + peasycap->timeval1.tv_sec = 0; + peasycap->timeval1.tv_usec = 0; + + submit_audio_urbs(peasycap); + + JOM(4, "finished initialization\n"); + return 0; } /*****************************************************************************/ /*---------------------------------------------------------------------------*/ @@ -1042,120 +714,75 @@ return szret; int submit_audio_urbs(struct easycap *peasycap) { -struct data_urb *pdata_urb; -struct urb *purb; -struct list_head *plist_head; -int j, isbad, nospc, m, rc; -int isbuf; - -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if ((struct list_head *)NULL == peasycap->purb_audio_head) { - SAM("ERROR: peasycap->urb_audio_head uninitialized\n"); - return -EFAULT; -} -if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; -} -if (!peasycap->audio_isoc_streaming) { + struct data_urb *pdata_urb; + struct urb *purb; + struct list_head *plist_head; + int j, isbad, nospc, m, rc; + int isbuf; + + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + if (!peasycap->purb_audio_head) { + SAM("ERROR: peasycap->urb_audio_head uninitialized\n"); + return -EFAULT; + } + if (!peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; + } + + if (peasycap->audio_isoc_streaming) { + JOM(4, "already streaming audio urbs\n"); + return 0; + } + JOM(4, "initial submission of all audio urbs\n"); rc = usb_set_interface(peasycap->pusb_device, - peasycap->audio_interface, \ - peasycap->audio_altsetting_on); - JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", \ - peasycap->audio_interface, \ - peasycap->audio_altsetting_on, rc); - - isbad = 0; nospc = 0; m = 0; - list_for_each(plist_head, (peasycap->purb_audio_head)) { + peasycap->audio_interface, + peasycap->audio_altsetting_on); + JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", + peasycap->audio_interface, + peasycap->audio_altsetting_on, rc); + + isbad = 0; + nospc = 0; + m = 0; + list_for_each(plist_head, peasycap->purb_audio_head) { pdata_urb = list_entry(plist_head, struct data_urb, list_head); - if (NULL != pdata_urb) { + if (pdata_urb && pdata_urb->purb) { purb = pdata_urb->purb; - if (NULL != purb) { - isbuf = pdata_urb->isbuf; + isbuf = pdata_urb->isbuf; - purb->interval = 1; - purb->dev = peasycap->pusb_device; - purb->pipe = \ - usb_rcvisocpipe(peasycap->pusb_device,\ + purb->interval = 1; + purb->dev = peasycap->pusb_device; + purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, peasycap->audio_endpointnumber); - purb->transfer_flags = URB_ISO_ASAP; - purb->transfer_buffer = \ - peasycap->audio_isoc_buffer[isbuf].pgo; - purb->transfer_buffer_length = \ - peasycap->audio_isoc_buffer_size; - purb->complete = easysnd_complete; - purb->context = peasycap; - purb->start_frame = 0; - purb->number_of_packets = \ - peasycap->audio_isoc_framesperdesc; - for (j = 0; j < peasycap->\ - audio_isoc_framesperdesc; \ - j++) { - purb->iso_frame_desc[j].offset = j * \ - peasycap->\ - audio_isoc_maxframesize; - purb->iso_frame_desc[j].length = \ - peasycap->\ - audio_isoc_maxframesize; - } + purb->transfer_flags = URB_ISO_ASAP; + purb->transfer_buffer = peasycap->audio_isoc_buffer[isbuf].pgo; + purb->transfer_buffer_length = peasycap->audio_isoc_buffer_size; +#ifdef CONFIG_EASYCAP_OSS + purb->complete = easyoss_complete; +#else /* CONFIG_EASYCAP_OSS */ + purb->complete = easycap_alsa_complete; +#endif /* CONFIG_EASYCAP_OSS */ + purb->context = peasycap; + purb->start_frame = 0; + purb->number_of_packets = peasycap->audio_isoc_framesperdesc; + for (j = 0; j < peasycap->audio_isoc_framesperdesc; j++) { + purb->iso_frame_desc[j].offset = j * peasycap->audio_isoc_maxframesize; + purb->iso_frame_desc[j].length = peasycap->audio_isoc_maxframesize; + } - rc = usb_submit_urb(purb, GFP_KERNEL); - if (0 != rc) { - isbad++; - SAM("ERROR: usb_submit_urb() failed" \ - " for urb with rc:\n"); - switch (rc) { - case -ENOMEM: { - SAM("-ENOMEM\n"); - break; - } - case -ENODEV: { - SAM("-ENODEV\n"); - break; - } - case -ENXIO: { - SAM("-ENXIO\n"); - break; - } - case -EINVAL: { - SAM("-EINVAL\n"); - break; - } - case -EAGAIN: { - SAM("-EAGAIN\n"); - break; - } - case -EFBIG: { - SAM("-EFBIG\n"); - break; - } - case -EPIPE: { - SAM("-EPIPE\n"); - break; - } - case -EMSGSIZE: { - SAM("-EMSGSIZE\n"); - break; - } - case -ENOSPC: { - nospc++; - break; - } - default: { - SAM("unknown error code %i\n",\ - rc); - break; - } - } - } else { - m++; - } - } else { + rc = usb_submit_urb(purb, GFP_KERNEL); + if (rc) { isbad++; + SAM("ERROR: usb_submit_urb() failed" + " for urb with rc: -%s: %d\n", + strerror(rc), rc); + } else { + m++; } } else { isbad++; @@ -1169,23 +796,17 @@ if (!peasycap->audio_isoc_streaming) { if (isbad) { JOM(4, "attempting cleanup instead of submitting\n"); list_for_each(plist_head, (peasycap->purb_audio_head)) { - pdata_urb = list_entry(plist_head, struct data_urb, \ - list_head); - if (NULL != pdata_urb) { - purb = pdata_urb->purb; - if (NULL != purb) - usb_kill_urb(purb); - } + pdata_urb = list_entry(plist_head, struct data_urb, list_head); + if (pdata_urb && pdata_urb->purb) + usb_kill_urb(pdata_urb->purb); } peasycap->audio_isoc_streaming = 0; } else { - peasycap->audio_isoc_streaming = 1; + peasycap->audio_isoc_streaming = m; JOM(4, "submitted %i audio urbs\n", m); } -} else - JOM(4, "already streaming audio urbs\n"); -return 0; + return 0; } /*****************************************************************************/ /*---------------------------------------------------------------------------*/ @@ -1196,38 +817,38 @@ return 0; int kill_audio_urbs(struct easycap *peasycap) { -int m; -struct list_head *plist_head; -struct data_urb *pdata_urb; + int m; + struct list_head *plist_head; + struct data_urb *pdata_urb; -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return -EFAULT; -} -if (peasycap->audio_isoc_streaming) { - if ((struct list_head *)NULL != peasycap->purb_audio_head) { - peasycap->audio_isoc_streaming = 0; - JOM(4, "killing audio urbs\n"); - m = 0; - list_for_each(plist_head, (peasycap->purb_audio_head)) { - pdata_urb = list_entry(plist_head, struct data_urb, - list_head); - if ((struct data_urb *)NULL != pdata_urb) { - if ((struct urb *)NULL != pdata_urb->purb) { - usb_kill_urb(pdata_urb->purb); - m++; - } - } - } - JOM(4, "%i audio urbs killed\n", m); - } else { + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; + } + + if (!peasycap->audio_isoc_streaming) { + JOM(8, "%i=audio_isoc_streaming, no audio urbs killed\n", + peasycap->audio_isoc_streaming); + return 0; + } + + if (!peasycap->purb_audio_head) { SAM("ERROR: peasycap->purb_audio_head is NULL\n"); return -EFAULT; } -} else { - JOM(8, "%i=audio_isoc_streaming, no audio urbs killed\n", \ - peasycap->audio_isoc_streaming); -} -return 0; + + peasycap->audio_isoc_streaming = 0; + JOM(4, "killing audio urbs\n"); + m = 0; + list_for_each(plist_head, (peasycap->purb_audio_head)) { + pdata_urb = list_entry(plist_head, struct data_urb, list_head); + if (pdata_urb && pdata_urb->purb) { + usb_kill_urb(pdata_urb->purb); + m++; + } + } + JOM(4, "%i audio urbs killed\n", m); + + return 0; } /*****************************************************************************/ diff --git a/drivers/staging/easycap/easycap_sound.h b/drivers/staging/easycap/easycap_sound.h deleted file mode 100644 index 49127396902..00000000000 --- a/drivers/staging/easycap/easycap_sound.h +++ /dev/null @@ -1,28 +0,0 @@ -/***************************************************************************** -* * -* easycap_sound.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 - * -*/ -/*****************************************************************************/ -extern struct easycap *peasycap; -extern struct usb_driver easycap_usb_driver; diff --git a/drivers/staging/easycap/easycap_sound_oss.c b/drivers/staging/easycap/easycap_sound_oss.c new file mode 100644 index 00000000000..d92baf22276 --- /dev/null +++ b/drivers/staging/easycap/easycap_sound_oss.c @@ -0,0 +1,954 @@ +/****************************************************************************** +* * +* easycap_sound.c * +* * +* Audio driver for EasyCAP USB2.0 Video Capture Device DC60 * +* * +* * +******************************************************************************/ +/* + * + * 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 + * +*/ +/*****************************************************************************/ + +#include "easycap.h" + +/*****************************************************************************/ +/**************************** **************************/ +/**************************** Open Sound System **************************/ +/**************************** **************************/ +/*****************************************************************************/ +/*--------------------------------------------------------------------------*/ +/* + * PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE + */ +/*--------------------------------------------------------------------------*/ +/*****************************************************************************/ +/*---------------------------------------------------------------------------*/ +/* + * ON COMPLETION OF AN AUDIO URB ITS DATA IS COPIED TO THE AUDIO BUFFERS + * PROVIDED peasycap->audio_idle IS ZERO. REGARDLESS OF THIS BEING TRUE, + * IT IS RESUBMITTED PROVIDED peasycap->audio_isoc_streaming IS NOT ZERO. + */ +/*---------------------------------------------------------------------------*/ +void +easyoss_complete(struct urb *purb) +{ + struct easycap *peasycap; + struct data_buffer *paudio_buffer; + u8 *p1, *p2; + s16 tmp; + int i, j, more, much, leap, rc; +#ifdef UPSAMPLE + int k; + s16 oldaudio, newaudio, delta; +#endif /*UPSAMPLE*/ + + JOT(16, "\n"); + + if (!purb) { + SAY("ERROR: purb is NULL\n"); + return; + } + peasycap = purb->context; + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return; + } + much = 0; + if (peasycap->audio_idle) { + JOM(16, "%i=audio_idle %i=audio_isoc_streaming\n", + peasycap->audio_idle, peasycap->audio_isoc_streaming); + if (peasycap->audio_isoc_streaming) { + rc = usb_submit_urb(purb, GFP_ATOMIC); + if (rc) { + if (-ENODEV != rc && -ENOENT != rc) { + SAM("ERROR: while %i=audio_idle, " + "usb_submit_urb() failed with rc: -%s: %d\n", + peasycap->audio_idle, + strerror(rc), rc); + } + } + } + return; + } +/*---------------------------------------------------------------------------*/ + if (purb->status) { + if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) { + JOM(16, "urb status -ESHUTDOWN or -ENOENT\n"); + return; + } + SAM("ERROR: non-zero urb status: -%s: %d\n", + strerror(purb->status), purb->status); + goto resubmit; + } +/*---------------------------------------------------------------------------*/ +/* + * PROCEED HERE WHEN NO ERROR + */ +/*---------------------------------------------------------------------------*/ +#ifdef UPSAMPLE + oldaudio = peasycap->oldaudio; +#endif /*UPSAMPLE*/ + + for (i = 0; i < purb->number_of_packets; i++) { + if (!purb->iso_frame_desc[i].status) { + + SAM("-%s\n", strerror(purb->iso_frame_desc[i].status)); + + more = purb->iso_frame_desc[i].actual_length; + + if (!more) + peasycap->audio_mt++; + else { + if (peasycap->audio_mt) { + JOM(12, "%4i empty audio urb frames\n", + peasycap->audio_mt); + peasycap->audio_mt = 0; + } + + p1 = (u8 *)(purb->transfer_buffer + purb->iso_frame_desc[i].offset); + + leap = 0; + p1 += leap; + more -= leap; + /* + * COPY more BYTES FROM ISOC BUFFER + * TO AUDIO BUFFER, CONVERTING + * 8-BIT MONO TO 16-BIT SIGNED + * LITTLE-ENDIAN SAMPLES IF NECESSARY + */ + while (more) { + if (0 > more) { + SAM("MISTAKE: more is negative\n"); + return; + } + if (peasycap->audio_buffer_page_many <= peasycap->audio_fill) { + SAM("ERROR: bad peasycap->audio_fill\n"); + return; + } + + paudio_buffer = &peasycap->audio_buffer[peasycap->audio_fill]; + if (PAGE_SIZE < (paudio_buffer->pto - paudio_buffer->pgo)) { + SAM("ERROR: bad paudio_buffer->pto\n"); + return; + } + if (PAGE_SIZE == (paudio_buffer->pto - paudio_buffer->pgo)) { + + paudio_buffer->pto = paudio_buffer->pgo; + (peasycap->audio_fill)++; + if (peasycap->audio_buffer_page_many <= peasycap->audio_fill) + peasycap->audio_fill = 0; + + JOM(8, "bumped peasycap->" + "audio_fill to %i\n", + peasycap->audio_fill); + + paudio_buffer = &peasycap->audio_buffer[peasycap->audio_fill]; + paudio_buffer->pto = paudio_buffer->pgo; + + if (!(peasycap->audio_fill % peasycap->audio_pages_per_fragment)) { + JOM(12, "wakeup call on wq_audio, %i=frag reading %i=fragment fill\n", + (peasycap->audio_read / peasycap->audio_pages_per_fragment), + (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); + wake_up_interruptible(&(peasycap->wq_audio)); + } + } + + much = PAGE_SIZE - (int)(paudio_buffer->pto - paudio_buffer->pgo); + + if (!peasycap->microphone) { + if (much > more) + much = more; + + memcpy(paudio_buffer->pto, p1, much); + p1 += much; + more -= much; + } else { +#ifdef UPSAMPLE + if (much % 16) + JOM(8, "MISTAKE? much" + " is not divisible by 16\n"); + if (much > (16 * more)) + much = 16 * more; + p2 = (u8 *)paudio_buffer->pto; + + for (j = 0; j < (much/16); j++) { + newaudio = ((int) *p1) - 128; + newaudio = 128 * newaudio; + + delta = (newaudio - oldaudio) / 4; + tmp = oldaudio + delta; + + for (k = 0; k < 4; k++) { + *p2 = (0x00FF & tmp); + *(p2 + 1) = (0xFF00 & tmp) >> 8; + p2 += 2; + *p2 = (0x00FF & tmp); + *(p2 + 1) = (0xFF00 & tmp) >> 8; + p2 += 2; + + tmp += delta; + } + p1++; + more--; + oldaudio = tmp; + } +#else /*!UPSAMPLE*/ + if (much > (2 * more)) + much = 2 * more; + p2 = (u8 *)paudio_buffer->pto; + + for (j = 0; j < (much / 2); j++) { + tmp = ((int) *p1) - 128; + tmp = 128 * tmp; + *p2 = (0x00FF & tmp); + *(p2 + 1) = (0xFF00 & tmp) >> 8; + p1++; + p2 += 2; + more--; + } +#endif /*UPSAMPLE*/ + } + (paudio_buffer->pto) += much; + } + } + } else { + JOM(12, "discarding audio samples because " + "%i=purb->iso_frame_desc[i].status\n", + purb->iso_frame_desc[i].status); + } + +#ifdef UPSAMPLE + peasycap->oldaudio = oldaudio; +#endif /*UPSAMPLE*/ + + } +/*---------------------------------------------------------------------------*/ +/* + * RESUBMIT THIS URB + */ +/*---------------------------------------------------------------------------*/ +resubmit: + if (peasycap->audio_isoc_streaming) { + rc = usb_submit_urb(purb, GFP_ATOMIC); + if (rc) { + if (-ENODEV != rc && -ENOENT != rc) { + SAM("ERROR: while %i=audio_idle, " + "usb_submit_urb() failed " + "with rc: -%s: %d\n", peasycap->audio_idle, + strerror(rc), rc); + } + } + } + return; +} +/*****************************************************************************/ +/*---------------------------------------------------------------------------*/ +/* + * THE AUDIO URBS ARE SUBMITTED AT THIS EARLY STAGE SO THAT IT IS POSSIBLE TO + * STREAM FROM /dev/easyoss1 WITH SIMPLE PROGRAMS SUCH AS cat WHICH DO NOT + * HAVE AN IOCTL INTERFACE. + */ +/*---------------------------------------------------------------------------*/ +static int easyoss_open(struct inode *inode, struct file *file) +{ + struct usb_interface *pusb_interface; + struct easycap *peasycap; + int subminor; + struct v4l2_device *pv4l2_device; + + JOT(4, "begins\n"); + + subminor = iminor(inode); + + pusb_interface = usb_find_interface(&easycap_usb_driver, subminor); + if (!pusb_interface) { + SAY("ERROR: pusb_interface is NULL\n"); + SAY("ending unsuccessfully\n"); + return -1; + } + peasycap = usb_get_intfdata(pusb_interface); + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + SAY("ending unsuccessfully\n"); + return -1; + } +/*---------------------------------------------------------------------------*/ +/* + * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS + * BEEN WRITTEN BY THE CALL TO usb_set_intfdata() IN easycap_usb_probe(), + * REPLACING IT WITH A POINTER TO THE EMBEDDED v4l2_device STRUCTURE. + * TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED. +*/ +/*---------------------------------------------------------------------------*/ + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + pv4l2_device = usb_get_intfdata(pusb_interface); + if (!pv4l2_device) { + SAY("ERROR: pv4l2_device is NULL\n"); + return -EFAULT; + } + peasycap = container_of(pv4l2_device, + struct easycap, v4l2_device); + } +/*---------------------------------------------------------------------------*/ + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: %p\n", peasycap); + return -EFAULT; + } +/*---------------------------------------------------------------------------*/ + + file->private_data = peasycap; + + if (0 != easycap_sound_setup(peasycap)) { + ; + ; + } + return 0; +} +/*****************************************************************************/ +static int easyoss_release(struct inode *inode, struct file *file) +{ + struct easycap *peasycap; + + JOT(4, "begins\n"); + + peasycap = file->private_data; + if (!peasycap) { + SAY("ERROR: peasycap is NULL.\n"); + return -EFAULT; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: %p\n", peasycap); + return -EFAULT; + } + if (0 != kill_audio_urbs(peasycap)) { + SAM("ERROR: kill_audio_urbs() failed\n"); + return -EFAULT; + } + JOM(4, "ending successfully\n"); + return 0; +} +/*****************************************************************************/ +static ssize_t easyoss_read(struct file *file, char __user *puserspacebuffer, + size_t kount, loff_t *poff) +{ + struct timeval timeval; + long long int above, below, mean; + struct signed_div_result sdr; + unsigned char *p0; + long int kount1, more, rc, l0, lm; + int fragment, kd; + struct easycap *peasycap; + struct data_buffer *pdata_buffer; + size_t szret; + +/*---------------------------------------------------------------------------*/ +/* + * DO A BLOCKING READ TO TRANSFER DATA TO USER SPACE. + * + ****************************************************************************** + ***** N.B. IF THIS FUNCTION RETURNS 0, NOTHING IS SEEN IN USER SPACE. ****** + ***** THIS CONDITION SIGNIFIES END-OF-FILE. ****** + ****************************************************************************** + */ +/*---------------------------------------------------------------------------*/ + + JOT(8, "%5zd=kount %5lld=*poff\n", kount, *poff); + + if (!file) { + SAY("ERROR: file is NULL\n"); + return -ERESTARTSYS; + } + peasycap = file->private_data; + if (!peasycap) { + SAY("ERROR in easyoss_read(): peasycap is NULL\n"); + return -EFAULT; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: %p\n", peasycap); + return -EFAULT; + } + if (!peasycap->pusb_device) { + SAY("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; + } + kd = isdongle(peasycap); + if (0 <= kd && DONGLE_MANY > kd) { + if (mutex_lock_interruptible(&(easycapdc60_dongle[kd].mutex_audio))) { + SAY("ERROR: " + "cannot lock dongle[%i].mutex_audio\n", kd); + return -ERESTARTSYS; + } + JOM(4, "locked dongle[%i].mutex_audio\n", kd); + /* + * MEANWHILE, easycap_usb_disconnect() + * MAY HAVE FREED POINTER peasycap, + * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. + * IF NECESSARY, BAIL OUT. + */ + if (kd != isdongle(peasycap)) + return -ERESTARTSYS; + if (!file) { + SAY("ERROR: file is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + peasycap = file->private_data; + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: %p\n", peasycap); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + if (!peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + } else { + /* + * IF easycap_usb_disconnect() + * HAS ALREADY FREED POINTER peasycap BEFORE THE + * ATTEMPT TO ACQUIRE THE SEMAPHORE, + * isdongle() WILL HAVE FAILED. BAIL OUT. + */ + return -ERESTARTSYS; + } +/*---------------------------------------------------------------------------*/ + JOT(16, "%sBLOCKING kount=%zd, *poff=%lld\n", + (file->f_flags & O_NONBLOCK) ? "NON" : "", kount, *poff); + + if ((0 > peasycap->audio_read) || + (peasycap->audio_buffer_page_many <= peasycap->audio_read)) { + SAM("ERROR: peasycap->audio_read out of range\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read]; + if (!pdata_buffer) { + SAM("ERROR: pdata_buffer is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + JOM(12, "before wait, %i=frag read %i=frag fill\n", + (peasycap->audio_read / peasycap->audio_pages_per_fragment), + (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); + fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment); + while ((fragment == (peasycap->audio_fill / peasycap->audio_pages_per_fragment)) || + (0 == (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))) { + if (file->f_flags & O_NONBLOCK) { + JOM(16, "returning -EAGAIN as instructed\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EAGAIN; + } + rc = wait_event_interruptible(peasycap->wq_audio, + (peasycap->audio_idle || peasycap->audio_eof || + ((fragment != + (peasycap->audio_fill / peasycap->audio_pages_per_fragment)) && + (0 < (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))))); + if (rc) { + SAM("aborted by signal\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + if (peasycap->audio_eof) { + JOM(8, "returning 0 because %i=audio_eof\n", + peasycap->audio_eof); + kill_audio_urbs(peasycap); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return 0; + } + if (peasycap->audio_idle) { + JOM(16, "returning 0 because %i=audio_idle\n", + peasycap->audio_idle); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return 0; + } + if (!peasycap->audio_isoc_streaming) { + JOM(16, "returning 0 because audio urbs not streaming\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return 0; + } + } + JOM(12, "after wait, %i=frag read %i=frag fill\n", + (peasycap->audio_read / peasycap->audio_pages_per_fragment), + (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); + szret = (size_t)0; + fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment); + while (fragment == (peasycap->audio_read / peasycap->audio_pages_per_fragment)) { + if (!pdata_buffer->pgo) { + SAM("ERROR: pdata_buffer->pgo is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + if (!pdata_buffer->pto) { + SAM("ERROR: pdata_buffer->pto is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo); + if (0 > kount1) { + SAM("MISTAKE: kount1 is negative\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + if (!kount1) { + peasycap->audio_read++; + if (peasycap->audio_buffer_page_many <= peasycap->audio_read) + peasycap->audio_read = 0; + JOM(12, "bumped peasycap->audio_read to %i\n", + peasycap->audio_read); + + if (fragment != (peasycap->audio_read / peasycap->audio_pages_per_fragment)) + break; + + if ((0 > peasycap->audio_read) || + (peasycap->audio_buffer_page_many <= peasycap->audio_read)) { + SAM("ERROR: peasycap->audio_read out of range\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read]; + if (!pdata_buffer) { + SAM("ERROR: pdata_buffer is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + if (!pdata_buffer->pgo) { + SAM("ERROR: pdata_buffer->pgo is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + if (!pdata_buffer->pto) { + SAM("ERROR: pdata_buffer->pto is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo); + } + JOM(12, "ready to send %zd bytes\n", kount1); + JOM(12, "still to send %li bytes\n", (long int) kount); + more = kount1; + if (more > kount) + more = kount; + JOM(12, "agreed to send %li bytes from page %i\n", + more, peasycap->audio_read); + if (!more) + break; + + /* + * ACCUMULATE DYNAMIC-RANGE INFORMATION + */ + p0 = (unsigned char *)pdata_buffer->pgo; + l0 = 0; + lm = more/2; + while (l0 < lm) { + SUMMER(p0, &peasycap->audio_sample, + &peasycap->audio_niveau, + &peasycap->audio_square); + l0++; + p0 += 2; + } + /*-----------------------------------------------------------*/ + rc = copy_to_user(puserspacebuffer, pdata_buffer->pto, more); + if (rc) { + SAM("ERROR: copy_to_user() returned %li\n", rc); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + *poff += (loff_t)more; + szret += (size_t)more; + pdata_buffer->pto += more; + puserspacebuffer += more; + kount -= (size_t)more; + } + JOM(12, "after read, %i=frag read %i=frag fill\n", + (peasycap->audio_read / peasycap->audio_pages_per_fragment), + (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); + if (kount < 0) { + SAM("MISTAKE: %li=kount %li=szret\n", + (long int)kount, (long int)szret); + } +/*---------------------------------------------------------------------------*/ +/* + * CALCULATE DYNAMIC RANGE FOR (VAPOURWARE) AUTOMATIC VOLUME CONTROL + */ +/*---------------------------------------------------------------------------*/ + if (peasycap->audio_sample) { + below = peasycap->audio_sample; + above = peasycap->audio_square; + sdr = signed_div(above, below); + above = sdr.quotient; + mean = peasycap->audio_niveau; + sdr = signed_div(mean, peasycap->audio_sample); + + JOM(8, "%8lli=mean %8lli=meansquare after %lli samples, =>\n", + sdr.quotient, above, peasycap->audio_sample); + + sdr = signed_div(above, 32768); + JOM(8, "audio dynamic range is roughly %lli\n", sdr.quotient); + } +/*---------------------------------------------------------------------------*/ +/* + * UPDATE THE AUDIO CLOCK + */ +/*---------------------------------------------------------------------------*/ + do_gettimeofday(&timeval); + if (!peasycap->timeval1.tv_sec) { + peasycap->audio_bytes = 0; + peasycap->timeval3 = timeval; + peasycap->timeval1 = peasycap->timeval3; + sdr.quotient = 192000; + } else { + peasycap->audio_bytes += (long long int) szret; + below = ((long long int)(1000000)) * + ((long long int)(timeval.tv_sec - peasycap->timeval3.tv_sec)) + + (long long int)(timeval.tv_usec - peasycap->timeval3.tv_usec); + above = 1000000 * ((long long int) peasycap->audio_bytes); + + if (below) + sdr = signed_div(above, below); + else + sdr.quotient = 192000; + } + JOM(8, "audio streaming at %lli bytes/second\n", sdr.quotient); + peasycap->dnbydt = sdr.quotient; + + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + JOM(4, "unlocked easycapdc60_dongle[%i].mutex_audio\n", kd); + JOM(8, "returning %li\n", (long int)szret); + return szret; + +} +/*---------------------------------------------------------------------------*/ +static long easyoss_unlocked_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct easycap *peasycap; + struct usb_device *p; + int kd; + + if (!file) { + SAY("ERROR: file is NULL\n"); + return -ERESTARTSYS; + } + peasycap = file->private_data; + if (!peasycap) { + SAY("ERROR: peasycap is NULL.\n"); + return -EFAULT; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return -EFAULT; + } + p = peasycap->pusb_device; + if (!p) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; + } + kd = isdongle(peasycap); + if (0 <= kd && DONGLE_MANY > kd) { + if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_audio)) { + SAY("ERROR: cannot lock " + "easycapdc60_dongle[%i].mutex_audio\n", kd); + return -ERESTARTSYS; + } + JOM(4, "locked easycapdc60_dongle[%i].mutex_audio\n", kd); + /* + * MEANWHILE, easycap_usb_disconnect() + * MAY HAVE FREED POINTER peasycap, + * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. + * IF NECESSARY, BAIL OUT. + */ + if (kd != isdongle(peasycap)) + return -ERESTARTSYS; + if (!file) { + SAY("ERROR: file is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + peasycap = file->private_data; + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + p = peasycap->pusb_device; + if (!peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + } else { + /* + * IF easycap_usb_disconnect() + * HAS ALREADY FREED POINTER peasycap BEFORE THE + * ATTEMPT TO ACQUIRE THE SEMAPHORE, + * isdongle() WILL HAVE FAILED. BAIL OUT. + */ + return -ERESTARTSYS; + } +/*---------------------------------------------------------------------------*/ + switch (cmd) { + case SNDCTL_DSP_GETCAPS: { + int caps; + JOM(8, "SNDCTL_DSP_GETCAPS\n"); + +#ifdef UPSAMPLE + if (peasycap->microphone) + caps = 0x04400000; + else + caps = 0x04400000; +#else + if (peasycap->microphone) + caps = 0x02400000; + else + caps = 0x04400000; +#endif /*UPSAMPLE*/ + + if (copy_to_user((void __user *)arg, &caps, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + break; + } + case SNDCTL_DSP_GETFMTS: { + int incoming; + JOM(8, "SNDCTL_DSP_GETFMTS\n"); + +#ifdef UPSAMPLE + if (peasycap->microphone) + incoming = AFMT_S16_LE; + else + incoming = AFMT_S16_LE; +#else + if (peasycap->microphone) + incoming = AFMT_S16_LE; + else + incoming = AFMT_S16_LE; +#endif /*UPSAMPLE*/ + + if (copy_to_user((void __user *)arg, &incoming, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + break; + } + case SNDCTL_DSP_SETFMT: { + int incoming, outgoing; + JOM(8, "SNDCTL_DSP_SETFMT\n"); + if (copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + JOM(8, "........... %i=incoming\n", incoming); + +#ifdef UPSAMPLE + if (peasycap->microphone) + outgoing = AFMT_S16_LE; + else + outgoing = AFMT_S16_LE; +#else + if (peasycap->microphone) + outgoing = AFMT_S16_LE; + else + outgoing = AFMT_S16_LE; +#endif /*UPSAMPLE*/ + + if (incoming != outgoing) { + JOM(8, "........... %i=outgoing\n", outgoing); + JOM(8, " cf. %i=AFMT_S16_LE\n", AFMT_S16_LE); + JOM(8, " cf. %i=AFMT_U8\n", AFMT_U8); + if (copy_to_user((void __user *)arg, &outgoing, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EINVAL ; + } + break; + } + case SNDCTL_DSP_STEREO: { + int incoming; + JOM(8, "SNDCTL_DSP_STEREO\n"); + if (copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + JOM(8, "........... %i=incoming\n", incoming); + +#ifdef UPSAMPLE + if (peasycap->microphone) + incoming = 1; + else + incoming = 1; +#else + if (peasycap->microphone) + incoming = 0; + else + incoming = 1; +#endif /*UPSAMPLE*/ + + if (copy_to_user((void __user *)arg, &incoming, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + break; + } + case SNDCTL_DSP_SPEED: { + int incoming; + JOM(8, "SNDCTL_DSP_SPEED\n"); + if (copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + JOM(8, "........... %i=incoming\n", incoming); + +#ifdef UPSAMPLE + if (peasycap->microphone) + incoming = 32000; + else + incoming = 48000; +#else + if (peasycap->microphone) + incoming = 8000; + else + incoming = 48000; +#endif /*UPSAMPLE*/ + + if (copy_to_user((void __user *)arg, &incoming, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + break; + } + case SNDCTL_DSP_GETTRIGGER: { + int incoming; + JOM(8, "SNDCTL_DSP_GETTRIGGER\n"); + if (copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + JOM(8, "........... %i=incoming\n", incoming); + + incoming = PCM_ENABLE_INPUT; + if (copy_to_user((void __user *)arg, &incoming, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + break; + } + case SNDCTL_DSP_SETTRIGGER: { + int incoming; + JOM(8, "SNDCTL_DSP_SETTRIGGER\n"); + if (copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + JOM(8, "........... %i=incoming\n", incoming); + JOM(8, "........... cf 0x%x=PCM_ENABLE_INPUT " + "0x%x=PCM_ENABLE_OUTPUT\n", + PCM_ENABLE_INPUT, PCM_ENABLE_OUTPUT); + ; + ; + ; + ; + break; + } + case SNDCTL_DSP_GETBLKSIZE: { + int incoming; + JOM(8, "SNDCTL_DSP_GETBLKSIZE\n"); + if (copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + JOM(8, "........... %i=incoming\n", incoming); + incoming = peasycap->audio_bytes_per_fragment; + if (copy_to_user((void __user *)arg, &incoming, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + break; + } + case SNDCTL_DSP_GETISPACE: { + struct audio_buf_info audio_buf_info; + + JOM(8, "SNDCTL_DSP_GETISPACE\n"); + + audio_buf_info.bytes = peasycap->audio_bytes_per_fragment; + audio_buf_info.fragments = 1; + audio_buf_info.fragsize = 0; + audio_buf_info.fragstotal = 0; + + if (copy_to_user((void __user *)arg, &audio_buf_info, sizeof(int))) { + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -EFAULT; + } + break; + } + case 0x00005401: + case 0x00005402: + case 0x00005403: + case 0x00005404: + case 0x00005405: + case 0x00005406: { + JOM(8, "SNDCTL_TMR_...: 0x%08X unsupported\n", cmd); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ENOIOCTLCMD; + } + default: { + JOM(8, "ERROR: unrecognized DSP IOCTL command: 0x%08X\n", cmd); + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return -ENOIOCTLCMD; + } + } + mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); + return 0; +} +/*****************************************************************************/ + +static const struct file_operations easyoss_fops = { + .owner = THIS_MODULE, + .open = easyoss_open, + .release = easyoss_release, + .unlocked_ioctl = easyoss_unlocked_ioctl, + .read = easyoss_read, + .llseek = no_llseek, +}; +struct usb_class_driver easyoss_class = { + .name = "usb/easyoss%d", + .fops = &easyoss_fops, + .minor_base = USB_SKEL_MINOR_BASE, +}; +/*****************************************************************************/ diff --git a/drivers/staging/easycap/easycap_standard.h b/drivers/staging/easycap/easycap_standard.h deleted file mode 100644 index cadc8d27a85..00000000000 --- a/drivers/staging/easycap/easycap_standard.h +++ /dev/null @@ -1,27 +0,0 @@ -/***************************************************************************** -* * -* easycap_standard.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 - * -*/ -/*****************************************************************************/ -extern struct easycap_standard easycap_standard[]; diff --git a/drivers/staging/easycap/easycap_testcard.c b/drivers/staging/easycap/easycap_testcard.c index e27dfe9a9ba..0f71470ace3 100644 --- a/drivers/staging/easycap/easycap_testcard.c +++ b/drivers/staging/easycap/easycap_testcard.c @@ -26,397 +26,130 @@ /*****************************************************************************/ #include "easycap.h" -#include "easycap_debug.h" /*****************************************************************************/ #define TESTCARD_BYTESPERLINE (2 * 720) void easycap_testcard(struct easycap *peasycap, int field) { -int total; -int y, u, v, r, g, b; -unsigned char uyvy[4]; -int i1, line, k, m, n, more, much, barwidth, barheight; -unsigned char bfbar[TESTCARD_BYTESPERLINE / 8], *p1, *p2; -struct data_buffer *pfield_buffer; - -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - return; -} -JOM(8, "%i=field\n", field); -switch (peasycap->width) { -case 720: -case 360: { - barwidth = (2 * 720) / 8; - break; -} -case 704: -case 352: { - barwidth = (2 * 704) / 8; - break; -} -case 640: -case 320: { - barwidth = (2 * 640) / 8; - break; -} -default: { - SAM("ERROR: cannot set barwidth\n"); - return; -} -} -if (TESTCARD_BYTESPERLINE < barwidth) { - SAM("ERROR: barwidth is too large\n"); - return; -} -switch (peasycap->height) { -case 576: -case 288: { - barheight = 576; - break; -} -case 480: -case 240: { - barheight = 480; - break; -} -default: { - SAM("ERROR: cannot set barheight\n"); - return; -} -} -total = 0; -k = field; -m = 0; -n = 0; - -for (line = 0; line < (barheight / 2); line++) { - for (i1 = 0; i1 < 8; i1++) { - r = (i1 * 256)/8; - g = (i1 * 256)/8; - b = (i1 * 256)/8; - - y = 299*r/1000 + 587*g/1000 + 114*b/1000 ; - u = -147*r/1000 - 289*g/1000 + 436*b/1000 ; u = u + 128; - v = 615*r/1000 - 515*g/1000 - 100*b/1000 ; v = v + 128; - - uyvy[0] = 0xFF & u ; - uyvy[1] = 0xFF & y ; - uyvy[2] = 0xFF & v ; - uyvy[3] = 0xFF & y ; - - p1 = &bfbar[0]; - while (p1 < &bfbar[barwidth]) { - *p1++ = uyvy[0] ; - *p1++ = uyvy[1] ; - *p1++ = uyvy[2] ; - *p1++ = uyvy[3] ; - total += 4; - } - - p1 = &bfbar[0]; - more = barwidth; - - while (more) { - if ((FIELD_BUFFER_SIZE/PAGE_SIZE) <= m) { - SAM("ERROR: bad m reached\n"); - return; + int total; + int y, u, v, r, g, b; + unsigned char uyvy[4]; + int i1, line, k, m, n, more, much, barwidth, barheight; + unsigned char bfbar[TESTCARD_BYTESPERLINE / 8], *p1, *p2; + struct data_buffer *pfield_buffer; + + if (!peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return; + } + JOM(8, "%i=field\n", field); + switch (peasycap->width) { + case 720: + case 360: { + barwidth = (2 * 720) / 8; + break; + } + case 704: + case 352: { + barwidth = (2 * 704) / 8; + break; + } + case 640: + case 320: { + barwidth = (2 * 640) / 8; + break; + } + default: { + SAM("ERROR: cannot set barwidth\n"); + return; + } + } + if (TESTCARD_BYTESPERLINE < barwidth) { + SAM("ERROR: barwidth is too large\n"); + return; + } + switch (peasycap->height) { + case 576: + case 288: { + barheight = 576; + break; + } + case 480: + case 240: { + barheight = 480; + break; + } + default: { + SAM("ERROR: cannot set barheight\n"); + return; + } + } + total = 0; + k = field; + m = 0; + n = 0; + + for (line = 0; line < (barheight / 2); line++) { + for (i1 = 0; i1 < 8; i1++) { + r = (i1 * 256)/8; + g = (i1 * 256)/8; + b = (i1 * 256)/8; + + y = 299*r/1000 + 587*g/1000 + 114*b/1000 ; + u = -147*r/1000 - 289*g/1000 + 436*b/1000 ; + u = u + 128; + v = 615*r/1000 - 515*g/1000 - 100*b/1000 ; + v = v + 128; + + uyvy[0] = 0xFF & u ; + uyvy[1] = 0xFF & y ; + uyvy[2] = 0xFF & v ; + uyvy[3] = 0xFF & y ; + + p1 = &bfbar[0]; + while (p1 < &bfbar[barwidth]) { + *p1++ = uyvy[0] ; + *p1++ = uyvy[1] ; + *p1++ = uyvy[2] ; + *p1++ = uyvy[3] ; + total += 4; } - if (PAGE_SIZE < n) { - SAM("ERROR: bad n reached\n"); return; - } - if (0 > more) { - SAM("ERROR: internal fault\n"); - return; - } - - much = PAGE_SIZE - n; - if (much > more) - much = more; - pfield_buffer = &peasycap->field_buffer[k][m]; - p2 = pfield_buffer->pgo + n; - memcpy(p2, p1, much); - - p1 += much; - n += much; - more -= much; - if (PAGE_SIZE == n) { - m++; - n = 0; + p1 = &bfbar[0]; + more = barwidth; + + while (more) { + if ((FIELD_BUFFER_SIZE/PAGE_SIZE) <= m) { + SAM("ERROR: bad m reached\n"); + return; + } + if (PAGE_SIZE < n) { + SAM("ERROR: bad n reached\n"); + return; + } + + if (0 > more) { + SAM("ERROR: internal fault\n"); + return; + } + + much = PAGE_SIZE - n; + if (much > more) + much = more; + pfield_buffer = &peasycap->field_buffer[k][m]; + p2 = pfield_buffer->pgo + n; + memcpy(p2, p1, much); + + p1 += much; + n += much; + more -= much; + if (PAGE_SIZE == n) { + m++; + n = 0; + } } } } -} -return; -} -/*****************************************************************************/ -#if defined(EASYCAP_TESTTONE) -/*----------------------------------------------------------------------------- -THE tones[] ARRAY BELOW IS THE OUTPUT OF THIS PROGRAM, -COMPILED gcc -o prog -lm prog.c -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#include <stdio.h> -#include <math.h> - -int main(void); -int -main(void) -{ -int i1, i2, last; -double d1, d2; - -last = 1024 - 1; -d1 = 10.0*3.14159265/1024.0; -printf("int tones[2048] =\n{\n"); -for (i1 = 0; i1 <= last; i1++) - { - d2 = ((double)i1) * d1; - i2 = (int)(16384.0*sin(d2)); - - if (last != i1) - { - printf("%6i, ", i2); printf("%6i, ", i2); - if (!((i1 + 1)%5)) printf("\n"); - } - else - { - printf("%6i, ", i2); printf("%6i\n};\n", i2); - } - } -return 0; -} ------------------------------------------------------------------------------*/ -int tones[2048] = { -0, 0, 502, 502, 1004, 1004, 1505, 1505, 2005, 2005, -2503, 2503, 2998, 2998, 3491, 3491, 3980, 3980, 4466, 4466, -4948, 4948, 5424, 5424, 5896, 5896, 6362, 6362, 6822, 6822, -7276, 7276, 7723, 7723, 8162, 8162, 8594, 8594, 9018, 9018, -9434, 9434, 9840, 9840, 10237, 10237, 10625, 10625, 11002, 11002, -11370, 11370, 11726, 11726, 12072, 12072, 12406, 12406, 12728, 12728, -13038, 13038, 13337, 13337, 13622, 13622, 13895, 13895, 14155, 14155, -14401, 14401, 14634, 14634, 14853, 14853, 15058, 15058, 15249, 15249, -15426, 15426, 15588, 15588, 15735, 15735, 15868, 15868, 15985, 15985, -16088, 16088, 16175, 16175, 16248, 16248, 16305, 16305, 16346, 16346, -16372, 16372, 16383, 16383, 16379, 16379, 16359, 16359, 16323, 16323, -16272, 16272, 16206, 16206, 16125, 16125, 16028, 16028, 15917, 15917, -15790, 15790, 15649, 15649, 15492, 15492, 15322, 15322, 15136, 15136, -14937, 14937, 14723, 14723, 14496, 14496, 14255, 14255, 14001, 14001, -13733, 13733, 13452, 13452, 13159, 13159, 12854, 12854, 12536, 12536, -12207, 12207, 11866, 11866, 11513, 11513, 11150, 11150, 10777, 10777, -10393, 10393, 10000, 10000, 9597, 9597, 9185, 9185, 8765, 8765, -8336, 8336, 7900, 7900, 7456, 7456, 7005, 7005, 6547, 6547, -6083, 6083, 5614, 5614, 5139, 5139, 4659, 4659, 4175, 4175, -3687, 3687, 3196, 3196, 2701, 2701, 2204, 2204, 1705, 1705, -1205, 1205, 703, 703, 201, 201, -301, -301, -803, -803, --1305, -1305, -1805, -1805, -2304, -2304, -2801, -2801, -3294, -3294, --3785, -3785, -4272, -4272, -4756, -4756, -5234, -5234, -5708, -5708, --6176, -6176, -6639, -6639, -7095, -7095, -7545, -7545, -7988, -7988, --8423, -8423, -8850, -8850, -9268, -9268, -9679, -9679, -10079, -10079, --10471, -10471, -10853, -10853, -11224, -11224, -11585, -11585, -11935, -11935, --12273, -12273, -12600, -12600, -12916, -12916, -13219, -13219, -13510, -13510, --13788, -13788, -14053, -14053, -14304, -14304, -14543, -14543, -14767, -14767, --14978, -14978, -15175, -15175, -15357, -15357, -15525, -15525, -15678, -15678, --15817, -15817, -15940, -15940, -16049, -16049, -16142, -16142, -16221, -16221, --16284, -16284, -16331, -16331, -16364, -16364, -16381, -16381, -16382, -16382, --16368, -16368, -16339, -16339, -16294, -16294, -16234, -16234, -16159, -16159, --16069, -16069, -15963, -15963, -15842, -15842, -15707, -15707, -15557, -15557, --15392, -15392, -15212, -15212, -15018, -15018, -14810, -14810, -14589, -14589, --14353, -14353, -14104, -14104, -13842, -13842, -13566, -13566, -13278, -13278, --12977, -12977, -12665, -12665, -12340, -12340, -12003, -12003, -11656, -11656, --11297, -11297, -10928, -10928, -10548, -10548, -10159, -10159, -9759, -9759, --9351, -9351, -8934, -8934, -8509, -8509, -8075, -8075, -7634, -7634, --7186, -7186, -6731, -6731, -6269, -6269, -5802, -5802, -5329, -5329, --4852, -4852, -4369, -4369, -3883, -3883, -3393, -3393, -2900, -2900, --2404, -2404, -1905, -1905, -1405, -1405, -904, -904, -402, -402, -100, 100, 603, 603, 1105, 1105, 1605, 1605, 2105, 2105, -2602, 2602, 3097, 3097, 3589, 3589, 4078, 4078, 4563, 4563, -5043, 5043, 5519, 5519, 5990, 5990, 6455, 6455, 6914, 6914, -7366, 7366, 7811, 7811, 8249, 8249, 8680, 8680, 9102, 9102, -9516, 9516, 9920, 9920, 10315, 10315, 10701, 10701, 11077, 11077, -11442, 11442, 11796, 11796, 12139, 12139, 12471, 12471, 12791, 12791, -13099, 13099, 13395, 13395, 13678, 13678, 13948, 13948, 14205, 14205, -14449, 14449, 14679, 14679, 14895, 14895, 15098, 15098, 15286, 15286, -15459, 15459, 15618, 15618, 15763, 15763, 15892, 15892, 16007, 16007, -16107, 16107, 16191, 16191, 16260, 16260, 16314, 16314, 16353, 16353, -16376, 16376, 16384, 16384, 16376, 16376, 16353, 16353, 16314, 16314, -16260, 16260, 16191, 16191, 16107, 16107, 16007, 16007, 15892, 15892, -15763, 15763, 15618, 15618, 15459, 15459, 15286, 15286, 15098, 15098, -14895, 14895, 14679, 14679, 14449, 14449, 14205, 14205, 13948, 13948, -13678, 13678, 13395, 13395, 13099, 13099, 12791, 12791, 12471, 12471, -12139, 12139, 11796, 11796, 11442, 11442, 11077, 11077, 10701, 10701, -10315, 10315, 9920, 9920, 9516, 9516, 9102, 9102, 8680, 8680, -8249, 8249, 7811, 7811, 7366, 7366, 6914, 6914, 6455, 6455, -5990, 5990, 5519, 5519, 5043, 5043, 4563, 4563, 4078, 4078, -3589, 3589, 3097, 3097, 2602, 2602, 2105, 2105, 1605, 1605, -1105, 1105, 603, 603, 100, 100, -402, -402, -904, -904, --1405, -1405, -1905, -1905, -2404, -2404, -2900, -2900, -3393, -3393, --3883, -3883, -4369, -4369, -4852, -4852, -5329, -5329, -5802, -5802, --6269, -6269, -6731, -6731, -7186, -7186, -7634, -7634, -8075, -8075, --8509, -8509, -8934, -8934, -9351, -9351, -9759, -9759, -10159, -10159, --10548, -10548, -10928, -10928, -11297, -11297, -11656, -11656, -12003, -12003, --12340, -12340, -12665, -12665, -12977, -12977, -13278, -13278, -13566, -13566, --13842, -13842, -14104, -14104, -14353, -14353, -14589, -14589, -14810, -14810, --15018, -15018, -15212, -15212, -15392, -15392, -15557, -15557, -15707, -15707, --15842, -15842, -15963, -15963, -16069, -16069, -16159, -16159, -16234, -16234, --16294, -16294, -16339, -16339, -16368, -16368, -16382, -16382, -16381, -16381, --16364, -16364, -16331, -16331, -16284, -16284, -16221, -16221, -16142, -16142, --16049, -16049, -15940, -15940, -15817, -15817, -15678, -15678, -15525, -15525, --15357, -15357, -15175, -15175, -14978, -14978, -14767, -14767, -14543, -14543, --14304, -14304, -14053, -14053, -13788, -13788, -13510, -13510, -13219, -13219, --12916, -12916, -12600, -12600, -12273, -12273, -11935, -11935, -11585, -11585, --11224, -11224, -10853, -10853, -10471, -10471, -10079, -10079, -9679, -9679, --9268, -9268, -8850, -8850, -8423, -8423, -7988, -7988, -7545, -7545, --7095, -7095, -6639, -6639, -6176, -6176, -5708, -5708, -5234, -5234, --4756, -4756, -4272, -4272, -3785, -3785, -3294, -3294, -2801, -2801, --2304, -2304, -1805, -1805, -1305, -1305, -803, -803, -301, -301, -201, 201, 703, 703, 1205, 1205, 1705, 1705, 2204, 2204, -2701, 2701, 3196, 3196, 3687, 3687, 4175, 4175, 4659, 4659, -5139, 5139, 5614, 5614, 6083, 6083, 6547, 6547, 7005, 7005, -7456, 7456, 7900, 7900, 8336, 8336, 8765, 8765, 9185, 9185, -9597, 9597, 10000, 10000, 10393, 10393, 10777, 10777, 11150, 11150, -11513, 11513, 11866, 11866, 12207, 12207, 12536, 12536, 12854, 12854, -13159, 13159, 13452, 13452, 13733, 13733, 14001, 14001, 14255, 14255, -14496, 14496, 14723, 14723, 14937, 14937, 15136, 15136, 15322, 15322, -15492, 15492, 15649, 15649, 15790, 15790, 15917, 15917, 16028, 16028, -16125, 16125, 16206, 16206, 16272, 16272, 16323, 16323, 16359, 16359, -16379, 16379, 16383, 16383, 16372, 16372, 16346, 16346, 16305, 16305, -16248, 16248, 16175, 16175, 16088, 16088, 15985, 15985, 15868, 15868, -15735, 15735, 15588, 15588, 15426, 15426, 15249, 15249, 15058, 15058, -14853, 14853, 14634, 14634, 14401, 14401, 14155, 14155, 13895, 13895, -13622, 13622, 13337, 13337, 13038, 13038, 12728, 12728, 12406, 12406, -12072, 12072, 11726, 11726, 11370, 11370, 11002, 11002, 10625, 10625, -10237, 10237, 9840, 9840, 9434, 9434, 9018, 9018, 8594, 8594, -8162, 8162, 7723, 7723, 7276, 7276, 6822, 6822, 6362, 6362, -5896, 5896, 5424, 5424, 4948, 4948, 4466, 4466, 3980, 3980, -3491, 3491, 2998, 2998, 2503, 2503, 2005, 2005, 1505, 1505, -1004, 1004, 502, 502, 0, 0, -502, -502, -1004, -1004, --1505, -1505, -2005, -2005, -2503, -2503, -2998, -2998, -3491, -3491, --3980, -3980, -4466, -4466, -4948, -4948, -5424, -5424, -5896, -5896, --6362, -6362, -6822, -6822, -7276, -7276, -7723, -7723, -8162, -8162, --8594, -8594, -9018, -9018, -9434, -9434, -9840, -9840, -10237, -10237, --10625, -10625, -11002, -11002, -11370, -11370, -11726, -11726, -12072, -12072, --12406, -12406, -12728, -12728, -13038, -13038, -13337, -13337, -13622, -13622, --13895, -13895, -14155, -14155, -14401, -14401, -14634, -14634, -14853, -14853, --15058, -15058, -15249, -15249, -15426, -15426, -15588, -15588, -15735, -15735, --15868, -15868, -15985, -15985, -16088, -16088, -16175, -16175, -16248, -16248, --16305, -16305, -16346, -16346, -16372, -16372, -16383, -16383, -16379, -16379, --16359, -16359, -16323, -16323, -16272, -16272, -16206, -16206, -16125, -16125, --16028, -16028, -15917, -15917, -15790, -15790, -15649, -15649, -15492, -15492, --15322, -15322, -15136, -15136, -14937, -14937, -14723, -14723, -14496, -14496, --14255, -14255, -14001, -14001, -13733, -13733, -13452, -13452, -13159, -13159, --12854, -12854, -12536, -12536, -12207, -12207, -11866, -11866, -11513, -11513, --11150, -11150, -10777, -10777, -10393, -10393, -10000, -10000, -9597, -9597, --9185, -9185, -8765, -8765, -8336, -8336, -7900, -7900, -7456, -7456, --7005, -7005, -6547, -6547, -6083, -6083, -5614, -5614, -5139, -5139, --4659, -4659, -4175, -4175, -3687, -3687, -3196, -3196, -2701, -2701, --2204, -2204, -1705, -1705, -1205, -1205, -703, -703, -201, -201, -301, 301, 803, 803, 1305, 1305, 1805, 1805, 2304, 2304, -2801, 2801, 3294, 3294, 3785, 3785, 4272, 4272, 4756, 4756, -5234, 5234, 5708, 5708, 6176, 6176, 6639, 6639, 7095, 7095, -7545, 7545, 7988, 7988, 8423, 8423, 8850, 8850, 9268, 9268, -9679, 9679, 10079, 10079, 10471, 10471, 10853, 10853, 11224, 11224, -11585, 11585, 11935, 11935, 12273, 12273, 12600, 12600, 12916, 12916, -13219, 13219, 13510, 13510, 13788, 13788, 14053, 14053, 14304, 14304, -14543, 14543, 14767, 14767, 14978, 14978, 15175, 15175, 15357, 15357, -15525, 15525, 15678, 15678, 15817, 15817, 15940, 15940, 16049, 16049, -16142, 16142, 16221, 16221, 16284, 16284, 16331, 16331, 16364, 16364, -16381, 16381, 16382, 16382, 16368, 16368, 16339, 16339, 16294, 16294, -16234, 16234, 16159, 16159, 16069, 16069, 15963, 15963, 15842, 15842, -15707, 15707, 15557, 15557, 15392, 15392, 15212, 15212, 15018, 15018, -14810, 14810, 14589, 14589, 14353, 14353, 14104, 14104, 13842, 13842, -13566, 13566, 13278, 13278, 12977, 12977, 12665, 12665, 12340, 12340, -12003, 12003, 11656, 11656, 11297, 11297, 10928, 10928, 10548, 10548, -10159, 10159, 9759, 9759, 9351, 9351, 8934, 8934, 8509, 8509, -8075, 8075, 7634, 7634, 7186, 7186, 6731, 6731, 6269, 6269, -5802, 5802, 5329, 5329, 4852, 4852, 4369, 4369, 3883, 3883, -3393, 3393, 2900, 2900, 2404, 2404, 1905, 1905, 1405, 1405, -904, 904, 402, 402, -100, -100, -603, -603, -1105, -1105, --1605, -1605, -2105, -2105, -2602, -2602, -3097, -3097, -3589, -3589, --4078, -4078, -4563, -4563, -5043, -5043, -5519, -5519, -5990, -5990, --6455, -6455, -6914, -6914, -7366, -7366, -7811, -7811, -8249, -8249, --8680, -8680, -9102, -9102, -9516, -9516, -9920, -9920, -10315, -10315, --10701, -10701, -11077, -11077, -11442, -11442, -11796, -11796, -12139, -12139, --12471, -12471, -12791, -12791, -13099, -13099, -13395, -13395, -13678, -13678, --13948, -13948, -14205, -14205, -14449, -14449, -14679, -14679, -14895, -14895, --15098, -15098, -15286, -15286, -15459, -15459, -15618, -15618, -15763, -15763, --15892, -15892, -16007, -16007, -16107, -16107, -16191, -16191, -16260, -16260, --16314, -16314, -16353, -16353, -16376, -16376, -16383, -16383, -16376, -16376, --16353, -16353, -16314, -16314, -16260, -16260, -16191, -16191, -16107, -16107, --16007, -16007, -15892, -15892, -15763, -15763, -15618, -15618, -15459, -15459, --15286, -15286, -15098, -15098, -14895, -14895, -14679, -14679, -14449, -14449, --14205, -14205, -13948, -13948, -13678, -13678, -13395, -13395, -13099, -13099, --12791, -12791, -12471, -12471, -12139, -12139, -11796, -11796, -11442, -11442, --11077, -11077, -10701, -10701, -10315, -10315, -9920, -9920, -9516, -9516, --9102, -9102, -8680, -8680, -8249, -8249, -7811, -7811, -7366, -7366, --6914, -6914, -6455, -6455, -5990, -5990, -5519, -5519, -5043, -5043, --4563, -4563, -4078, -4078, -3589, -3589, -3097, -3097, -2602, -2602, --2105, -2105, -1605, -1605, -1105, -1105, -603, -603, -100, -100, -402, 402, 904, 904, 1405, 1405, 1905, 1905, 2404, 2404, -2900, 2900, 3393, 3393, 3883, 3883, 4369, 4369, 4852, 4852, -5329, 5329, 5802, 5802, 6269, 6269, 6731, 6731, 7186, 7186, -7634, 7634, 8075, 8075, 8509, 8509, 8934, 8934, 9351, 9351, -9759, 9759, 10159, 10159, 10548, 10548, 10928, 10928, 11297, 11297, -11656, 11656, 12003, 12003, 12340, 12340, 12665, 12665, 12977, 12977, -13278, 13278, 13566, 13566, 13842, 13842, 14104, 14104, 14353, 14353, -14589, 14589, 14810, 14810, 15018, 15018, 15212, 15212, 15392, 15392, -15557, 15557, 15707, 15707, 15842, 15842, 15963, 15963, 16069, 16069, -16159, 16159, 16234, 16234, 16294, 16294, 16339, 16339, 16368, 16368, -16382, 16382, 16381, 16381, 16364, 16364, 16331, 16331, 16284, 16284, -16221, 16221, 16142, 16142, 16049, 16049, 15940, 15940, 15817, 15817, -15678, 15678, 15525, 15525, 15357, 15357, 15175, 15175, 14978, 14978, -14767, 14767, 14543, 14543, 14304, 14304, 14053, 14053, 13788, 13788, -13510, 13510, 13219, 13219, 12916, 12916, 12600, 12600, 12273, 12273, -11935, 11935, 11585, 11585, 11224, 11224, 10853, 10853, 10471, 10471, -10079, 10079, 9679, 9679, 9268, 9268, 8850, 8850, 8423, 8423, -7988, 7988, 7545, 7545, 7095, 7095, 6639, 6639, 6176, 6176, -5708, 5708, 5234, 5234, 4756, 4756, 4272, 4272, 3785, 3785, -3294, 3294, 2801, 2801, 2304, 2304, 1805, 1805, 1305, 1305, -803, 803, 301, 301, -201, -201, -703, -703, -1205, -1205, --1705, -1705, -2204, -2204, -2701, -2701, -3196, -3196, -3687, -3687, --4175, -4175, -4659, -4659, -5139, -5139, -5614, -5614, -6083, -6083, --6547, -6547, -7005, -7005, -7456, -7456, -7900, -7900, -8336, -8336, --8765, -8765, -9185, -9185, -9597, -9597, -10000, -10000, -10393, -10393, --10777, -10777, -11150, -11150, -11513, -11513, -11866, -11866, -12207, -12207, --12536, -12536, -12854, -12854, -13159, -13159, -13452, -13452, -13733, -13733, --14001, -14001, -14255, -14255, -14496, -14496, -14723, -14723, -14937, -14937, --15136, -15136, -15322, -15322, -15492, -15492, -15649, -15649, -15790, -15790, --15917, -15917, -16028, -16028, -16125, -16125, -16206, -16206, -16272, -16272, --16323, -16323, -16359, -16359, -16379, -16379, -16383, -16383, -16372, -16372, --16346, -16346, -16305, -16305, -16248, -16248, -16175, -16175, -16088, -16088, --15985, -15985, -15868, -15868, -15735, -15735, -15588, -15588, -15426, -15426, --15249, -15249, -15058, -15058, -14853, -14853, -14634, -14634, -14401, -14401, --14155, -14155, -13895, -13895, -13622, -13622, -13337, -13337, -13038, -13038, --12728, -12728, -12406, -12406, -12072, -12072, -11726, -11726, -11370, -11370, --11002, -11002, -10625, -10625, -10237, -10237, -9840, -9840, -9434, -9434, --9018, -9018, -8594, -8594, -8162, -8162, -7723, -7723, -7276, -7276, --6822, -6822, -6362, -6362, -5896, -5896, -5424, -5424, -4948, -4948, --4466, -4466, -3980, -3980, -3491, -3491, -2998, -2998, -2503, -2503, --2005, -2005, -1505, -1505, -1004, -1004, -502, -502 -}; -/*****************************************************************************/ -void -easysnd_testtone(struct easycap *peasycap, int audio_fill) -{ -int i1; -unsigned char *p2; -struct data_buffer *paudio_buffer; - -if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); return; } -JOM(8, "%i=audio_fill\n", audio_fill); -paudio_buffer = &peasycap->audio_buffer[audio_fill]; -p2 = (unsigned char *)(paudio_buffer->pgo); -for (i1 = 0; i1 < PAGE_SIZE; i1 += 4, p2 += 4) { - *p2 = (unsigned char) (0x00FF & tones[i1/2]); - *(p2 + 1) = (unsigned char)((0xFF00 & tones[i1/2]) >> 8); - *(p2 + 2) = (unsigned char) (0x00FF & tones[i1/2 + 1]); - *(p2 + 3) = (unsigned char)((0xFF00 & tones[i1/2 + 1]) >> 8); - } -return; -} -#endif /*EASYCAP_TESTTONE*/ -/*****************************************************************************/ |