aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-07 04:49:05 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-07 04:49:05 -0400
commit0b8e74c6f44094189dbe78baf4101acc7570c6af (patch)
tree6440561d09fb71ba5928664604ec92f29940be6b /drivers/staging
parent7f60ba388f5b9dd8b0da463b394412dace3ab814 (diff)
parentbd0d10498826ed150da5e4c45baf8b9c7088fb71 (diff)
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: "The first part of the media updates for Kernel 3.7. This series contain: - A major tree renaming patch series: now, drivers are organized internally by their used bus, instead of by V4L2 and/or DVB API, providing a cleaner driver location for hybrid drivers that implement both APIs, and allowing to cleanup the Kconfig items and make them more intuitive for the end user; - Media Kernel developers are typically very lazy with their duties of keeping the MAINTAINERS entries for their drivers updated. As now the tree is more organized, we're doing an effort to add/update those entries for the drivers that aren't currently orphan; - Several DVB USB drivers got moved to a new DVB USB v2 core; the new core fixes several bugs (as the existing one that got bitroted). Now, suspend/resume finally started to work fine (at least with some devices - we should expect more work with regards to it); - added multistream support for DVB-T2, and unified the API for DVB-S2 and ISDB-S. Backward binary support is preserved; - as usual, a few new drivers, some V4L2 core improvements and lots of drivers improvements and fixes. There are some points to notice on this series: 1) you should expect a trivial merge conflict on your tree, with the removal of Documentation/feature-removal-schedule.txt: this series would be adding two additional entries there. I opted to not rebase it due to this recent change; 2) With regards to the PCTV 520e udev-related breakage, I opted to fix it in a way that the patches can be backported to 3.5 even without your firmware fix patch. This way, Greg doesn't need to rush backporting your patch (as there are still the firmware cache and firmware path customization issues to be addressed there). I'll send later a patch (likely after the end of the merge window) reverting the rest of the DRX-K async firmware request, fully restoring its original behaviour to allow media drivers to initialize everything serialized as before for 3.7 and upper. 3) I'm planning to work on this weekend to test the DMABUF patches for V4L2. The patches are on my queue for several Kernel cycles, but, up to now, there is/was no way to test the series locally. I have some concerns about this particular changeset with regards to security issues, and with regards to the replacement of the old VIDIOC_OVERLAY ioctl's that is broken on modern systems, due to GPU drivers change. The Overlay API allows direct PCI2PCI transfers from a media capture card into the GPU framebuffer, but its API is crappy. Also, the only existing X11 driver that implements it requires a XV extension that is not available anymore on modern drivers. The DMABUF can do the same thing, but with it is promising to be a properly-designed API. If I can successfully test this series and be happy with it, I should be asking you to pull them next week." * 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (717 commits) em28xx: regression fix: use DRX-K sync firmware requests on em28xx drxk: allow loading firmware synchrousnously em28xx: Make all em28xx extensions to be initialized asynchronously [media] tda18271: properly report read errors in tda18271_get_id [media] tda18271: delay IR & RF calibration until init() if delay_cal is set [media] MAINTAINERS: add Michael Krufky as tda827x maintainer [media] MAINTAINERS: add Michael Krufky as tda8290 maintainer [media] MAINTAINERS: add Michael Krufky as cxusb maintainer [media] MAINTAINERS: add Michael Krufky as lg2160 maintainer [media] MAINTAINERS: add Michael Krufky as lgdt3305 maintainer [media] MAINTAINERS: add Michael Krufky as mxl111sf maintainer [media] MAINTAINERS: add Michael Krufky as mxl5007t maintainer [media] MAINTAINERS: add Michael Krufky as tda18271 maintainer [media] s5p-tv: Report only multi-plane capabilities in vidioc_querycap [media] s5p-mfc: Fix misplaced return statement in s5p_mfc_suspend() [media] exynos-gsc: Add missing static storage class specifiers [media] exynos-gsc: Remove <linux/version.h> header file inclusion [media] s5p-fimc: Fix incorrect condition in fimc_lite_reqbufs() [media] s5p-tv: Fix potential NULL pointer dereference error [media] s5k6aa: Fix possible NULL pointer dereference ...
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/media/Kconfig2
-rw-r--r--drivers/staging/media/Makefile1
-rw-r--r--drivers/staging/media/as102/Makefile2
-rw-r--r--drivers/staging/media/cxd2099/Makefile6
-rw-r--r--drivers/staging/media/cxd2099/cxd2099.c13
-rw-r--r--drivers/staging/media/dt3155v4l/dt3155v4l.c29
-rw-r--r--drivers/staging/media/easycap/Kconfig30
-rw-r--r--drivers/staging/media/easycap/Makefile10
-rw-r--r--drivers/staging/media/easycap/README141
-rw-r--r--drivers/staging/media/easycap/easycap.h567
-rw-r--r--drivers/staging/media/easycap/easycap_ioctl.c2443
-rw-r--r--drivers/staging/media/easycap/easycap_low.c968
-rw-r--r--drivers/staging/media/easycap/easycap_main.c4239
-rw-r--r--drivers/staging/media/easycap/easycap_settings.c696
-rw-r--r--drivers/staging/media/easycap/easycap_sound.c750
-rw-r--r--drivers/staging/media/easycap/easycap_testcard.c155
-rw-r--r--drivers/staging/media/go7007/Makefile6
-rw-r--r--drivers/staging/media/go7007/go7007-v4l2.c4
-rw-r--r--drivers/staging/media/lirc/Kconfig6
-rw-r--r--drivers/staging/media/lirc/Makefile1
-rw-r--r--drivers/staging/media/lirc/lirc_ene0100.h169
-rw-r--r--drivers/staging/media/lirc/lirc_igorplugusb.c4
-rw-r--r--drivers/staging/media/lirc/lirc_ttusbir.c376
-rw-r--r--drivers/staging/media/lirc/lirc_zilog.c3
24 files changed, 40 insertions, 10581 deletions
diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig
index 4f4b7d6281a7..427218b8b10f 100644
--- a/drivers/staging/media/Kconfig
+++ b/drivers/staging/media/Kconfig
@@ -25,8 +25,6 @@ source "drivers/staging/media/cxd2099/Kconfig"
25 25
26source "drivers/staging/media/dt3155v4l/Kconfig" 26source "drivers/staging/media/dt3155v4l/Kconfig"
27 27
28source "drivers/staging/media/easycap/Kconfig"
29
30source "drivers/staging/media/go7007/Kconfig" 28source "drivers/staging/media/go7007/Kconfig"
31 29
32source "drivers/staging/media/solo6x10/Kconfig" 30source "drivers/staging/media/solo6x10/Kconfig"
diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile
index c69124cdb0d3..aec6eb963940 100644
--- a/drivers/staging/media/Makefile
+++ b/drivers/staging/media/Makefile
@@ -1,6 +1,5 @@
1obj-$(CONFIG_DVB_AS102) += as102/ 1obj-$(CONFIG_DVB_AS102) += as102/
2obj-$(CONFIG_DVB_CXD2099) += cxd2099/ 2obj-$(CONFIG_DVB_CXD2099) += cxd2099/
3obj-$(CONFIG_EASYCAP) += easycap/
4obj-$(CONFIG_LIRC_STAGING) += lirc/ 3obj-$(CONFIG_LIRC_STAGING) += lirc/
5obj-$(CONFIG_SOLO6X10) += solo6x10/ 4obj-$(CONFIG_SOLO6X10) += solo6x10/
6obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/ 5obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/
diff --git a/drivers/staging/media/as102/Makefile b/drivers/staging/media/as102/Makefile
index 1bca43e847c7..d8dfb757f1e2 100644
--- a/drivers/staging/media/as102/Makefile
+++ b/drivers/staging/media/as102/Makefile
@@ -3,4 +3,4 @@ dvb-as102-objs := as102_drv.o as102_fw.o as10x_cmd.o as10x_cmd_stream.o \
3 3
4obj-$(CONFIG_DVB_AS102) += dvb-as102.o 4obj-$(CONFIG_DVB_AS102) += dvb-as102.o
5 5
6EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 6EXTRA_CFLAGS += -Idrivers/media/dvb-core
diff --git a/drivers/staging/media/cxd2099/Makefile b/drivers/staging/media/cxd2099/Makefile
index 64cfc77be357..b2905e65057c 100644
--- a/drivers/staging/media/cxd2099/Makefile
+++ b/drivers/staging/media/cxd2099/Makefile
@@ -1,5 +1,5 @@
1obj-$(CONFIG_DVB_CXD2099) += cxd2099.o 1obj-$(CONFIG_DVB_CXD2099) += cxd2099.o
2 2
3ccflags-y += -Idrivers/media/dvb/dvb-core/ 3ccflags-y += -Idrivers/media/dvb-core/
4ccflags-y += -Idrivers/media/dvb/frontends/ 4ccflags-y += -Idrivers/media/dvb-frontends/
5ccflags-y += -Idrivers/media/common/tuners/ 5ccflags-y += -Idrivers/media/tuners/
diff --git a/drivers/staging/media/cxd2099/cxd2099.c b/drivers/staging/media/cxd2099/cxd2099.c
index 1c04185bcfd7..0ff19724992f 100644
--- a/drivers/staging/media/cxd2099/cxd2099.c
+++ b/drivers/staging/media/cxd2099/cxd2099.c
@@ -683,27 +683,26 @@ struct dvb_ca_en50221 *cxd2099_attach(struct cxd2099_cfg *cfg,
683 void *priv, 683 void *priv,
684 struct i2c_adapter *i2c) 684 struct i2c_adapter *i2c)
685{ 685{
686 struct cxd *ci = 0; 686 struct cxd *ci;
687 u8 val; 687 u8 val;
688 688
689 if (i2c_read_reg(i2c, cfg->adr, 0, &val) < 0) { 689 if (i2c_read_reg(i2c, cfg->adr, 0, &val) < 0) {
690 printk(KERN_INFO "No CXD2099 detected at %02x\n", cfg->adr); 690 printk(KERN_INFO "No CXD2099 detected at %02x\n", cfg->adr);
691 return 0; 691 return NULL;
692 } 692 }
693 693
694 ci = kmalloc(sizeof(struct cxd), GFP_KERNEL); 694 ci = kzalloc(sizeof(struct cxd), GFP_KERNEL);
695 if (!ci) 695 if (!ci)
696 return 0; 696 return NULL;
697 memset(ci, 0, sizeof(*ci));
698 697
699 mutex_init(&ci->lock); 698 mutex_init(&ci->lock);
700 memcpy(&ci->cfg, cfg, sizeof(struct cxd2099_cfg)); 699 ci->cfg = *cfg;
701 ci->i2c = i2c; 700 ci->i2c = i2c;
702 ci->lastaddress = 0xff; 701 ci->lastaddress = 0xff;
703 ci->clk_reg_b = 0x4a; 702 ci->clk_reg_b = 0x4a;
704 ci->clk_reg_f = 0x1b; 703 ci->clk_reg_f = 0x1b;
705 704
706 memcpy(&ci->en, &en_templ, sizeof(en_templ)); 705 ci->en = en_templ;
707 ci->en.data = ci; 706 ci->en.data = ci;
708 init(ci); 707 init(ci);
709 printk(KERN_INFO "Attached CXD2099AR at %02x\n", ci->cfg.adr); 708 printk(KERN_INFO "Attached CXD2099AR at %02x\n", ci->cfg.adr);
diff --git a/drivers/staging/media/dt3155v4l/dt3155v4l.c b/drivers/staging/media/dt3155v4l/dt3155v4l.c
index ebe5a27c06f5..2e7b711c8501 100644
--- a/drivers/staging/media/dt3155v4l/dt3155v4l.c
+++ b/drivers/staging/media/dt3155v4l/dt3155v4l.c
@@ -381,6 +381,8 @@ dt3155_open(struct file *filp)
381 int ret = 0; 381 int ret = 0;
382 struct dt3155_priv *pd = video_drvdata(filp); 382 struct dt3155_priv *pd = video_drvdata(filp);
383 383
384 if (mutex_lock_interruptible(&pd->mux))
385 return -ERESTARTSYS;
384 if (!pd->users) { 386 if (!pd->users) {
385 pd->q = kzalloc(sizeof(*pd->q), GFP_KERNEL); 387 pd->q = kzalloc(sizeof(*pd->q), GFP_KERNEL);
386 if (!pd->q) { 388 if (!pd->q) {
@@ -411,6 +413,7 @@ err_request_irq:
411 kfree(pd->q); 413 kfree(pd->q);
412 pd->q = NULL; 414 pd->q = NULL;
413err_alloc_queue: 415err_alloc_queue:
416 mutex_unlock(&pd->mux);
414 return ret; 417 return ret;
415} 418}
416 419
@@ -419,6 +422,7 @@ dt3155_release(struct file *filp)
419{ 422{
420 struct dt3155_priv *pd = video_drvdata(filp); 423 struct dt3155_priv *pd = video_drvdata(filp);
421 424
425 mutex_lock(&pd->mux);
422 pd->users--; 426 pd->users--;
423 BUG_ON(pd->users < 0); 427 BUG_ON(pd->users < 0);
424 if (!pd->users) { 428 if (!pd->users) {
@@ -429,6 +433,7 @@ dt3155_release(struct file *filp)
429 kfree(pd->q); 433 kfree(pd->q);
430 pd->q = NULL; 434 pd->q = NULL;
431 } 435 }
436 mutex_unlock(&pd->mux);
432 return 0; 437 return 0;
433} 438}
434 439
@@ -436,24 +441,38 @@ static ssize_t
436dt3155_read(struct file *filp, char __user *user, size_t size, loff_t *loff) 441dt3155_read(struct file *filp, char __user *user, size_t size, loff_t *loff)
437{ 442{
438 struct dt3155_priv *pd = video_drvdata(filp); 443 struct dt3155_priv *pd = video_drvdata(filp);
444 ssize_t res;
439 445
440 return vb2_read(pd->q, user, size, loff, filp->f_flags & O_NONBLOCK); 446 if (mutex_lock_interruptible(&pd->mux))
447 return -ERESTARTSYS;
448 res = vb2_read(pd->q, user, size, loff, filp->f_flags & O_NONBLOCK);
449 mutex_unlock(&pd->mux);
450 return res;
441} 451}
442 452
443static unsigned int 453static unsigned int
444dt3155_poll(struct file *filp, struct poll_table_struct *polltbl) 454dt3155_poll(struct file *filp, struct poll_table_struct *polltbl)
445{ 455{
446 struct dt3155_priv *pd = video_drvdata(filp); 456 struct dt3155_priv *pd = video_drvdata(filp);
457 unsigned int res;
447 458
448 return vb2_poll(pd->q, filp, polltbl); 459 mutex_lock(&pd->mux);
460 res = vb2_poll(pd->q, filp, polltbl);
461 mutex_unlock(&pd->mux);
462 return res;
449} 463}
450 464
451static int 465static int
452dt3155_mmap(struct file *filp, struct vm_area_struct *vma) 466dt3155_mmap(struct file *filp, struct vm_area_struct *vma)
453{ 467{
454 struct dt3155_priv *pd = video_drvdata(filp); 468 struct dt3155_priv *pd = video_drvdata(filp);
469 int res;
455 470
456 return vb2_mmap(pd->q, vma); 471 if (mutex_lock_interruptible(&pd->mux))
472 return -ERESTARTSYS;
473 res = vb2_mmap(pd->q, vma);
474 mutex_unlock(&pd->mux);
475 return res;
457} 476}
458 477
459static const struct v4l2_file_operations dt3155_fops = { 478static const struct v4l2_file_operations dt3155_fops = {
@@ -898,10 +917,6 @@ dt3155_probe(struct pci_dev *pdev, const struct pci_device_id *id)
898 INIT_LIST_HEAD(&pd->dmaq); 917 INIT_LIST_HEAD(&pd->dmaq);
899 mutex_init(&pd->mux); 918 mutex_init(&pd->mux);
900 pd->vdev->lock = &pd->mux; /* for locking v4l2_file_operations */ 919 pd->vdev->lock = &pd->mux; /* for locking v4l2_file_operations */
901 /* Locking in file operations other than ioctl should be done
902 by the driver, not the V4L2 core.
903 This driver needs auditing so that this flag can be removed. */
904 set_bit(V4L2_FL_LOCK_ALL_FOPS, &pd->vdev->flags);
905 spin_lock_init(&pd->lock); 920 spin_lock_init(&pd->lock);
906 pd->csr2 = csr2_init; 921 pd->csr2 = csr2_init;
907 pd->config = config_init; 922 pd->config = config_init;
diff --git a/drivers/staging/media/easycap/Kconfig b/drivers/staging/media/easycap/Kconfig
deleted file mode 100644
index a425a6f9cdca..000000000000
--- a/drivers/staging/media/easycap/Kconfig
+++ /dev/null
@@ -1,30 +0,0 @@
1config EASYCAP
2 tristate "EasyCAP USB ID 05e1:0408 support"
3 depends on USB && VIDEO_DEV && SND
4 select SND_PCM
5
6 ---help---
7 This is an integrated audio/video driver for EasyCAP cards with
8 USB ID 05e1:0408. It supports two hardware variants:
9
10 * EasyCAP USB 2.0 Video Adapter with Audio, Model DC60,
11 having input cables labelled CVBS, S-VIDEO, AUDIO(L), AUDIO(R)
12
13 * EasyCAP002 4-Channel USB 2.0 DVR, having input cables labelled
14 1, 2, 3, 4 and an unlabelled input cable for a microphone.
15
16 To compile this driver as a module, choose M here: the
17 module will be called easycap
18
19config EASYCAP_DEBUG
20 bool "Enable EasyCAP driver debugging"
21 depends on EASYCAP
22
23 ---help---
24 This option enables debug printouts
25
26 To enable debug, pass the debug level to the debug module
27 parameter:
28
29 modprobe easycap debug=[0..9]
30
diff --git a/drivers/staging/media/easycap/Makefile b/drivers/staging/media/easycap/Makefile
deleted file mode 100644
index a34e75f59c18..000000000000
--- a/drivers/staging/media/easycap/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
1easycap-objs := easycap_main.o
2easycap-objs += easycap_low.o
3easycap-objs += easycap_ioctl.o
4easycap-objs += easycap_settings.o
5easycap-objs += easycap_testcard.o
6easycap-objs += easycap_sound.o
7obj-$(CONFIG_EASYCAP) += easycap.o
8
9ccflags-y := -Wall
10
diff --git a/drivers/staging/media/easycap/README b/drivers/staging/media/easycap/README
deleted file mode 100644
index 796b032384bd..000000000000
--- a/drivers/staging/media/easycap/README
+++ /dev/null
@@ -1,141 +0,0 @@
1
2 ***********************************************************
3 * EasyCAP USB 2.0 Video Adapter with Audio, Model DC60 *
4 * and *
5 * EasyCAP002 4-Channel USB 2.0 DVR *
6 ***********************************************************
7 Mike Thomas <rmthomas@sciolus.org>
8
9
10
11SUPPORTED HARDWARE
12------------------
13
14This driver is intended for use with hardware having USB ID 05e1:0408.
15Two kinds of EasyCAP have this USB ID, namely:
16
17 * EasyCAP USB 2.0 Video Adapter with Audio, Model DC60,
18 having input cables labelled CVBS, S-VIDEO, AUDIO(L), AUDIO(R)
19
20 * EasyCAP002 4-Channel USB 2.0 DVR, having input cables labelled
21 1, 2, 3, 4 and an unlabelled input cable for a microphone.
22
23
24BUILD OPTIONS AND DEPENDENCIES
25------------------------------
26
27Unless EASYCAP_DEBUG is defined during compilation it will not be possible
28to select a debug level at the time of module installation.
29
30
31KNOWN RUNTIME ISSUES
32--------------------
33
34(1) Intentionally, this driver will not stream material which is unambiguously
35identified by the hardware as copy-protected. Normal video output will be
36present for about a minute but will then freeze when this situation arises.
37
38(2) The controls for luminance, contrast, saturation, hue and volume may not
39always work properly.
40
41(3) Reduced-resolution S-Video seems to suffer from moire artefacts.
42
43
44INPUT NUMBERING
45---------------
46
47For the EasyCAP with S-VIDEO input cable the driver regards a request for
48inputs numbered 0 or 1 as referring to CVBS and a request for input
49numbered 5 as referring to S-VIDEO.
50
51For the EasyCAP with four CVBS inputs the driver expects to be asked for
52any one of inputs numbered 1,2,3,4. If input 0 is asked for, it is
53interpreted as input 1.
54
55
56MODULE PARAMETERS
57-----------------
58
59Three module parameters are defined:
60
61debug the easycap module is configured at diagnostic level n (0 to 9)
62gain audio gain level n (0 to 31, default is 16)
63bars whether to display testcard bars when incoming video signal is lost
64 0 => no, 1 => yes (default)
65
66
67SUPPORTED TV STANDARDS AND RESOLUTIONS
68--------------------------------------
69
70The following TV standards are natively supported by the hardware and are
71usable as (for example) the "norm=" parameter in the mplayer command:
72
73 PAL_BGHIN, NTSC_N_443,
74 PAL_Nc, NTSC_N,
75 SECAM, NTSC_M, NTSC_M_JP,
76 PAL_60, NTSC_443,
77 PAL_M.
78
79In addition, the driver offers "custom" pseudo-standards with a framerate
80which is 20% of the usual framerate. These pseudo-standards are named:
81
82 PAL_BGHIN_SLOW, NTSC_N_443_SLOW,
83 PAL_Nc_SLOW, NTSC_N_SLOW,
84 SECAM_SLOW, NTSC_M_SLOW, NTSC_M_JP_SLOW,
85 PAL_60_SLOW, NTSC_443_SLOW,
86 PAL_M_SLOW.
87
88
89The available picture sizes are:
90
91 at 25 frames per second: 720x576, 704x576, 640x480, 360x288, 320x240;
92 at 30 frames per second: 720x480, 640x480, 360x240, 320x240.
93
94
95WHAT'S TESTED AND WHAT'S NOT
96----------------------------
97
98This driver is known to work with mplayer, mencoder, tvtime, zoneminder,
99xawtv, gstreamer and sufficiently recent versions of vlc. An interface
100to ffmpeg is implemented, but serious audio-video synchronization problems
101remain.
102
103The driver is designed to support all the TV standards accepted by the
104hardware, but as yet it has actually been tested on only a few of these.
105
106I have been unable to test and calibrate the S-video input myself because I
107do not possess any equipment with S-video output.
108
109
110UDEV RULES
111----------
112
113In order that the special files /dev/easycap0 and /dev/easysnd1 are created
114with conveniently relaxed permissions when the EasyCAP is plugged in, a file
115is preferably to be provided in directory /etc/udev/rules.d with content:
116
117ACTION!="add|change", GOTO="easycap_rules_end"
118ATTRS{idVendor}=="05e1", ATTRS{idProduct}=="0408", \
119 MODE="0666", OWNER="root", GROUP="root"
120LABEL="easycap_rules_end"
121
122
123MODPROBE CONFIGURATION
124----------------------
125
126The easycap module is in competition with the module snd-usb-audio for the
127EasyCAP's audio channel, and its installation can be aided by providing a
128file in directory /etc/modprobe.d with content:
129
130options easycap gain=16 bars=1
131install easycap /sbin/rmmod snd-usb-audio; /sbin/modprobe --ignore-install easycap
132
133
134ACKNOWLEGEMENTS AND REFERENCES
135------------------------------
136This driver makes use of information contained in the Syntek Semicon DC-1125
137Driver, presently maintained at http://sourceforge.net/projects/syntekdriver/
138by Nicolas Vivien. Particularly useful has been a patch to the latter driver
139provided by Ivor Hewitt in January 2009. The NTSC implementation is taken
140from the work of Ben Trask.
141
diff --git a/drivers/staging/media/easycap/easycap.h b/drivers/staging/media/easycap/easycap.h
deleted file mode 100644
index a007e7442be8..000000000000
--- a/drivers/staging/media/easycap/easycap.h
+++ /dev/null
@@ -1,567 +0,0 @@
1/*****************************************************************************
2* *
3* easycap.h *
4* *
5*****************************************************************************/
6/*
7 *
8 * Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
9 *
10 *
11 * This is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The software is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this software; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25*/
26/*****************************************************************************/
27/*---------------------------------------------------------------------------*/
28/*
29 * THE FOLLOWING PARAMETERS ARE UNDEFINED:
30 *
31 * EASYCAP_DEBUG
32 *
33 * IF REQUIRED THEY MUST BE EXTERNALLY DEFINED, FOR EXAMPLE AS COMPILER
34 * OPTIONS.
35 */
36/*---------------------------------------------------------------------------*/
37
38#ifndef __EASYCAP_H__
39#define __EASYCAP_H__
40
41/*---------------------------------------------------------------------------*/
42/*
43 * THESE ARE NORMALLY DEFINED
44 */
45/*---------------------------------------------------------------------------*/
46#define PATIENCE 500
47#define PERSEVERE
48/*---------------------------------------------------------------------------*/
49/*
50 * THESE ARE FOR MAINTENANCE ONLY - NORMALLY UNDEFINED:
51 */
52/*---------------------------------------------------------------------------*/
53#undef EASYCAP_TESTCARD
54/*---------------------------------------------------------------------------*/
55#include <linux/kernel.h>
56#include <linux/errno.h>
57#include <linux/init.h>
58#include <linux/slab.h>
59#include <linux/module.h>
60#include <linux/kref.h>
61#include <linux/usb.h>
62#include <linux/uaccess.h>
63
64#include <linux/i2c.h>
65#include <linux/workqueue.h>
66#include <linux/poll.h>
67#include <linux/mm.h>
68#include <linux/fs.h>
69#include <linux/delay.h>
70#include <linux/types.h>
71
72#include <linux/vmalloc.h>
73#include <linux/sound.h>
74#include <sound/core.h>
75#include <sound/pcm.h>
76#include <sound/pcm_params.h>
77#include <sound/info.h>
78#include <sound/initval.h>
79#include <sound/control.h>
80#include <media/v4l2-dev.h>
81#include <media/v4l2-device.h>
82#include <linux/videodev2.h>
83#include <linux/soundcard.h>
84
85/*---------------------------------------------------------------------------*/
86/* VENDOR, PRODUCT: Syntek Semiconductor Co., Ltd
87 *
88 * EITHER EasyCAP USB 2.0 Video Adapter with Audio, Model No. DC60
89 * with input cabling: AUDIO(L), AUDIO(R), CVBS, S-VIDEO.
90 *
91 * OR EasyCAP 4CHANNEL USB 2.0 DVR, Model No. EasyCAP002
92 * with input cabling: MICROPHONE, CVBS1, CVBS2, CVBS3, CVBS4.
93 */
94/*---------------------------------------------------------------------------*/
95#define USB_EASYCAP_VENDOR_ID 0x05e1
96#define USB_EASYCAP_PRODUCT_ID 0x0408
97
98#define EASYCAP_DRIVER_VERSION "0.9.01"
99#define EASYCAP_DRIVER_DESCRIPTION "easycapdc60"
100
101#define DONGLE_MANY 8
102#define INPUT_MANY 6
103/*---------------------------------------------------------------------------*/
104/*
105 * DEFAULT LUMINANCE, CONTRAST, SATURATION AND HUE
106 */
107/*---------------------------------------------------------------------------*/
108#define SAA_0A_DEFAULT 0x7F
109#define SAA_0B_DEFAULT 0x3F
110#define SAA_0C_DEFAULT 0x2F
111#define SAA_0D_DEFAULT 0x00
112/*---------------------------------------------------------------------------*/
113/*
114 * VIDEO STREAMING PARAMETERS:
115 * USB 2.0 PROVIDES FOR HIGH-BANDWIDTH ENDPOINTS WITH AN UPPER LIMIT
116 * OF 3072 BYTES PER MICROFRAME for wMaxPacketSize.
117 */
118/*---------------------------------------------------------------------------*/
119#define VIDEO_ISOC_BUFFER_MANY 16
120#define VIDEO_ISOC_ORDER 3
121#define VIDEO_ISOC_FRAMESPERDESC ((unsigned int) 1 << VIDEO_ISOC_ORDER)
122#define USB_2_0_MAXPACKETSIZE 3072
123#if (USB_2_0_MAXPACKETSIZE > PAGE_SIZE)
124#error video_isoc_buffer[.] will not be big enough
125#endif
126#define VIDEO_JUNK_TOLERATE VIDEO_ISOC_BUFFER_MANY
127#define VIDEO_LOST_TOLERATE 50
128/*---------------------------------------------------------------------------*/
129/*
130 * VIDEO BUFFERS
131 */
132/*---------------------------------------------------------------------------*/
133#define FIELD_BUFFER_SIZE (203 * PAGE_SIZE)
134#define FRAME_BUFFER_SIZE (405 * PAGE_SIZE)
135#define FIELD_BUFFER_MANY 4
136#define FRAME_BUFFER_MANY 6
137/*---------------------------------------------------------------------------*/
138/*
139 * AUDIO STREAMING PARAMETERS
140 */
141/*---------------------------------------------------------------------------*/
142#define AUDIO_ISOC_BUFFER_MANY 16
143#define AUDIO_ISOC_ORDER 1
144#define AUDIO_ISOC_FRAMESPERDESC 32
145#define AUDIO_ISOC_BUFFER_SIZE (PAGE_SIZE << AUDIO_ISOC_ORDER)
146/*---------------------------------------------------------------------------*/
147/*
148 * AUDIO BUFFERS
149 */
150/*---------------------------------------------------------------------------*/
151#define AUDIO_FRAGMENT_MANY 32
152#define PAGES_PER_AUDIO_FRAGMENT 4
153/*---------------------------------------------------------------------------*/
154/*
155 * IT IS ESSENTIAL THAT EVEN-NUMBERED STANDARDS ARE 25 FRAMES PER SECOND,
156 * ODD-NUMBERED STANDARDS ARE 30 FRAMES PER SECOND.
157 * THE NUMBERING OF STANDARDS MUST NOT BE CHANGED WITHOUT DUE CARE. NOT
158 * ONLY MUST THE PARAMETER
159 * STANDARD_MANY
160 * BE CHANGED TO CORRESPOND TO THE NEW NUMBER OF STANDARDS, BUT ALSO THE
161 * NUMBERING MUST REMAIN AN UNBROKEN ASCENDING SEQUENCE: DUMMY STANDARDS
162 * MAY NEED TO BE ADDED. APPROPRIATE CHANGES WILL ALWAYS BE REQUIRED IN
163 * ROUTINE fillin_formats() AND POSSIBLY ELSEWHERE. BEWARE.
164 */
165/*---------------------------------------------------------------------------*/
166#define PAL_BGHIN 0
167#define PAL_Nc 2
168#define SECAM 4
169#define NTSC_N 6
170#define NTSC_N_443 8
171#define NTSC_M 1
172#define NTSC_443 3
173#define NTSC_M_JP 5
174#define PAL_60 7
175#define PAL_M 9
176#define PAL_BGHIN_SLOW 10
177#define PAL_Nc_SLOW 12
178#define SECAM_SLOW 14
179#define NTSC_N_SLOW 16
180#define NTSC_N_443_SLOW 18
181#define NTSC_M_SLOW 11
182#define NTSC_443_SLOW 13
183#define NTSC_M_JP_SLOW 15
184#define PAL_60_SLOW 17
185#define PAL_M_SLOW 19
186#define STANDARD_MANY 20
187/*---------------------------------------------------------------------------*/
188/*
189 * ENUMS
190 */
191/*---------------------------------------------------------------------------*/
192enum {
193 AT_720x576,
194 AT_704x576,
195 AT_640x480,
196 AT_720x480,
197 AT_360x288,
198 AT_320x240,
199 AT_360x240,
200 RESOLUTION_MANY
201};
202enum {
203 FMT_UYVY,
204 FMT_YUY2,
205 FMT_RGB24,
206 FMT_RGB32,
207 FMT_BGR24,
208 FMT_BGR32,
209 PIXELFORMAT_MANY
210};
211enum {
212 FIELD_NONE,
213 FIELD_INTERLACED,
214 INTERLACE_MANY
215};
216#define SETTINGS_MANY (STANDARD_MANY * \
217 RESOLUTION_MANY * \
218 2 * \
219 PIXELFORMAT_MANY * \
220 INTERLACE_MANY)
221/*---------------------------------------------------------------------------*/
222/*
223 * STRUCTURE DEFINITIONS
224 */
225/*---------------------------------------------------------------------------*/
226struct easycap_dongle {
227 struct easycap *peasycap;
228 struct mutex mutex_video;
229 struct mutex mutex_audio;
230};
231/*---------------------------------------------------------------------------*/
232struct data_buffer {
233 struct list_head list_head;
234 void *pgo;
235 void *pto;
236 u16 kount;
237 u16 input;
238};
239/*---------------------------------------------------------------------------*/
240struct data_urb {
241 struct list_head list_head;
242 struct urb *purb;
243 int isbuf;
244 int length;
245};
246/*---------------------------------------------------------------------------*/
247struct easycap_standard {
248 u16 mask;
249struct v4l2_standard v4l2_standard;
250};
251struct easycap_format {
252 u16 mask;
253 char name[128];
254struct v4l2_format v4l2_format;
255};
256struct inputset {
257 int input;
258 int input_ok;
259 int standard_offset;
260 int standard_offset_ok;
261 int format_offset;
262 int format_offset_ok;
263 int brightness;
264 int brightness_ok;
265 int contrast;
266 int contrast_ok;
267 int saturation;
268 int saturation_ok;
269 int hue;
270 int hue_ok;
271};
272/*---------------------------------------------------------------------------*/
273/*
274 * easycap.ilk == 0 => CVBS+S-VIDEO HARDWARE, AUDIO wMaxPacketSize=256
275 * easycap.ilk == 2 => CVBS+S-VIDEO HARDWARE, AUDIO wMaxPacketSize=9
276 * easycap.ilk == 3 => FOUR-CVBS HARDWARE, AUDIO wMaxPacketSize=9
277 */
278/*---------------------------------------------------------------------------*/
279struct easycap {
280 int isdongle;
281 int minor;
282
283 struct video_device video_device;
284 struct v4l2_device v4l2_device;
285
286 int status;
287 unsigned int audio_pages_per_fragment;
288 unsigned int audio_bytes_per_fragment;
289 unsigned int audio_buffer_page_many;
290
291#define UPSAMPLE
292#ifdef UPSAMPLE
293 s16 oldaudio;
294#endif /*UPSAMPLE*/
295
296 int ilk;
297 bool microphone;
298
299 struct usb_device *pusb_device;
300 struct usb_interface *pusb_interface;
301
302 struct kref kref;
303
304 int queued[FRAME_BUFFER_MANY];
305 int done[FRAME_BUFFER_MANY];
306
307 wait_queue_head_t wq_video;
308 wait_queue_head_t wq_audio;
309 wait_queue_head_t wq_trigger;
310
311 int input;
312 int polled;
313 int standard_offset;
314 int format_offset;
315 struct inputset inputset[INPUT_MANY];
316
317 bool ntsc;
318 int fps;
319 int usec;
320 int tolerate;
321 int skip;
322 int skipped;
323 int lost[INPUT_MANY];
324 int merit[180];
325
326 int video_interface;
327 int video_altsetting_on;
328 int video_altsetting_off;
329 int video_endpointnumber;
330 int video_isoc_maxframesize;
331 int video_isoc_buffer_size;
332 int video_isoc_framesperdesc;
333
334 int video_isoc_streaming;
335 int video_isoc_sequence;
336 int video_idle;
337 int video_eof;
338 int video_junk;
339
340 struct data_buffer video_isoc_buffer[VIDEO_ISOC_BUFFER_MANY];
341 struct data_buffer field_buffer[FIELD_BUFFER_MANY]
342 [(FIELD_BUFFER_SIZE/PAGE_SIZE)];
343 struct data_buffer frame_buffer[FRAME_BUFFER_MANY]
344 [(FRAME_BUFFER_SIZE/PAGE_SIZE)];
345
346 struct list_head urb_video_head;
347 struct list_head *purb_video_head;
348
349 u8 cache[8];
350 u8 *pcache;
351 int video_mt;
352 int audio_mt;
353 u32 isequence;
354
355 int vma_many;
356/*---------------------------------------------------------------------------*/
357/*
358 * BUFFER INDICATORS
359 */
360/*---------------------------------------------------------------------------*/
361 int field_fill; /* Field buffer being filled by easycap_complete(). */
362 /* Bumped only by easycap_complete(). */
363 int field_page; /* Page of field buffer page being filled by */
364 /* easycap_complete(). */
365 int field_read; /* Field buffer to be read by field2frame(). */
366 /* Bumped only by easycap_complete(). */
367 int frame_fill; /* Frame buffer being filled by field2frame(). */
368 /* Bumped only by easycap_dqbuf() when */
369 /* field2frame() has created a complete frame. */
370 int frame_read; /* Frame buffer offered to user by DQBUF. */
371 /* Set only by easycap_dqbuf() to trail frame_fill.*/
372 int frame_lock; /* Flag set to 1 by DQBUF and cleared by QBUF */
373/*---------------------------------------------------------------------------*/
374/*
375 * IMAGE PROPERTIES
376 */
377/*---------------------------------------------------------------------------*/
378 u32 pixelformat;
379 int width;
380 int height;
381 int bytesperpixel;
382 bool byteswaporder;
383 bool decimatepixel;
384 bool offerfields;
385 int frame_buffer_used;
386 int frame_buffer_many;
387 int videofieldamount;
388
389 int brightness;
390 int contrast;
391 int saturation;
392 int hue;
393
394 int allocation_video_urb;
395 int allocation_video_page;
396 int allocation_video_struct;
397 int registered_video;
398/*---------------------------------------------------------------------------*/
399/*
400 * ALSA
401 */
402/*---------------------------------------------------------------------------*/
403 struct snd_pcm_hardware alsa_hardware;
404 struct snd_card *psnd_card;
405 struct snd_pcm *psnd_pcm;
406 struct snd_pcm_substream *psubstream;
407 int dma_fill;
408 int dma_next;
409 int dma_read;
410/*---------------------------------------------------------------------------*/
411/*
412 * SOUND PROPERTIES
413 */
414/*---------------------------------------------------------------------------*/
415 int audio_interface;
416 int audio_altsetting_on;
417 int audio_altsetting_off;
418 int audio_endpointnumber;
419 int audio_isoc_maxframesize;
420 int audio_isoc_buffer_size;
421 int audio_isoc_framesperdesc;
422
423 int audio_isoc_streaming;
424 int audio_idle;
425 int audio_eof;
426 int volume;
427 int mute;
428 s8 gain;
429
430 struct data_buffer audio_isoc_buffer[AUDIO_ISOC_BUFFER_MANY];
431
432 struct list_head urb_audio_head;
433 struct list_head *purb_audio_head;
434/*---------------------------------------------------------------------------*/
435/*
436 * BUFFER INDICATORS
437 */
438/*---------------------------------------------------------------------------*/
439 int audio_fill; /* Audio buffer being filled by easycap_complete(). */
440 /* Bumped only by easycap_complete(). */
441 int audio_read; /* Audio buffer page being read by easycap_read(). */
442 /* Set by easycap_read() to trail audio_fill by */
443 /* one fragment. */
444/*---------------------------------------------------------------------------*/
445/*
446 * SOUND PROPERTIES
447 */
448/*---------------------------------------------------------------------------*/
449 int allocation_audio_urb;
450 int allocation_audio_page;
451 int allocation_audio_struct;
452 int registered_audio;
453
454 long long int audio_sample;
455 long long int audio_niveau;
456 long long int audio_square;
457
458 struct data_buffer audio_buffer[];
459};
460/*---------------------------------------------------------------------------*/
461/*
462 * VIDEO FUNCTION PROTOTYPES
463 */
464/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
465int easycap_newinput(struct easycap *, int);
466void easycap_testcard(struct easycap *, int);
467int easycap_isdongle(struct easycap *);
468
469long easycap_unlocked_ioctl(struct file *, unsigned int, unsigned long);
470
471int easycap_video_dqbuf(struct easycap *, int);
472int easycap_video_submit_urbs(struct easycap *);
473int easycap_video_kill_urbs(struct easycap *);
474int easycap_video_fillin_formats(void);
475
476int adjust_standard(struct easycap *, v4l2_std_id);
477int adjust_format(struct easycap *, u32, u32, u32, int, bool);
478int adjust_brightness(struct easycap *, int);
479int adjust_contrast(struct easycap *, int);
480int adjust_saturation(struct easycap *, int);
481int adjust_hue(struct easycap *, int);
482/*---------------------------------------------------------------------------*/
483/*
484 * AUDIO FUNCTION PROTOTYPES
485 */
486/*---------------------------------------------------------------------------*/
487int easycap_alsa_probe(struct easycap *);
488int easycap_audio_kill_urbs(struct easycap *);
489void easycap_alsa_complete(struct urb *);
490/*---------------------------------------------------------------------------*/
491/*
492 * LOW-LEVEL FUNCTION PROTOTYPES
493 */
494/*---------------------------------------------------------------------------*/
495int easycap_audio_gainset(struct usb_device *, s8);
496int easycap_audio_setup(struct easycap *);
497
498int easycap_wakeup_device(struct usb_device *);
499
500int setup_stk(struct usb_device *, bool);
501int setup_saa(struct usb_device *, bool);
502int ready_saa(struct usb_device *);
503int merit_saa(struct usb_device *);
504int check_vt(struct usb_device *);
505int select_input(struct usb_device *, int, int);
506int set_resolution(struct usb_device *, u16, u16, u16, u16);
507
508int read_saa(struct usb_device *, u16);
509int write_saa(struct usb_device *, u16, u16);
510int start_100(struct usb_device *);
511int stop_100(struct usb_device *);
512/*---------------------------------------------------------------------------*/
513
514
515/*---------------------------------------------------------------------------*/
516/*
517 * MACROS SAM(...) AND JOM(...) ALLOW DIAGNOSTIC OUTPUT TO BE TAGGED WITH
518 * THE IDENTITY OF THE DONGLE TO WHICH IT APPLIES, BUT IF INVOKED WHEN THE
519 * POINTER peasycap IS INVALID AN Oops IS LIKELY, AND ITS CAUSE MAY NOT BE
520 * IMMEDIATELY OBVIOUS FROM A CASUAL READING OF THE SOURCE CODE. BEWARE.
521*/
522/*---------------------------------------------------------------------------*/
523const char *strerror(int err);
524
525#define SAY(format, args...) do { \
526 printk(KERN_DEBUG "easycap:: %s: " \
527 format, __func__, ##args); \
528} while (0)
529#define SAM(format, args...) do { \
530 printk(KERN_DEBUG "easycap::%i%s: " \
531 format, peasycap->isdongle, __func__, ##args);\
532} while (0)
533
534#ifdef CONFIG_EASYCAP_DEBUG
535extern int easycap_debug;
536#define JOT(n, format, args...) do { \
537 if (n <= easycap_debug) { \
538 printk(KERN_DEBUG "easycap:: %s: " \
539 format, __func__, ##args);\
540 } \
541} while (0)
542#define JOM(n, format, args...) do { \
543 if (n <= easycap_debug) { \
544 printk(KERN_DEBUG "easycap::%i%s: " \
545 format, peasycap->isdongle, __func__, ##args);\
546 } \
547} while (0)
548
549#else
550#define JOT(n, format, args...) do {} while (0)
551#define JOM(n, format, args...) do {} while (0)
552#endif /* CONFIG_EASYCAP_DEBUG */
553
554/*---------------------------------------------------------------------------*/
555
556/*---------------------------------------------------------------------------*/
557/* globals
558 */
559/*---------------------------------------------------------------------------*/
560
561extern bool easycap_readback;
562extern const struct easycap_standard easycap_standard[];
563extern struct easycap_format easycap_format[];
564extern struct v4l2_queryctrl easycap_control[];
565extern struct easycap_dongle easycapdc60_dongle[];
566
567#endif /* !__EASYCAP_H__ */
diff --git a/drivers/staging/media/easycap/easycap_ioctl.c b/drivers/staging/media/easycap/easycap_ioctl.c
deleted file mode 100644
index 3cee3cd986d2..000000000000
--- a/drivers/staging/media/easycap/easycap_ioctl.c
+++ /dev/null
@@ -1,2443 +0,0 @@
1/******************************************************************************
2* *
3* easycap_ioctl.c *
4* *
5******************************************************************************/
6/*
7 *
8 * Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
9 *
10 *
11 * This is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The software is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this software; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25*/
26/*****************************************************************************/
27
28#include "easycap.h"
29#include <linux/version.h>
30
31/*--------------------------------------------------------------------------*/
32/*
33 * UNLESS THERE IS A PREMATURE ERROR RETURN THIS ROUTINE UPDATES THE
34 * FOLLOWING:
35 * peasycap->standard_offset
36 * peasycap->inputset[peasycap->input].standard_offset
37 * peasycap->fps
38 * peasycap->usec
39 * peasycap->tolerate
40 * peasycap->skip
41 */
42/*---------------------------------------------------------------------------*/
43int adjust_standard(struct easycap *peasycap, v4l2_std_id std_id)
44{
45 struct easycap_standard const *peasycap_standard;
46 u16 reg, set;
47 int ir, rc, need, k;
48 unsigned int itwas, isnow;
49 bool resubmit;
50
51 if (!peasycap) {
52 SAY("ERROR: peasycap is NULL\n");
53 return -EFAULT;
54 }
55 if (!peasycap->pusb_device) {
56 SAM("ERROR: peasycap->pusb_device is NULL\n");
57 return -EFAULT;
58 }
59 peasycap_standard = &easycap_standard[0];
60 while (0xFFFF != peasycap_standard->mask) {
61 if (std_id == peasycap_standard->v4l2_standard.id)
62 break;
63 peasycap_standard++;
64 }
65 if (0xFFFF == peasycap_standard->mask) {
66 peasycap_standard = &easycap_standard[0];
67 while (0xFFFF != peasycap_standard->mask) {
68 if (std_id & peasycap_standard->v4l2_standard.id)
69 break;
70 peasycap_standard++;
71 }
72 }
73 if (0xFFFF == peasycap_standard->mask) {
74 SAM("ERROR: 0x%08X=std_id: standard not found\n",
75 (unsigned int)std_id);
76 return -EINVAL;
77 }
78 SAM("selected standard: %s\n",
79 &(peasycap_standard->v4l2_standard.name[0]));
80 if (peasycap->standard_offset == peasycap_standard - easycap_standard) {
81 SAM("requested standard already in effect\n");
82 return 0;
83 }
84 peasycap->standard_offset = peasycap_standard - easycap_standard;
85 for (k = 0; k < INPUT_MANY; k++) {
86 if (!peasycap->inputset[k].standard_offset_ok) {
87 peasycap->inputset[k].standard_offset =
88 peasycap->standard_offset;
89 }
90 }
91 if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
92 peasycap->inputset[peasycap->input].standard_offset =
93 peasycap->standard_offset;
94 peasycap->inputset[peasycap->input].standard_offset_ok = 1;
95 } else
96 JOM(8, "%i=peasycap->input\n", peasycap->input);
97
98 peasycap->fps = peasycap_standard->v4l2_standard.frameperiod.denominator /
99 peasycap_standard->v4l2_standard.frameperiod.numerator;
100 switch (peasycap->fps) {
101 case 6:
102 case 30: {
103 peasycap->ntsc = true;
104 break;
105 }
106 case 5:
107 case 25: {
108 peasycap->ntsc = false;
109 break;
110 }
111 default: {
112 SAM("MISTAKE: %i=frames-per-second\n", peasycap->fps);
113 return -ENOENT;
114 }
115 }
116 JOM(8, "%i frames-per-second\n", peasycap->fps);
117 if (0x8000 & peasycap_standard->mask) {
118 peasycap->skip = 5;
119 peasycap->usec = 1000000 / (2 * (5 * peasycap->fps));
120 peasycap->tolerate = 1000 * (25 / (5 * peasycap->fps));
121 } else {
122 peasycap->skip = 0;
123 peasycap->usec = 1000000 / (2 * peasycap->fps);
124 peasycap->tolerate = 1000 * (25 / peasycap->fps);
125 }
126 if (peasycap->video_isoc_streaming) {
127 resubmit = true;
128 easycap_video_kill_urbs(peasycap);
129 } else
130 resubmit = false;
131/*--------------------------------------------------------------------------*/
132/*
133 * SAA7113H DATASHEET PAGE 44, TABLE 42
134 */
135/*--------------------------------------------------------------------------*/
136 need = 0;
137 itwas = 0;
138 reg = 0x00;
139 set = 0x00;
140 switch (peasycap_standard->mask & 0x000F) {
141 case NTSC_M_JP: {
142 reg = 0x0A;
143 set = 0x95;
144 ir = read_saa(peasycap->pusb_device, reg);
145 if (0 > ir)
146 SAM("ERROR: cannot read SAA register 0x%02X\n", reg);
147 else
148 itwas = (unsigned int)ir;
149 rc = write_saa(peasycap->pusb_device, reg, set);
150 if (rc)
151 SAM("ERROR: failed to set SAA register "
152 "0x%02X to 0x%02X for JP standard\n", reg, set);
153 else {
154 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
155 if (0 > ir)
156 JOM(8, "SAA register 0x%02X changed "
157 "to 0x%02X\n", reg, isnow);
158 else
159 JOM(8, "SAA register 0x%02X changed "
160 "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
161 }
162
163 reg = 0x0B;
164 set = 0x48;
165 ir = read_saa(peasycap->pusb_device, reg);
166 if (0 > ir)
167 SAM("ERROR: cannot read SAA register 0x%02X\n", reg);
168 else
169 itwas = (unsigned int)ir;
170 rc = write_saa(peasycap->pusb_device, reg, set);
171 if (rc)
172 SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X "
173 "for JP standard\n", reg, set);
174 else {
175 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
176 if (0 > ir)
177 JOM(8, "SAA register 0x%02X changed "
178 "to 0x%02X\n", reg, isnow);
179 else
180 JOM(8, "SAA register 0x%02X changed "
181 "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
182 }
183/*--------------------------------------------------------------------------*/
184/*
185 * NOTE: NO break HERE: RUN ON TO NEXT CASE
186 */
187/*--------------------------------------------------------------------------*/
188 }
189 case NTSC_M:
190 case PAL_BGHIN: {
191 reg = 0x0E;
192 set = 0x01;
193 need = 1;
194 break;
195 }
196 case NTSC_N_443:
197 case PAL_60: {
198 reg = 0x0E;
199 set = 0x11;
200 need = 1;
201 break;
202 }
203 case NTSC_443:
204 case PAL_Nc: {
205 reg = 0x0E;
206 set = 0x21;
207 need = 1;
208 break;
209 }
210 case NTSC_N:
211 case PAL_M: {
212 reg = 0x0E;
213 set = 0x31;
214 need = 1;
215 break;
216 }
217 case SECAM: {
218 reg = 0x0E;
219 set = 0x51;
220 need = 1;
221 break;
222 }
223 default:
224 break;
225 }
226/*--------------------------------------------------------------------------*/
227 if (need) {
228 ir = read_saa(peasycap->pusb_device, reg);
229 if (0 > ir)
230 SAM("ERROR: failed to read SAA register 0x%02X\n", reg);
231 else
232 itwas = (unsigned int)ir;
233 rc = write_saa(peasycap->pusb_device, reg, set);
234 if (0 != write_saa(peasycap->pusb_device, reg, set)) {
235 SAM("ERROR: failed to set SAA register "
236 "0x%02X to 0x%02X for table 42\n", reg, set);
237 } else {
238 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
239 if (0 > ir)
240 JOM(8, "SAA register 0x%02X changed "
241 "to 0x%02X\n", reg, isnow);
242 else
243 JOM(8, "SAA register 0x%02X changed "
244 "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
245 }
246 }
247/*--------------------------------------------------------------------------*/
248/*
249 * SAA7113H DATASHEET PAGE 41
250 */
251/*--------------------------------------------------------------------------*/
252 reg = 0x08;
253 ir = read_saa(peasycap->pusb_device, reg);
254 if (0 > ir)
255 SAM("ERROR: failed to read SAA register 0x%02X "
256 "so cannot reset\n", reg);
257 else {
258 itwas = (unsigned int)ir;
259 if (peasycap_standard->mask & 0x0001)
260 set = itwas | 0x40 ;
261 else
262 set = itwas & ~0x40 ;
263 rc = write_saa(peasycap->pusb_device, reg, set);
264 if (rc)
265 SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n",
266 reg, set);
267 else {
268 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
269 if (0 > ir)
270 JOM(8, "SAA register 0x%02X changed to 0x%02X\n",
271 reg, isnow);
272 else
273 JOM(8, "SAA register 0x%02X changed "
274 "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
275 }
276 }
277/*--------------------------------------------------------------------------*/
278/*
279 * SAA7113H DATASHEET PAGE 51, TABLE 57
280 */
281/*---------------------------------------------------------------------------*/
282 reg = 0x40;
283 ir = read_saa(peasycap->pusb_device, reg);
284 if (0 > ir)
285 SAM("ERROR: failed to read SAA register 0x%02X "
286 "so cannot reset\n", reg);
287 else {
288 itwas = (unsigned int)ir;
289 if (peasycap_standard->mask & 0x0001)
290 set = itwas | 0x80 ;
291 else
292 set = itwas & ~0x80 ;
293 rc = write_saa(peasycap->pusb_device, reg, set);
294 if (rc)
295 SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n",
296 reg, set);
297 else {
298 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
299 if (0 > ir)
300 JOM(8, "SAA register 0x%02X changed to 0x%02X\n",
301 reg, isnow);
302 else
303 JOM(8, "SAA register 0x%02X changed "
304 "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
305 }
306 }
307/*--------------------------------------------------------------------------*/
308/*
309 * SAA7113H DATASHEET PAGE 53, TABLE 66
310 */
311/*--------------------------------------------------------------------------*/
312 reg = 0x5A;
313 ir = read_saa(peasycap->pusb_device, reg);
314 if (0 > ir)
315 SAM("ERROR: failed to read SAA register 0x%02X but continuing\n", reg);
316 itwas = (unsigned int)ir;
317 if (peasycap_standard->mask & 0x0001)
318 set = 0x0A ;
319 else
320 set = 0x07 ;
321 if (0 != write_saa(peasycap->pusb_device, reg, set))
322 SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n",
323 reg, set);
324 else {
325 isnow = (unsigned int)read_saa(peasycap->pusb_device, reg);
326 if (0 > ir)
327 JOM(8, "SAA register 0x%02X changed "
328 "to 0x%02X\n", reg, isnow);
329 else
330 JOM(8, "SAA register 0x%02X changed "
331 "from 0x%02X to 0x%02X\n", reg, itwas, isnow);
332 }
333 if (resubmit)
334 easycap_video_submit_urbs(peasycap);
335 return 0;
336}
337/*****************************************************************************/
338/*--------------------------------------------------------------------------*/
339/*
340 * THE ALGORITHM FOR RESPONDING TO THE VIDIO_S_FMT IOCTL REQUIRES
341 * A VALID VALUE OF peasycap->standard_offset, OTHERWISE -EBUSY IS RETURNED.
342 *
343 * PROVIDED THE ARGUMENT try IS false AND THERE IS NO PREMATURE ERROR RETURN
344 * THIS ROUTINE UPDATES THE FOLLOWING:
345 * peasycap->format_offset
346 * peasycap->inputset[peasycap->input].format_offset
347 * peasycap->pixelformat
348 * peasycap->height
349 * peasycap->width
350 * peasycap->bytesperpixel
351 * peasycap->byteswaporder
352 * peasycap->decimatepixel
353 * peasycap->frame_buffer_used
354 * peasycap->videofieldamount
355 * peasycap->offerfields
356 *
357 * IF SUCCESSFUL THE FUNCTION RETURNS THE OFFSET IN easycap_format[]
358 * IDENTIFYING THE FORMAT WHICH IS TO RETURNED TO THE USER.
359 * ERRORS RETURN A NEGATIVE NUMBER.
360 */
361/*--------------------------------------------------------------------------*/
362int adjust_format(struct easycap *peasycap,
363 u32 width, u32 height, u32 pixelformat, int field, bool try)
364{
365 struct easycap_format *peasycap_format, *peasycap_best_format;
366 u16 mask;
367 struct usb_device *p;
368 int miss, multiplier, best, k;
369 char bf[5], fo[32], *pc;
370 u32 uc;
371 bool resubmit;
372
373 if (!peasycap) {
374 SAY("ERROR: peasycap is NULL\n");
375 return -EFAULT;
376 }
377 if (0 > peasycap->standard_offset) {
378 JOM(8, "%i=peasycap->standard_offset\n", peasycap->standard_offset);
379 return -EBUSY;
380 }
381 p = peasycap->pusb_device;
382 if (!p) {
383 SAM("ERROR: peaycap->pusb_device is NULL\n");
384 return -EFAULT;
385 }
386 pc = &bf[0];
387 uc = pixelformat;
388 memcpy((void *)pc, (void *)(&uc), 4);
389 bf[4] = 0;
390 mask = 0xFF & easycap_standard[peasycap->standard_offset].mask;
391 SAM("sought: %ix%i,%s(0x%08X),%i=field,0x%02X=std mask\n",
392 width, height, pc, pixelformat, field, mask);
393 switch (field) {
394 case V4L2_FIELD_ANY: {
395 strcpy(&fo[0], "V4L2_FIELD_ANY ");
396 break;
397 }
398 case V4L2_FIELD_NONE: {
399 strcpy(&fo[0], "V4L2_FIELD_NONE");
400 break;
401 }
402 case V4L2_FIELD_TOP: {
403 strcpy(&fo[0], "V4L2_FIELD_TOP");
404 break;
405 }
406 case V4L2_FIELD_BOTTOM: {
407 strcpy(&fo[0], "V4L2_FIELD_BOTTOM");
408 break;
409 }
410 case V4L2_FIELD_INTERLACED: {
411 strcpy(&fo[0], "V4L2_FIELD_INTERLACED");
412 break;
413 }
414 case V4L2_FIELD_SEQ_TB: {
415 strcpy(&fo[0], "V4L2_FIELD_SEQ_TB");
416 break;
417 }
418 case V4L2_FIELD_SEQ_BT: {
419 strcpy(&fo[0], "V4L2_FIELD_SEQ_BT");
420 break;
421 }
422 case V4L2_FIELD_ALTERNATE: {
423 strcpy(&fo[0], "V4L2_FIELD_ALTERNATE");
424 break;
425 }
426 case V4L2_FIELD_INTERLACED_TB: {
427 strcpy(&fo[0], "V4L2_FIELD_INTERLACED_TB");
428 break;
429 }
430 case V4L2_FIELD_INTERLACED_BT: {
431 strcpy(&fo[0], "V4L2_FIELD_INTERLACED_BT");
432 break;
433 }
434 default: {
435 strcpy(&fo[0], "V4L2_FIELD_... UNKNOWN ");
436 break;
437 }
438 }
439 SAM("sought: %s\n", &fo[0]);
440 if (V4L2_FIELD_ANY == field) {
441 field = V4L2_FIELD_NONE;
442 SAM("prefer: V4L2_FIELD_NONE=field, was V4L2_FIELD_ANY\n");
443 }
444 peasycap_best_format = NULL;
445 peasycap_format = &easycap_format[0];
446 while (0 != peasycap_format->v4l2_format.fmt.pix.width) {
447 JOM(16, ".> %i %i 0x%08X %ix%i\n",
448 peasycap_format->mask & 0x01,
449 peasycap_format->v4l2_format.fmt.pix.field,
450 peasycap_format->v4l2_format.fmt.pix.pixelformat,
451 peasycap_format->v4l2_format.fmt.pix.width,
452 peasycap_format->v4l2_format.fmt.pix.height);
453
454 if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) &&
455 (peasycap_format->v4l2_format.fmt.pix.field == field) &&
456 (peasycap_format->v4l2_format.fmt.pix.pixelformat == pixelformat) &&
457 (peasycap_format->v4l2_format.fmt.pix.width == width) &&
458 (peasycap_format->v4l2_format.fmt.pix.height == height)) {
459
460 peasycap_best_format = peasycap_format;
461 break;
462 }
463 peasycap_format++;
464 }
465 if (0 == peasycap_format->v4l2_format.fmt.pix.width) {
466 SAM("cannot do: %ix%i with standard mask 0x%02X\n",
467 width, height, mask);
468 peasycap_format = &easycap_format[0];
469 best = -1;
470 while (0 != peasycap_format->v4l2_format.fmt.pix.width) {
471 if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) &&
472 (peasycap_format->v4l2_format.fmt.pix.field == field) &&
473 (peasycap_format->v4l2_format.fmt.pix.pixelformat == pixelformat)) {
474
475 miss = abs(peasycap_format->v4l2_format.fmt.pix.width - width);
476 if ((best > miss) || (best < 0)) {
477 best = miss;
478 peasycap_best_format = peasycap_format;
479 if (!miss)
480 break;
481 }
482 }
483 peasycap_format++;
484 }
485 if (-1 == best) {
486 SAM("cannot do %ix... with standard mask 0x%02X\n",
487 width, mask);
488 SAM("cannot do ...x%i with standard mask 0x%02X\n",
489 height, mask);
490 SAM(" %ix%i unmatched\n", width, height);
491 return peasycap->format_offset;
492 }
493 }
494 if (!peasycap_best_format) {
495 SAM("MISTAKE: peasycap_best_format is NULL");
496 return -EINVAL;
497 }
498 peasycap_format = peasycap_best_format;
499
500/*...........................................................................*/
501 if (try)
502 return peasycap_best_format - easycap_format;
503/*...........................................................................*/
504
505 if (false != try) {
506 SAM("MISTAKE: true==try where is should be false\n");
507 return -EINVAL;
508 }
509 SAM("actioning: %ix%i %s\n",
510 peasycap_format->v4l2_format.fmt.pix.width,
511 peasycap_format->v4l2_format.fmt.pix.height,
512 &peasycap_format->name[0]);
513 peasycap->height = peasycap_format->v4l2_format.fmt.pix.height;
514 peasycap->width = peasycap_format->v4l2_format.fmt.pix.width;
515 peasycap->pixelformat = peasycap_format->v4l2_format.fmt.pix.pixelformat;
516 peasycap->format_offset = peasycap_format - easycap_format;
517
518
519 for (k = 0; k < INPUT_MANY; k++) {
520 if (!peasycap->inputset[k].format_offset_ok) {
521 peasycap->inputset[k].format_offset =
522 peasycap->format_offset;
523 }
524 }
525 if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
526 peasycap->inputset[peasycap->input].format_offset =
527 peasycap->format_offset;
528 peasycap->inputset[peasycap->input].format_offset_ok = 1;
529 } else
530 JOM(8, "%i=peasycap->input\n", peasycap->input);
531
532
533
534 peasycap->bytesperpixel = (0x00E0 & peasycap_format->mask) >> 5 ;
535 if (0x0100 & peasycap_format->mask)
536 peasycap->byteswaporder = true;
537 else
538 peasycap->byteswaporder = false;
539 if (0x0200 & peasycap_format->mask)
540 peasycap->skip = 5;
541 else
542 peasycap->skip = 0;
543 if (0x0800 & peasycap_format->mask)
544 peasycap->decimatepixel = true;
545 else
546 peasycap->decimatepixel = false;
547 if (0x1000 & peasycap_format->mask)
548 peasycap->offerfields = true;
549 else
550 peasycap->offerfields = false;
551 if (peasycap->decimatepixel)
552 multiplier = 2;
553 else
554 multiplier = 1;
555 peasycap->videofieldamount =
556 multiplier * peasycap->width * multiplier * peasycap->height;
557 peasycap->frame_buffer_used =
558 peasycap->bytesperpixel * peasycap->width * peasycap->height;
559 if (peasycap->video_isoc_streaming) {
560 resubmit = true;
561 easycap_video_kill_urbs(peasycap);
562 } else
563 resubmit = false;
564/*---------------------------------------------------------------------------*/
565/*
566 * PAL
567 */
568/*---------------------------------------------------------------------------*/
569 if (0 == (0x01 & peasycap_format->mask)) {
570 if (((720 == peasycap_format->v4l2_format.fmt.pix.width) &&
571 (576 == peasycap_format->v4l2_format.fmt.pix.height)) ||
572 ((360 == peasycap_format->v4l2_format.fmt.pix.width) &&
573 (288 == peasycap_format->v4l2_format.fmt.pix.height))) {
574 if (set_resolution(p, 0x0000, 0x0001, 0x05A0, 0x0121)) {
575 SAM("ERROR: set_resolution() failed\n");
576 return -EINVAL;
577 }
578 } else if ((704 == peasycap_format->v4l2_format.fmt.pix.width) &&
579 (576 == peasycap_format->v4l2_format.fmt.pix.height)) {
580 if (set_resolution(p, 0x0004, 0x0001, 0x0584, 0x0121)) {
581 SAM("ERROR: set_resolution() failed\n");
582 return -EINVAL;
583 }
584 } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) &&
585 (480 == peasycap_format->v4l2_format.fmt.pix.height)) ||
586 ((320 == peasycap_format->v4l2_format.fmt.pix.width) &&
587 (240 == peasycap_format->v4l2_format.fmt.pix.height))) {
588 if (set_resolution(p, 0x0014, 0x0020, 0x0514, 0x0110)) {
589 SAM("ERROR: set_resolution() failed\n");
590 return -EINVAL;
591 }
592 } else {
593 SAM("MISTAKE: bad format, cannot set resolution\n");
594 return -EINVAL;
595 }
596/*---------------------------------------------------------------------------*/
597/*
598 * NTSC
599 */
600/*---------------------------------------------------------------------------*/
601 } else {
602 if (((720 == peasycap_format->v4l2_format.fmt.pix.width) &&
603 (480 == peasycap_format->v4l2_format.fmt.pix.height)) ||
604 ((360 == peasycap_format->v4l2_format.fmt.pix.width) &&
605 (240 == peasycap_format->v4l2_format.fmt.pix.height))) {
606 if (set_resolution(p, 0x0000, 0x0003, 0x05A0, 0x00F3)) {
607 SAM("ERROR: set_resolution() failed\n");
608 return -EINVAL;
609 }
610 } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) &&
611 (480 == peasycap_format->v4l2_format.fmt.pix.height)) ||
612 ((320 == peasycap_format->v4l2_format.fmt.pix.width) &&
613 (240 == peasycap_format->v4l2_format.fmt.pix.height))) {
614 if (set_resolution(p, 0x0014, 0x0003, 0x0514, 0x00F3)) {
615 SAM("ERROR: set_resolution() failed\n");
616 return -EINVAL;
617 }
618 } else {
619 SAM("MISTAKE: bad format, cannot set resolution\n");
620 return -EINVAL;
621 }
622 }
623/*---------------------------------------------------------------------------*/
624 if (resubmit)
625 easycap_video_submit_urbs(peasycap);
626
627 return peasycap_best_format - easycap_format;
628}
629/*****************************************************************************/
630int adjust_brightness(struct easycap *peasycap, int value)
631{
632 unsigned int mood;
633 int i1, k;
634
635 if (!peasycap) {
636 SAY("ERROR: peasycap is NULL\n");
637 return -EFAULT;
638 }
639 if (!peasycap->pusb_device) {
640 SAM("ERROR: peasycap->pusb_device is NULL\n");
641 return -EFAULT;
642 }
643 i1 = 0;
644 while (0xFFFFFFFF != easycap_control[i1].id) {
645 if (V4L2_CID_BRIGHTNESS == easycap_control[i1].id) {
646 if ((easycap_control[i1].minimum > value) ||
647 (easycap_control[i1].maximum < value))
648 value = easycap_control[i1].default_value;
649
650 if ((easycap_control[i1].minimum <= peasycap->brightness) &&
651 (easycap_control[i1].maximum >= peasycap->brightness)) {
652 if (peasycap->brightness == value) {
653 SAM("unchanged brightness at 0x%02X\n",
654 value);
655 return 0;
656 }
657 }
658 peasycap->brightness = value;
659 for (k = 0; k < INPUT_MANY; k++) {
660 if (!peasycap->inputset[k].brightness_ok)
661 peasycap->inputset[k].brightness =
662 peasycap->brightness;
663 }
664 if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
665 peasycap->inputset[peasycap->input].brightness =
666 peasycap->brightness;
667 peasycap->inputset[peasycap->input].brightness_ok = 1;
668 } else
669 JOM(8, "%i=peasycap->input\n", peasycap->input);
670
671 mood = 0x00FF & (unsigned int)peasycap->brightness;
672 if (write_saa(peasycap->pusb_device, 0x0A, mood)) {
673 SAM("WARNING: failed to adjust brightness "
674 "to 0x%02X\n", mood);
675 return -ENOENT;
676 }
677 SAM("adjusting brightness to 0x%02X\n", mood);
678 return 0;
679 }
680 i1++;
681 }
682 SAM("WARNING: failed to adjust brightness: control not found\n");
683 return -ENOENT;
684}
685/*****************************************************************************/
686int adjust_contrast(struct easycap *peasycap, int value)
687{
688 unsigned int mood;
689 int i1, k;
690
691 if (!peasycap) {
692 SAY("ERROR: peasycap is NULL\n");
693 return -EFAULT;
694 }
695 if (!peasycap->pusb_device) {
696 SAM("ERROR: peasycap->pusb_device is NULL\n");
697 return -EFAULT;
698 }
699 i1 = 0;
700 while (0xFFFFFFFF != easycap_control[i1].id) {
701 if (V4L2_CID_CONTRAST == easycap_control[i1].id) {
702 if ((easycap_control[i1].minimum > value) ||
703 (easycap_control[i1].maximum < value))
704 value = easycap_control[i1].default_value;
705
706
707 if ((easycap_control[i1].minimum <= peasycap->contrast) &&
708 (easycap_control[i1].maximum >= peasycap->contrast)) {
709 if (peasycap->contrast == value) {
710 SAM("unchanged contrast at 0x%02X\n", value);
711 return 0;
712 }
713 }
714 peasycap->contrast = value;
715 for (k = 0; k < INPUT_MANY; k++) {
716 if (!peasycap->inputset[k].contrast_ok)
717 peasycap->inputset[k].contrast = peasycap->contrast;
718 }
719
720 if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
721 peasycap->inputset[peasycap->input].contrast =
722 peasycap->contrast;
723 peasycap->inputset[peasycap->input].contrast_ok = 1;
724 } else
725 JOM(8, "%i=peasycap->input\n", peasycap->input);
726
727 mood = 0x00FF & (unsigned int) (peasycap->contrast - 128);
728 if (write_saa(peasycap->pusb_device, 0x0B, mood)) {
729 SAM("WARNING: failed to adjust contrast to "
730 "0x%02X\n", mood);
731 return -ENOENT;
732 }
733 SAM("adjusting contrast to 0x%02X\n", mood);
734 return 0;
735 }
736 i1++;
737 }
738 SAM("WARNING: failed to adjust contrast: control not found\n");
739 return -ENOENT;
740}
741/*****************************************************************************/
742int adjust_saturation(struct easycap *peasycap, int value)
743{
744 unsigned int mood;
745 int i1, k;
746
747 if (!peasycap) {
748 SAY("ERROR: peasycap is NULL\n");
749 return -EFAULT;
750 }
751 if (!peasycap->pusb_device) {
752 SAM("ERROR: peasycap->pusb_device is NULL\n");
753 return -EFAULT;
754 }
755 i1 = 0;
756 while (0xFFFFFFFF != easycap_control[i1].id) {
757 if (V4L2_CID_SATURATION == easycap_control[i1].id) {
758 if ((easycap_control[i1].minimum > value) ||
759 (easycap_control[i1].maximum < value))
760 value = easycap_control[i1].default_value;
761
762
763 if ((easycap_control[i1].minimum <= peasycap->saturation) &&
764 (easycap_control[i1].maximum >= peasycap->saturation)) {
765 if (peasycap->saturation == value) {
766 SAM("unchanged saturation at 0x%02X\n",
767 value);
768 return 0;
769 }
770 }
771 peasycap->saturation = value;
772 for (k = 0; k < INPUT_MANY; k++) {
773 if (!peasycap->inputset[k].saturation_ok)
774 peasycap->inputset[k].saturation =
775 peasycap->saturation;
776 }
777 if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) {
778 peasycap->inputset[peasycap->input].saturation =
779 peasycap->saturation;
780 peasycap->inputset[peasycap->input].saturation_ok = 1;
781 } else
782 JOM(8, "%i=peasycap->input\n", peasycap->input);
783 mood = 0x00FF & (unsigned int) (peasycap->saturation - 128);
784 if (write_saa(peasycap->pusb_device, 0x0C, mood)) {
785 SAM("WARNING: failed to adjust saturation to "
786 "0x%02X\n", mood);
787 return -ENOENT;
788 }
789 SAM("adjusting saturation to 0x%02X\n", mood);
790 return 0;
791 break;
792 }
793 i1++;
794 }
795 SAM("WARNING: failed to adjust saturation: control not found\n");
796 return -ENOENT;
797}
798/*****************************************************************************/
799int adjust_hue(struct easycap *peasycap, int value)
800{
801 unsigned int mood;
802 int i1, i2, k;
803
804 if (!peasycap) {
805 SAY("ERROR: peasycap is NULL\n");
806 return -EFAULT;
807 }
808 if (!peasycap->pusb_device) {
809 SAM("ERROR: peasycap->pusb_device is NULL\n");
810 return -EFAULT;
811 }
812 i1 = 0;
813 while (0xFFFFFFFF != easycap_control[i1].id) {
814 if (V4L2_CID_HUE == easycap_control[i1].id) {
815 if ((easycap_control[i1].minimum > value) ||
816 (easycap_control[i1].maximum < value))
817 value = easycap_control[i1].default_value;
818
819 if ((easycap_control[i1].minimum <= peasycap->hue) &&
820 (easycap_control[i1].maximum >= peasycap->hue)) {
821 if (peasycap->hue == value) {
822 SAM("unchanged hue at 0x%02X\n", value);
823 return 0;
824 }
825 }
826 peasycap->hue = value;
827 for (k = 0; k < INPUT_MANY; k++) {
828 if (!peasycap->inputset[k].hue_ok)
829 peasycap->inputset[k].hue = peasycap->hue;
830 }
831 if (0 <= peasycap->input && INPUT_MANY > peasycap->input) {
832 peasycap->inputset[peasycap->input].hue = peasycap->hue;
833 peasycap->inputset[peasycap->input].hue_ok = 1;
834 } else
835 JOM(8, "%i=peasycap->input\n", peasycap->input);
836 i2 = peasycap->hue - 128;
837 mood = 0x00FF & ((int) i2);
838 if (write_saa(peasycap->pusb_device, 0x0D, mood)) {
839 SAM("WARNING: failed to adjust hue to 0x%02X\n", mood);
840 return -ENOENT;
841 }
842 SAM("adjusting hue to 0x%02X\n", mood);
843 return 0;
844 break;
845 }
846 i1++;
847 }
848 SAM("WARNING: failed to adjust hue: control not found\n");
849 return -ENOENT;
850}
851/*****************************************************************************/
852static int adjust_volume(struct easycap *peasycap, int value)
853{
854 s8 mood;
855 int i1;
856
857 if (!peasycap) {
858 SAY("ERROR: peasycap is NULL\n");
859 return -EFAULT;
860 }
861 if (!peasycap->pusb_device) {
862 SAM("ERROR: peasycap->pusb_device is NULL\n");
863 return -EFAULT;
864 }
865 i1 = 0;
866 while (0xFFFFFFFF != easycap_control[i1].id) {
867 if (V4L2_CID_AUDIO_VOLUME == easycap_control[i1].id) {
868 if ((easycap_control[i1].minimum > value) ||
869 (easycap_control[i1].maximum < value))
870 value = easycap_control[i1].default_value;
871
872 if ((easycap_control[i1].minimum <= peasycap->volume) &&
873 (easycap_control[i1].maximum >= peasycap->volume)) {
874 if (peasycap->volume == value) {
875 SAM("unchanged volume at 0x%02X\n", value);
876 return 0;
877 }
878 }
879 peasycap->volume = value;
880 mood = (16 > peasycap->volume) ? 16 :
881 ((31 < peasycap->volume) ? 31 :
882 (s8) peasycap->volume);
883 if (!easycap_audio_gainset(peasycap->pusb_device, mood)) {
884 SAM("WARNING: failed to adjust volume to "
885 "0x%2X\n", mood);
886 return -ENOENT;
887 }
888 SAM("adjusting volume to 0x%02X\n", mood);
889 return 0;
890 }
891 i1++;
892 }
893 SAM("WARNING: failed to adjust volume: control not found\n");
894 return -ENOENT;
895}
896/*****************************************************************************/
897/*---------------------------------------------------------------------------*/
898/*
899 * AN ALTERNATIVE METHOD OF MUTING MIGHT SEEM TO BE:
900 * usb_set_interface(peasycap->pusb_device,
901 * peasycap->audio_interface,
902 * peasycap->audio_altsetting_off);
903 * HOWEVER, AFTER THIS COMMAND IS ISSUED ALL SUBSEQUENT URBS RECEIVE STATUS
904 * -ESHUTDOWN. THE HANDLER ROUTINE easyxxx_complete() DECLINES TO RESUBMIT
905 * THE URB AND THE PIPELINE COLLAPSES IRRETRIEVABLY. BEWARE.
906 */
907/*---------------------------------------------------------------------------*/
908static int adjust_mute(struct easycap *peasycap, int value)
909{
910 int i1;
911
912 if (!peasycap) {
913 SAY("ERROR: peasycap is NULL\n");
914 return -EFAULT;
915 }
916 if (!peasycap->pusb_device) {
917 SAM("ERROR: peasycap->pusb_device is NULL\n");
918 return -EFAULT;
919 }
920 i1 = 0;
921 while (0xFFFFFFFF != easycap_control[i1].id) {
922 if (V4L2_CID_AUDIO_MUTE == easycap_control[i1].id) {
923 peasycap->mute = value;
924 switch (peasycap->mute) {
925 case 1: {
926 peasycap->audio_idle = 1;
927 SAM("adjusting mute: %i=peasycap->audio_idle\n",
928 peasycap->audio_idle);
929 return 0;
930 }
931 default: {
932 peasycap->audio_idle = 0;
933 SAM("adjusting mute: %i=peasycap->audio_idle\n",
934 peasycap->audio_idle);
935 return 0;
936 }
937 }
938 break;
939 }
940 i1++;
941 }
942 SAM("WARNING: failed to adjust mute: control not found\n");
943 return -ENOENT;
944}
945/*---------------------------------------------------------------------------*/
946long easycap_unlocked_ioctl(struct file *file,
947 unsigned int cmd, unsigned long arg)
948{
949 struct easycap *peasycap;
950 struct usb_device *p;
951 int kd;
952
953 if (!file) {
954 SAY("ERROR: file is NULL\n");
955 return -ERESTARTSYS;
956 }
957 peasycap = file->private_data;
958 if (!peasycap) {
959 SAY("ERROR: peasycap is NULL\n");
960 return -1;
961 }
962 p = peasycap->pusb_device;
963 if (!p) {
964 SAM("ERROR: peasycap->pusb_device is NULL\n");
965 return -EFAULT;
966 }
967 kd = easycap_isdongle(peasycap);
968 if (0 <= kd && DONGLE_MANY > kd) {
969 if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) {
970 SAY("ERROR: cannot lock "
971 "easycapdc60_dongle[%i].mutex_video\n", kd);
972 return -ERESTARTSYS;
973 }
974 JOM(4, "locked easycapdc60_dongle[%i].mutex_video\n", kd);
975/*---------------------------------------------------------------------------*/
976/*
977 * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap,
978 * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL.
979 * IF NECESSARY, BAIL OUT.
980 */
981/*---------------------------------------------------------------------------*/
982 if (kd != easycap_isdongle(peasycap))
983 return -ERESTARTSYS;
984 if (!file) {
985 SAY("ERROR: file is NULL\n");
986 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
987 return -ERESTARTSYS;
988 }
989 peasycap = file->private_data;
990 if (!peasycap) {
991 SAY("ERROR: peasycap is NULL\n");
992 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
993 return -ERESTARTSYS;
994 }
995 if (!peasycap->pusb_device) {
996 SAM("ERROR: peasycap->pusb_device is NULL\n");
997 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
998 return -ERESTARTSYS;
999 }
1000 } else {
1001/*---------------------------------------------------------------------------*/
1002/*
1003 * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE
1004 * ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED. BAIL OUT.
1005 */
1006/*---------------------------------------------------------------------------*/
1007 return -ERESTARTSYS;
1008 }
1009/*---------------------------------------------------------------------------*/
1010 switch (cmd) {
1011 case VIDIOC_QUERYCAP: {
1012 struct v4l2_capability v4l2_capability;
1013 char version[16], *p1, *p2;
1014 int i, rc, k[3];
1015 long lng;
1016
1017 JOM(8, "VIDIOC_QUERYCAP\n");
1018
1019 if (16 <= strlen(EASYCAP_DRIVER_VERSION)) {
1020 SAM("ERROR: bad driver version string\n");
1021 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1022 return -EINVAL;
1023 }
1024 strcpy(&version[0], EASYCAP_DRIVER_VERSION);
1025 for (i = 0; i < 3; i++)
1026 k[i] = 0;
1027 p2 = &version[0];
1028 i = 0;
1029 while (*p2) {
1030 p1 = p2;
1031 while (*p2 && ('.' != *p2))
1032 p2++;
1033 if (*p2)
1034 *p2++ = 0;
1035 if (3 > i) {
1036 rc = (int) strict_strtol(p1, 10, &lng);
1037 if (rc) {
1038 SAM("ERROR: %i=strict_strtol(%s,.,,)\n",
1039 rc, p1);
1040 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1041 return -EINVAL;
1042 }
1043 k[i] = (int)lng;
1044 }
1045 i++;
1046 }
1047
1048 memset(&v4l2_capability, 0, sizeof(struct v4l2_capability));
1049 strlcpy(&v4l2_capability.driver[0],
1050 "easycap", sizeof(v4l2_capability.driver));
1051
1052 v4l2_capability.capabilities = V4L2_CAP_VIDEO_CAPTURE |
1053 V4L2_CAP_STREAMING |
1054 V4L2_CAP_AUDIO |
1055 V4L2_CAP_READWRITE;
1056
1057 v4l2_capability.version = KERNEL_VERSION(k[0], k[1], k[2]);
1058 JOM(8, "v4l2_capability.version=(%i,%i,%i)\n", k[0], k[1], k[2]);
1059
1060 strlcpy(&v4l2_capability.card[0],
1061 "EasyCAP DC60", sizeof(v4l2_capability.card));
1062
1063 if (usb_make_path(peasycap->pusb_device,
1064 &v4l2_capability.bus_info[0],
1065 sizeof(v4l2_capability.bus_info)) < 0) {
1066
1067 strlcpy(&v4l2_capability.bus_info[0], "EasyCAP bus_info",
1068 sizeof(v4l2_capability.bus_info));
1069 JOM(8, "%s=v4l2_capability.bus_info\n",
1070 &v4l2_capability.bus_info[0]);
1071 }
1072 if (copy_to_user((void __user *)arg, &v4l2_capability,
1073 sizeof(struct v4l2_capability))) {
1074 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1075 return -EFAULT;
1076 }
1077 break;
1078 }
1079/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1080 case VIDIOC_ENUMINPUT: {
1081 struct v4l2_input v4l2_input;
1082 u32 index;
1083
1084 JOM(8, "VIDIOC_ENUMINPUT\n");
1085
1086 if (copy_from_user(&v4l2_input, (void __user *)arg,
1087 sizeof(struct v4l2_input))) {
1088 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1089 return -EFAULT;
1090 }
1091
1092 index = v4l2_input.index;
1093 memset(&v4l2_input, 0, sizeof(struct v4l2_input));
1094
1095 switch (index) {
1096 case 0: {
1097 v4l2_input.index = index;
1098 strcpy(&v4l2_input.name[0], "CVBS0");
1099 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
1100 v4l2_input.audioset = 0x01;
1101 v4l2_input.tuner = 0;
1102 v4l2_input.std = V4L2_STD_PAL |
1103 V4L2_STD_SECAM |
1104 V4L2_STD_NTSC ;
1105 v4l2_input.status = 0;
1106 JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1107 break;
1108 }
1109 case 1: {
1110 v4l2_input.index = index;
1111 strcpy(&v4l2_input.name[0], "CVBS1");
1112 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
1113 v4l2_input.audioset = 0x01;
1114 v4l2_input.tuner = 0;
1115 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM |
1116 V4L2_STD_NTSC;
1117 v4l2_input.status = 0;
1118 JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1119 break;
1120 }
1121 case 2: {
1122 v4l2_input.index = index;
1123 strcpy(&v4l2_input.name[0], "CVBS2");
1124 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
1125 v4l2_input.audioset = 0x01;
1126 v4l2_input.tuner = 0;
1127 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM |
1128 V4L2_STD_NTSC ;
1129 v4l2_input.status = 0;
1130 JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1131 break;
1132 }
1133 case 3: {
1134 v4l2_input.index = index;
1135 strcpy(&v4l2_input.name[0], "CVBS3");
1136 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
1137 v4l2_input.audioset = 0x01;
1138 v4l2_input.tuner = 0;
1139 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM |
1140 V4L2_STD_NTSC ;
1141 v4l2_input.status = 0;
1142 JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1143 break;
1144 }
1145 case 4: {
1146 v4l2_input.index = index;
1147 strcpy(&v4l2_input.name[0], "CVBS4");
1148 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
1149 v4l2_input.audioset = 0x01;
1150 v4l2_input.tuner = 0;
1151 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM |
1152 V4L2_STD_NTSC ;
1153 v4l2_input.status = 0;
1154 JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1155 break;
1156 }
1157 case 5: {
1158 v4l2_input.index = index;
1159 strcpy(&v4l2_input.name[0], "S-VIDEO");
1160 v4l2_input.type = V4L2_INPUT_TYPE_CAMERA;
1161 v4l2_input.audioset = 0x01;
1162 v4l2_input.tuner = 0;
1163 v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM |
1164 V4L2_STD_NTSC ;
1165 v4l2_input.status = 0;
1166 JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]);
1167 break;
1168 }
1169 default: {
1170 JOM(8, "%i=index: exhausts inputs\n", index);
1171 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1172 return -EINVAL;
1173 }
1174 }
1175
1176 if (copy_to_user((void __user *)arg, &v4l2_input,
1177 sizeof(struct v4l2_input))) {
1178 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1179 return -EFAULT;
1180 }
1181 break;
1182 }
1183/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1184 case VIDIOC_G_INPUT: {
1185 u32 index;
1186
1187 JOM(8, "VIDIOC_G_INPUT\n");
1188 index = (u32)peasycap->input;
1189 JOM(8, "user is told: %i\n", index);
1190 if (copy_to_user((void __user *)arg, &index, sizeof(u32))) {
1191 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1192 return -EFAULT;
1193 }
1194 break;
1195 }
1196/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1197 case VIDIOC_S_INPUT:
1198 {
1199 u32 index;
1200 int rc;
1201
1202 JOM(8, "VIDIOC_S_INPUT\n");
1203
1204 if (0 != copy_from_user(&index, (void __user *)arg, sizeof(u32))) {
1205 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1206 return -EFAULT;
1207 }
1208
1209 JOM(8, "user requests input %i\n", index);
1210
1211 if ((int)index == peasycap->input) {
1212 SAM("requested input already in effect\n");
1213 break;
1214 }
1215
1216 if ((0 > index) || (INPUT_MANY <= index)) {
1217 JOM(8, "ERROR: bad requested input: %i\n", index);
1218 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1219 return -EINVAL;
1220 }
1221
1222 rc = easycap_newinput(peasycap, (int)index);
1223 if (0 == rc) {
1224 JOM(8, "newinput(.,%i) OK\n", (int)index);
1225 } else {
1226 SAM("ERROR: newinput(.,%i) returned %i\n", (int)index, rc);
1227 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1228 return -EFAULT;
1229 }
1230 break;
1231 }
1232/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1233 case VIDIOC_ENUMAUDIO: {
1234 JOM(8, "VIDIOC_ENUMAUDIO\n");
1235 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1236 return -EINVAL;
1237 }
1238/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1239 case VIDIOC_ENUMAUDOUT: {
1240 struct v4l2_audioout v4l2_audioout;
1241
1242 JOM(8, "VIDIOC_ENUMAUDOUT\n");
1243
1244 if (copy_from_user(&v4l2_audioout, (void __user *)arg,
1245 sizeof(struct v4l2_audioout))) {
1246 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1247 return -EFAULT;
1248 }
1249
1250 if (0 != v4l2_audioout.index) {
1251 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1252 return -EINVAL;
1253 }
1254 memset(&v4l2_audioout, 0, sizeof(struct v4l2_audioout));
1255 v4l2_audioout.index = 0;
1256 strcpy(&v4l2_audioout.name[0], "Soundtrack");
1257
1258 if (copy_to_user((void __user *)arg, &v4l2_audioout,
1259 sizeof(struct v4l2_audioout))) {
1260 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1261 return -EFAULT;
1262 }
1263 break;
1264 }
1265/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1266 case VIDIOC_QUERYCTRL: {
1267 int i1;
1268 struct v4l2_queryctrl v4l2_queryctrl;
1269
1270 JOM(8, "VIDIOC_QUERYCTRL\n");
1271
1272 if (0 != copy_from_user(&v4l2_queryctrl, (void __user *)arg,
1273 sizeof(struct v4l2_queryctrl))) {
1274 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1275 return -EFAULT;
1276 }
1277
1278 i1 = 0;
1279 while (0xFFFFFFFF != easycap_control[i1].id) {
1280 if (easycap_control[i1].id == v4l2_queryctrl.id) {
1281 JOM(8, "VIDIOC_QUERYCTRL %s=easycap_control[%i]"
1282 ".name\n", &easycap_control[i1].name[0], i1);
1283 memcpy(&v4l2_queryctrl, &easycap_control[i1],
1284 sizeof(struct v4l2_queryctrl));
1285 break;
1286 }
1287 i1++;
1288 }
1289 if (0xFFFFFFFF == easycap_control[i1].id) {
1290 JOM(8, "%i=index: exhausts controls\n", i1);
1291 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1292 return -EINVAL;
1293 }
1294 if (copy_to_user((void __user *)arg, &v4l2_queryctrl,
1295 sizeof(struct v4l2_queryctrl))) {
1296 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1297 return -EFAULT;
1298 }
1299 break;
1300 }
1301/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1302 case VIDIOC_QUERYMENU: {
1303 JOM(8, "VIDIOC_QUERYMENU unsupported\n");
1304 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1305 return -EINVAL;
1306 }
1307/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1308 case VIDIOC_G_CTRL: {
1309 struct v4l2_control *pv4l2_control;
1310
1311 JOM(8, "VIDIOC_G_CTRL\n");
1312 pv4l2_control = memdup_user((void __user *)arg,
1313 sizeof(struct v4l2_control));
1314 if (IS_ERR(pv4l2_control)) {
1315 SAM("ERROR: copy from user failed\n");
1316 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1317 return PTR_ERR(pv4l2_control);
1318 }
1319
1320 switch (pv4l2_control->id) {
1321 case V4L2_CID_BRIGHTNESS: {
1322 pv4l2_control->value = peasycap->brightness;
1323 JOM(8, "user enquires brightness: %i\n", pv4l2_control->value);
1324 break;
1325 }
1326 case V4L2_CID_CONTRAST: {
1327 pv4l2_control->value = peasycap->contrast;
1328 JOM(8, "user enquires contrast: %i\n", pv4l2_control->value);
1329 break;
1330 }
1331 case V4L2_CID_SATURATION: {
1332 pv4l2_control->value = peasycap->saturation;
1333 JOM(8, "user enquires saturation: %i\n", pv4l2_control->value);
1334 break;
1335 }
1336 case V4L2_CID_HUE: {
1337 pv4l2_control->value = peasycap->hue;
1338 JOM(8, "user enquires hue: %i\n", pv4l2_control->value);
1339 break;
1340 }
1341 case V4L2_CID_AUDIO_VOLUME: {
1342 pv4l2_control->value = peasycap->volume;
1343 JOM(8, "user enquires volume: %i\n", pv4l2_control->value);
1344 break;
1345 }
1346 case V4L2_CID_AUDIO_MUTE: {
1347 if (1 == peasycap->mute)
1348 pv4l2_control->value = true;
1349 else
1350 pv4l2_control->value = false;
1351 JOM(8, "user enquires mute: %i\n", pv4l2_control->value);
1352 break;
1353 }
1354 default: {
1355 SAM("ERROR: unknown V4L2 control: 0x%08X=id\n",
1356 pv4l2_control->id);
1357 kfree(pv4l2_control);
1358 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1359 return -EINVAL;
1360 }
1361 }
1362 if (copy_to_user((void __user *)arg, pv4l2_control,
1363 sizeof(struct v4l2_control))) {
1364 kfree(pv4l2_control);
1365 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1366 return -EFAULT;
1367 }
1368 kfree(pv4l2_control);
1369 break;
1370 }
1371/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1372 case VIDIOC_S_CTRL: {
1373 struct v4l2_control v4l2_control;
1374
1375 JOM(8, "VIDIOC_S_CTRL\n");
1376
1377 if (0 != copy_from_user(&v4l2_control, (void __user *)arg,
1378 sizeof(struct v4l2_control))) {
1379 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1380 return -EFAULT;
1381 }
1382
1383 switch (v4l2_control.id) {
1384 case V4L2_CID_BRIGHTNESS: {
1385 JOM(8, "user requests brightness %i\n", v4l2_control.value);
1386 if (0 != adjust_brightness(peasycap, v4l2_control.value))
1387 ;
1388 break;
1389 }
1390 case V4L2_CID_CONTRAST: {
1391 JOM(8, "user requests contrast %i\n", v4l2_control.value);
1392 if (0 != adjust_contrast(peasycap, v4l2_control.value))
1393 ;
1394 break;
1395 }
1396 case V4L2_CID_SATURATION: {
1397 JOM(8, "user requests saturation %i\n", v4l2_control.value);
1398 if (0 != adjust_saturation(peasycap, v4l2_control.value))
1399 ;
1400 break;
1401 }
1402 case V4L2_CID_HUE: {
1403 JOM(8, "user requests hue %i\n", v4l2_control.value);
1404 if (0 != adjust_hue(peasycap, v4l2_control.value))
1405 ;
1406 break;
1407 }
1408 case V4L2_CID_AUDIO_VOLUME: {
1409 JOM(8, "user requests volume %i\n", v4l2_control.value);
1410 if (0 != adjust_volume(peasycap, v4l2_control.value))
1411 ;
1412 break;
1413 }
1414 case V4L2_CID_AUDIO_MUTE: {
1415 int mute;
1416
1417 JOM(8, "user requests mute %i\n", v4l2_control.value);
1418 if (v4l2_control.value)
1419 mute = 1;
1420 else
1421 mute = 0;
1422
1423 if (0 != adjust_mute(peasycap, mute))
1424 SAM("WARNING: failed to adjust mute to %i\n", mute);
1425 break;
1426 }
1427 default: {
1428 SAM("ERROR: unknown V4L2 control: 0x%08X=id\n",
1429 v4l2_control.id);
1430 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1431 return -EINVAL;
1432 }
1433 }
1434 break;
1435 }
1436/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1437 case VIDIOC_S_EXT_CTRLS: {
1438 JOM(8, "VIDIOC_S_EXT_CTRLS unsupported\n");
1439 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1440 return -EINVAL;
1441 }
1442/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1443 case VIDIOC_ENUM_FMT: {
1444 u32 index;
1445 struct v4l2_fmtdesc v4l2_fmtdesc;
1446
1447 JOM(8, "VIDIOC_ENUM_FMT\n");
1448
1449 if (0 != copy_from_user(&v4l2_fmtdesc, (void __user *)arg,
1450 sizeof(struct v4l2_fmtdesc))) {
1451 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1452 return -EFAULT;
1453 }
1454
1455 index = v4l2_fmtdesc.index;
1456 memset(&v4l2_fmtdesc, 0, sizeof(struct v4l2_fmtdesc));
1457
1458 v4l2_fmtdesc.index = index;
1459 v4l2_fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1460
1461 switch (index) {
1462 case 0: {
1463 v4l2_fmtdesc.flags = 0;
1464 strcpy(&v4l2_fmtdesc.description[0], "uyvy");
1465 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_UYVY;
1466 JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1467 break;
1468 }
1469 case 1: {
1470 v4l2_fmtdesc.flags = 0;
1471 strcpy(&v4l2_fmtdesc.description[0], "yuy2");
1472 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_YUYV;
1473 JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1474 break;
1475 }
1476 case 2: {
1477 v4l2_fmtdesc.flags = 0;
1478 strcpy(&v4l2_fmtdesc.description[0], "rgb24");
1479 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB24;
1480 JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1481 break;
1482 }
1483 case 3: {
1484 v4l2_fmtdesc.flags = 0;
1485 strcpy(&v4l2_fmtdesc.description[0], "rgb32");
1486 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB32;
1487 JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1488 break;
1489 }
1490 case 4: {
1491 v4l2_fmtdesc.flags = 0;
1492 strcpy(&v4l2_fmtdesc.description[0], "bgr24");
1493 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR24;
1494 JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1495 break;
1496 }
1497 case 5: {
1498 v4l2_fmtdesc.flags = 0;
1499 strcpy(&v4l2_fmtdesc.description[0], "bgr32");
1500 v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR32;
1501 JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]);
1502 break;
1503 }
1504 default: {
1505 JOM(8, "%i=index: exhausts formats\n", index);
1506 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1507 return -EINVAL;
1508 }
1509 }
1510 if (copy_to_user((void __user *)arg, &v4l2_fmtdesc,
1511 sizeof(struct v4l2_fmtdesc))) {
1512 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1513 return -EFAULT;
1514 }
1515 break;
1516 }
1517/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1518/*
1519 * THE RESPONSE TO VIDIOC_ENUM_FRAMESIZES MUST BE CONDITIONED ON THE
1520 * THE CURRENT STANDARD, BECAUSE THAT IS WHAT gstreamer EXPECTS. BEWARE.
1521 */
1522/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1523 case VIDIOC_ENUM_FRAMESIZES: {
1524 u32 index;
1525 struct v4l2_frmsizeenum v4l2_frmsizeenum;
1526
1527 JOM(8, "VIDIOC_ENUM_FRAMESIZES\n");
1528
1529 if (0 != copy_from_user(&v4l2_frmsizeenum, (void __user *)arg,
1530 sizeof(struct v4l2_frmsizeenum))) {
1531 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1532 return -EFAULT;
1533 }
1534
1535 index = v4l2_frmsizeenum.index;
1536
1537 v4l2_frmsizeenum.type = (u32) V4L2_FRMSIZE_TYPE_DISCRETE;
1538
1539 if (peasycap->ntsc) {
1540 switch (index) {
1541 case 0: {
1542 v4l2_frmsizeenum.discrete.width = 640;
1543 v4l2_frmsizeenum.discrete.height = 480;
1544 JOM(8, "%i=index: %ix%i\n", index,
1545 (int)(v4l2_frmsizeenum.
1546 discrete.width),
1547 (int)(v4l2_frmsizeenum.
1548 discrete.height));
1549 break;
1550 }
1551 case 1: {
1552 v4l2_frmsizeenum.discrete.width = 320;
1553 v4l2_frmsizeenum.discrete.height = 240;
1554 JOM(8, "%i=index: %ix%i\n", index,
1555 (int)(v4l2_frmsizeenum.
1556 discrete.width),
1557 (int)(v4l2_frmsizeenum.
1558 discrete.height));
1559 break;
1560 }
1561 case 2: {
1562 v4l2_frmsizeenum.discrete.width = 720;
1563 v4l2_frmsizeenum.discrete.height = 480;
1564 JOM(8, "%i=index: %ix%i\n", index,
1565 (int)(v4l2_frmsizeenum.
1566 discrete.width),
1567 (int)(v4l2_frmsizeenum.
1568 discrete.height));
1569 break;
1570 }
1571 case 3: {
1572 v4l2_frmsizeenum.discrete.width = 360;
1573 v4l2_frmsizeenum.discrete.height = 240;
1574 JOM(8, "%i=index: %ix%i\n", index,
1575 (int)(v4l2_frmsizeenum.
1576 discrete.width),
1577 (int)(v4l2_frmsizeenum.
1578 discrete.height));
1579 break;
1580 }
1581 default: {
1582 JOM(8, "%i=index: exhausts framesizes\n", index);
1583 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1584 return -EINVAL;
1585 }
1586 }
1587 } else {
1588 switch (index) {
1589 case 0: {
1590 v4l2_frmsizeenum.discrete.width = 640;
1591 v4l2_frmsizeenum.discrete.height = 480;
1592 JOM(8, "%i=index: %ix%i\n", index,
1593 (int)(v4l2_frmsizeenum.
1594 discrete.width),
1595 (int)(v4l2_frmsizeenum.
1596 discrete.height));
1597 break;
1598 }
1599 case 1: {
1600 v4l2_frmsizeenum.discrete.width = 320;
1601 v4l2_frmsizeenum.discrete.height = 240;
1602 JOM(8, "%i=index: %ix%i\n", index,
1603 (int)(v4l2_frmsizeenum.
1604 discrete.width),
1605 (int)(v4l2_frmsizeenum.
1606 discrete.height));
1607 break;
1608 }
1609 case 2: {
1610 v4l2_frmsizeenum.discrete.width = 704;
1611 v4l2_frmsizeenum.discrete.height = 576;
1612 JOM(8, "%i=index: %ix%i\n", index,
1613 (int)(v4l2_frmsizeenum.
1614 discrete.width),
1615 (int)(v4l2_frmsizeenum.
1616 discrete.height));
1617 break;
1618 }
1619 case 3: {
1620 v4l2_frmsizeenum.discrete.width = 720;
1621 v4l2_frmsizeenum.discrete.height = 576;
1622 JOM(8, "%i=index: %ix%i\n", index,
1623 (int)(v4l2_frmsizeenum.
1624 discrete.width),
1625 (int)(v4l2_frmsizeenum.
1626 discrete.height));
1627 break;
1628 }
1629 case 4: {
1630 v4l2_frmsizeenum.discrete.width = 360;
1631 v4l2_frmsizeenum.discrete.height = 288;
1632 JOM(8, "%i=index: %ix%i\n", index,
1633 (int)(v4l2_frmsizeenum.
1634 discrete.width),
1635 (int)(v4l2_frmsizeenum.
1636 discrete.height));
1637 break;
1638 }
1639 default: {
1640 JOM(8, "%i=index: exhausts framesizes\n", index);
1641 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1642 return -EINVAL;
1643 }
1644 }
1645 }
1646 if (copy_to_user((void __user *)arg, &v4l2_frmsizeenum,
1647 sizeof(struct v4l2_frmsizeenum))) {
1648 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1649 return -EFAULT;
1650 }
1651 break;
1652 }
1653/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1654/*
1655 * THE RESPONSE TO VIDIOC_ENUM_FRAMEINTERVALS MUST BE CONDITIONED ON THE
1656 * THE CURRENT STANDARD, BECAUSE THAT IS WHAT gstreamer EXPECTS. BEWARE.
1657 */
1658/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1659 case VIDIOC_ENUM_FRAMEINTERVALS: {
1660 u32 index;
1661 int denominator;
1662 struct v4l2_frmivalenum v4l2_frmivalenum;
1663
1664 JOM(8, "VIDIOC_ENUM_FRAMEINTERVALS\n");
1665
1666 if (peasycap->fps)
1667 denominator = peasycap->fps;
1668 else {
1669 if (peasycap->ntsc)
1670 denominator = 30;
1671 else
1672 denominator = 25;
1673 }
1674
1675 if (0 != copy_from_user(&v4l2_frmivalenum, (void __user *)arg,
1676 sizeof(struct v4l2_frmivalenum))) {
1677 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1678 return -EFAULT;
1679 }
1680
1681 index = v4l2_frmivalenum.index;
1682
1683 v4l2_frmivalenum.type = (u32) V4L2_FRMIVAL_TYPE_DISCRETE;
1684
1685 switch (index) {
1686 case 0: {
1687 v4l2_frmivalenum.discrete.numerator = 1;
1688 v4l2_frmivalenum.discrete.denominator = denominator;
1689 JOM(8, "%i=index: %i/%i\n", index,
1690 (int)(v4l2_frmivalenum.discrete.numerator),
1691 (int)(v4l2_frmivalenum.discrete.denominator));
1692 break;
1693 }
1694 case 1: {
1695 v4l2_frmivalenum.discrete.numerator = 1;
1696 v4l2_frmivalenum.discrete.denominator = denominator/5;
1697 JOM(8, "%i=index: %i/%i\n", index,
1698 (int)(v4l2_frmivalenum.discrete.numerator),
1699 (int)(v4l2_frmivalenum.discrete.denominator));
1700 break;
1701 }
1702 default: {
1703 JOM(8, "%i=index: exhausts frameintervals\n", index);
1704 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1705 return -EINVAL;
1706 }
1707 }
1708 if (copy_to_user((void __user *)arg, &v4l2_frmivalenum,
1709 sizeof(struct v4l2_frmivalenum))) {
1710 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1711 return -EFAULT;
1712 }
1713 break;
1714 }
1715/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1716 case VIDIOC_G_FMT: {
1717 struct v4l2_format *pv4l2_format;
1718 struct v4l2_pix_format *pv4l2_pix_format;
1719
1720 JOM(8, "VIDIOC_G_FMT\n");
1721 pv4l2_format = kzalloc(sizeof(struct v4l2_format), GFP_KERNEL);
1722 if (!pv4l2_format) {
1723 SAM("ERROR: out of memory\n");
1724 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1725 return -ENOMEM;
1726 }
1727 pv4l2_pix_format = kzalloc(sizeof(struct v4l2_pix_format), GFP_KERNEL);
1728 if (!pv4l2_pix_format) {
1729 SAM("ERROR: out of memory\n");
1730 kfree(pv4l2_format);
1731 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1732 return -ENOMEM;
1733 }
1734 if (0 != copy_from_user(pv4l2_format, (void __user *)arg,
1735 sizeof(struct v4l2_format))) {
1736 kfree(pv4l2_format);
1737 kfree(pv4l2_pix_format);
1738 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1739 return -EFAULT;
1740 }
1741
1742 if (pv4l2_format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1743 kfree(pv4l2_format);
1744 kfree(pv4l2_pix_format);
1745 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1746 return -EINVAL;
1747 }
1748
1749 memset(pv4l2_pix_format, 0, sizeof(struct v4l2_pix_format));
1750 pv4l2_format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1751 memcpy(&pv4l2_format->fmt.pix,
1752 &easycap_format[peasycap->format_offset]
1753 .v4l2_format.fmt.pix, sizeof(struct v4l2_pix_format));
1754 JOM(8, "user is told: %s\n",
1755 &easycap_format[peasycap->format_offset].name[0]);
1756
1757 if (copy_to_user((void __user *)arg, pv4l2_format,
1758 sizeof(struct v4l2_format))) {
1759 kfree(pv4l2_format);
1760 kfree(pv4l2_pix_format);
1761 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1762 return -EFAULT;
1763 }
1764 kfree(pv4l2_format);
1765 kfree(pv4l2_pix_format);
1766 break;
1767 }
1768/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1769 case VIDIOC_TRY_FMT:
1770 case VIDIOC_S_FMT: {
1771 struct v4l2_format v4l2_format;
1772 struct v4l2_pix_format v4l2_pix_format;
1773 bool try;
1774 int best_format;
1775
1776 if (VIDIOC_TRY_FMT == cmd) {
1777 JOM(8, "VIDIOC_TRY_FMT\n");
1778 try = true;
1779 } else {
1780 JOM(8, "VIDIOC_S_FMT\n");
1781 try = false;
1782 }
1783
1784 if (0 != copy_from_user(&v4l2_format, (void __user *)arg,
1785 sizeof(struct v4l2_format))) {
1786 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1787 return -EFAULT;
1788 }
1789
1790 best_format = adjust_format(peasycap,
1791 v4l2_format.fmt.pix.width,
1792 v4l2_format.fmt.pix.height,
1793 v4l2_format.fmt.pix.pixelformat,
1794 v4l2_format.fmt.pix.field,
1795 try);
1796 if (0 > best_format) {
1797 if (-EBUSY == best_format) {
1798 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1799 return -EBUSY;
1800 }
1801 JOM(8, "WARNING: adjust_format() returned %i\n", best_format);
1802 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1803 return -ENOENT;
1804 }
1805/*...........................................................................*/
1806 memset(&v4l2_pix_format, 0, sizeof(struct v4l2_pix_format));
1807 v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1808
1809 memcpy(&(v4l2_format.fmt.pix),
1810 &(easycap_format[best_format].v4l2_format.fmt.pix),
1811 sizeof(v4l2_pix_format));
1812 JOM(8, "user is told: %s\n", &easycap_format[best_format].name[0]);
1813
1814 if (copy_to_user((void __user *)arg, &v4l2_format,
1815 sizeof(struct v4l2_format))) {
1816 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1817 return -EFAULT;
1818 }
1819 break;
1820 }
1821/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1822 case VIDIOC_CROPCAP: {
1823 struct v4l2_cropcap v4l2_cropcap;
1824
1825 JOM(8, "VIDIOC_CROPCAP\n");
1826
1827 if (0 != copy_from_user(&v4l2_cropcap, (void __user *)arg,
1828 sizeof(struct v4l2_cropcap))) {
1829 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1830 return -EFAULT;
1831 }
1832
1833 if (v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1834 JOM(8, "v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
1835
1836 memset(&v4l2_cropcap, 0, sizeof(struct v4l2_cropcap));
1837 v4l2_cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1838 v4l2_cropcap.bounds.left = 0;
1839 v4l2_cropcap.bounds.top = 0;
1840 v4l2_cropcap.bounds.width = peasycap->width;
1841 v4l2_cropcap.bounds.height = peasycap->height;
1842 v4l2_cropcap.defrect.left = 0;
1843 v4l2_cropcap.defrect.top = 0;
1844 v4l2_cropcap.defrect.width = peasycap->width;
1845 v4l2_cropcap.defrect.height = peasycap->height;
1846 v4l2_cropcap.pixelaspect.numerator = 1;
1847 v4l2_cropcap.pixelaspect.denominator = 1;
1848
1849 JOM(8, "user is told: %ix%i\n", peasycap->width, peasycap->height);
1850
1851 if (copy_to_user((void __user *)arg, &v4l2_cropcap,
1852 sizeof(struct v4l2_cropcap))) {
1853 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1854 return -EFAULT;
1855 }
1856 break;
1857 }
1858/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1859 case VIDIOC_G_CROP:
1860 case VIDIOC_S_CROP: {
1861 JOM(8, "VIDIOC_G_CROP|VIDIOC_S_CROP unsupported\n");
1862 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1863 return -EINVAL;
1864 }
1865/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1866 case VIDIOC_QUERYSTD: {
1867 JOM(8, "VIDIOC_QUERYSTD: "
1868 "EasyCAP is incapable of detecting standard\n");
1869 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1870 return -EINVAL;
1871 break;
1872 }
1873 /*-------------------------------------------------------------------*/
1874 /*
1875 * THE MANIPULATIONS INVOLVING last0,last1,last2,last3
1876 * CONSTITUTE A WORKAROUND * FOR WHAT APPEARS TO BE
1877 * A BUG IN 64-BIT mplayer.
1878 * NOT NEEDED, BUT HOPEFULLY HARMLESS, FOR 32-BIT mplayer.
1879 */
1880 /*------------------------------------------------------------------*/
1881 case VIDIOC_ENUMSTD: {
1882 int last0 = -1, last1 = -1, last2 = -1, last3 = -1;
1883 struct v4l2_standard v4l2_standard;
1884 u32 index;
1885 struct easycap_standard const *peasycap_standard;
1886
1887 JOM(8, "VIDIOC_ENUMSTD\n");
1888
1889 if (0 != copy_from_user(&v4l2_standard, (void __user *)arg,
1890 sizeof(struct v4l2_standard))) {
1891 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1892 return -EFAULT;
1893 }
1894 index = v4l2_standard.index;
1895
1896 last3 = last2;
1897 last2 = last1;
1898 last1 = last0;
1899 last0 = index;
1900 if ((index == last3) && (index == last2) &&
1901 (index == last1) && (index == last0)) {
1902 index++;
1903 last3 = last2;
1904 last2 = last1;
1905 last1 = last0;
1906 last0 = index;
1907 }
1908
1909 memset(&v4l2_standard, 0, sizeof(struct v4l2_standard));
1910
1911 peasycap_standard = &easycap_standard[0];
1912 while (0xFFFF != peasycap_standard->mask) {
1913 if ((int)(peasycap_standard - &easycap_standard[0]) == index)
1914 break;
1915 peasycap_standard++;
1916 }
1917 if (0xFFFF == peasycap_standard->mask) {
1918 JOM(8, "%i=index: exhausts standards\n", index);
1919 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1920 return -EINVAL;
1921 }
1922 JOM(8, "%i=index: %s\n", index,
1923 &(peasycap_standard->v4l2_standard.name[0]));
1924 memcpy(&v4l2_standard, &(peasycap_standard->v4l2_standard),
1925 sizeof(struct v4l2_standard));
1926
1927 v4l2_standard.index = index;
1928
1929 if (copy_to_user((void __user *)arg, &v4l2_standard,
1930 sizeof(struct v4l2_standard))) {
1931 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1932 return -EFAULT;
1933 }
1934 break;
1935 }
1936/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1937 case VIDIOC_G_STD: {
1938 v4l2_std_id std_id;
1939 struct easycap_standard const *peasycap_standard;
1940
1941 JOM(8, "VIDIOC_G_STD\n");
1942
1943 if (0 > peasycap->standard_offset) {
1944 JOM(8, "%i=peasycap->standard_offset\n",
1945 peasycap->standard_offset);
1946 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1947 return -EBUSY;
1948 }
1949
1950 if (0 != copy_from_user(&std_id, (void __user *)arg,
1951 sizeof(v4l2_std_id))) {
1952 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1953 return -EFAULT;
1954 }
1955
1956 peasycap_standard = &easycap_standard[peasycap->standard_offset];
1957 std_id = peasycap_standard->v4l2_standard.id;
1958
1959 JOM(8, "user is told: %s\n",
1960 &peasycap_standard->v4l2_standard.name[0]);
1961
1962 if (copy_to_user((void __user *)arg, &std_id,
1963 sizeof(v4l2_std_id))) {
1964 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1965 return -EFAULT;
1966 }
1967 break;
1968 }
1969/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1970 case VIDIOC_S_STD: {
1971 v4l2_std_id std_id;
1972 int rc;
1973
1974 JOM(8, "VIDIOC_S_STD\n");
1975
1976 if (0 != copy_from_user(&std_id, (void __user *)arg,
1977 sizeof(v4l2_std_id))) {
1978 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1979 return -EFAULT;
1980 }
1981
1982 JOM(8, "User requests standard: 0x%08X%08X\n",
1983 (int)((std_id & (((v4l2_std_id)0xFFFFFFFF) << 32)) >> 32),
1984 (int)(std_id & ((v4l2_std_id)0xFFFFFFFF)));
1985
1986 rc = adjust_standard(peasycap, std_id);
1987 if (0 > rc) {
1988 JOM(8, "WARNING: adjust_standard() returned %i\n", rc);
1989 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
1990 return -ENOENT;
1991 }
1992 break;
1993 }
1994/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1995 case VIDIOC_REQBUFS: {
1996 int nbuffers;
1997 struct v4l2_requestbuffers v4l2_requestbuffers;
1998
1999 JOM(8, "VIDIOC_REQBUFS\n");
2000
2001 if (0 != copy_from_user(&v4l2_requestbuffers,
2002 (void __user *)arg,
2003 sizeof(struct v4l2_requestbuffers))) {
2004 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2005 return -EFAULT;
2006 }
2007
2008 if (v4l2_requestbuffers.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2009 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2010 return -EINVAL;
2011 }
2012 if (v4l2_requestbuffers.memory != V4L2_MEMORY_MMAP) {
2013 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2014 return -EINVAL;
2015 }
2016 nbuffers = v4l2_requestbuffers.count;
2017 JOM(8, " User requests %i buffers ...\n", nbuffers);
2018 if (nbuffers < 2)
2019 nbuffers = 2;
2020 if (nbuffers > FRAME_BUFFER_MANY)
2021 nbuffers = FRAME_BUFFER_MANY;
2022 if (v4l2_requestbuffers.count == nbuffers) {
2023 JOM(8, " ... agree to %i buffers\n",
2024 nbuffers);
2025 } else {
2026 JOM(8, " ... insist on %i buffers\n",
2027 nbuffers);
2028 v4l2_requestbuffers.count = nbuffers;
2029 }
2030 peasycap->frame_buffer_many = nbuffers;
2031
2032 if (copy_to_user((void __user *)arg, &v4l2_requestbuffers,
2033 sizeof(struct v4l2_requestbuffers))) {
2034 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2035 return -EFAULT;
2036 }
2037 break;
2038 }
2039/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2040 case VIDIOC_QUERYBUF: {
2041 u32 index;
2042 struct v4l2_buffer v4l2_buffer;
2043
2044 JOM(8, "VIDIOC_QUERYBUF\n");
2045
2046 if (peasycap->video_eof) {
2047 JOM(8, "returning -EIO because %i=video_eof\n",
2048 peasycap->video_eof);
2049 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2050 return -EIO;
2051 }
2052
2053 if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg,
2054 sizeof(struct v4l2_buffer))) {
2055 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2056 return -EFAULT;
2057 }
2058
2059 if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2060 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2061 return -EINVAL;
2062 }
2063 index = v4l2_buffer.index;
2064 if (index < 0 || index >= peasycap->frame_buffer_many)
2065 return -EINVAL;
2066 memset(&v4l2_buffer, 0, sizeof(struct v4l2_buffer));
2067 v4l2_buffer.index = index;
2068 v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2069 v4l2_buffer.bytesused = peasycap->frame_buffer_used;
2070 v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED |
2071 peasycap->done[index] |
2072 peasycap->queued[index];
2073 v4l2_buffer.field = V4L2_FIELD_NONE;
2074 v4l2_buffer.memory = V4L2_MEMORY_MMAP;
2075 v4l2_buffer.m.offset = index * FRAME_BUFFER_SIZE;
2076 v4l2_buffer.length = FRAME_BUFFER_SIZE;
2077
2078 JOM(16, " %10i=index\n", v4l2_buffer.index);
2079 JOM(16, " 0x%08X=type\n", v4l2_buffer.type);
2080 JOM(16, " %10i=bytesused\n", v4l2_buffer.bytesused);
2081 JOM(16, " 0x%08X=flags\n", v4l2_buffer.flags);
2082 JOM(16, " %10i=field\n", v4l2_buffer.field);
2083 JOM(16, " %10li=timestamp.tv_usec\n",
2084 (long)v4l2_buffer.timestamp.tv_usec);
2085 JOM(16, " %10i=sequence\n", v4l2_buffer.sequence);
2086 JOM(16, " 0x%08X=memory\n", v4l2_buffer.memory);
2087 JOM(16, " %10i=m.offset\n", v4l2_buffer.m.offset);
2088 JOM(16, " %10i=length\n", v4l2_buffer.length);
2089
2090 if (copy_to_user((void __user *)arg, &v4l2_buffer,
2091 sizeof(struct v4l2_buffer))) {
2092 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2093 return -EFAULT;
2094 }
2095 break;
2096 }
2097/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2098 case VIDIOC_QBUF: {
2099 struct v4l2_buffer v4l2_buffer;
2100
2101 JOM(8, "VIDIOC_QBUF\n");
2102
2103 if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg,
2104 sizeof(struct v4l2_buffer))) {
2105 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2106 return -EFAULT;
2107 }
2108
2109 if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2110 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2111 return -EINVAL;
2112 }
2113 if (v4l2_buffer.memory != V4L2_MEMORY_MMAP) {
2114 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2115 return -EINVAL;
2116 }
2117 if (v4l2_buffer.index < 0 ||
2118 v4l2_buffer.index >= peasycap->frame_buffer_many) {
2119 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2120 return -EINVAL;
2121 }
2122 v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED;
2123
2124 peasycap->done[v4l2_buffer.index] = 0;
2125 peasycap->queued[v4l2_buffer.index] = V4L2_BUF_FLAG_QUEUED;
2126
2127 if (copy_to_user((void __user *)arg, &v4l2_buffer,
2128 sizeof(struct v4l2_buffer))) {
2129 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2130 return -EFAULT;
2131 }
2132
2133 JOM(8, "..... user queueing frame buffer %i\n",
2134 (int)v4l2_buffer.index);
2135
2136 peasycap->frame_lock = 0;
2137
2138 break;
2139 }
2140/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2141 case VIDIOC_DQBUF:
2142 {
2143 struct timeval timeval, timeval2;
2144 int i, j;
2145 struct v4l2_buffer v4l2_buffer;
2146 int rcdq;
2147 u16 input;
2148
2149 JOM(8, "VIDIOC_DQBUF\n");
2150
2151 if ((peasycap->video_idle) || (peasycap->video_eof)) {
2152 JOM(8, "returning -EIO because "
2153 "%i=video_idle %i=video_eof\n",
2154 peasycap->video_idle, peasycap->video_eof);
2155 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2156 return -EIO;
2157 }
2158
2159 if (copy_from_user(&v4l2_buffer, (void __user *)arg,
2160 sizeof(struct v4l2_buffer))) {
2161 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2162 return -EFAULT;
2163 }
2164
2165 if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2166 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2167 return -EINVAL;
2168 }
2169
2170 if (peasycap->offerfields) {
2171 /*---------------------------------------------------*/
2172 /*
2173 * IN ITS 50 "fps" MODE tvtime SEEMS ALWAYS TO REQUEST
2174 * V4L2_FIELD_BOTTOM
2175 */
2176 /*---------------------------------------------------*/
2177 if (V4L2_FIELD_TOP == v4l2_buffer.field)
2178 JOM(8, "user wants V4L2_FIELD_TOP\n");
2179 else if (V4L2_FIELD_BOTTOM == v4l2_buffer.field)
2180 JOM(8, "user wants V4L2_FIELD_BOTTOM\n");
2181 else if (V4L2_FIELD_ANY == v4l2_buffer.field)
2182 JOM(8, "user wants V4L2_FIELD_ANY\n");
2183 else
2184 JOM(8, "user wants V4L2_FIELD_...UNKNOWN: %i\n",
2185 v4l2_buffer.field);
2186 }
2187
2188 if (!peasycap->video_isoc_streaming) {
2189 JOM(16, "returning -EIO because video urbs not streaming\n");
2190 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2191 return -EIO;
2192 }
2193 /*-------------------------------------------------------------------*/
2194 /*
2195 * IF THE USER HAS PREVIOUSLY CALLED easycap_poll(),
2196 * AS DETERMINED BY FINDING
2197 * THE FLAG peasycap->polled SET, THERE MUST BE
2198 * NO FURTHER WAIT HERE. IN THIS
2199 * CASE, JUST CHOOSE THE FRAME INDICATED BY peasycap->frame_read
2200 */
2201 /*-------------------------------------------------------------------*/
2202
2203 if (!peasycap->polled) {
2204 do {
2205 rcdq = easycap_video_dqbuf(peasycap, 0);
2206 if (-EIO == rcdq) {
2207 JOM(8, "returning -EIO because "
2208 "dqbuf() returned -EIO\n");
2209 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2210 return -EIO;
2211 }
2212 } while (0 != rcdq);
2213 } else {
2214 if (peasycap->video_eof) {
2215 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2216 return -EIO;
2217 }
2218 }
2219 if (V4L2_BUF_FLAG_DONE != peasycap->done[peasycap->frame_read]) {
2220 JOM(8, "V4L2_BUF_FLAG_DONE != 0x%08X\n",
2221 peasycap->done[peasycap->frame_read]);
2222 }
2223 peasycap->polled = 0;
2224
2225 if (!(peasycap->isequence % 10)) {
2226 for (i = 0; i < 179; i++)
2227 peasycap->merit[i] = peasycap->merit[i+1];
2228 peasycap->merit[179] = merit_saa(peasycap->pusb_device);
2229 j = 0;
2230 for (i = 0; i < 180; i++)
2231 j += peasycap->merit[i];
2232 if (90 < j) {
2233 SAM("easycap driver shutting down "
2234 "on condition blue\n");
2235 peasycap->video_eof = 1;
2236 peasycap->audio_eof = 1;
2237 }
2238 }
2239
2240 v4l2_buffer.index = peasycap->frame_read;
2241 v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2242 v4l2_buffer.bytesused = peasycap->frame_buffer_used;
2243 v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE;
2244 if (peasycap->offerfields)
2245 v4l2_buffer.field = V4L2_FIELD_BOTTOM;
2246 else
2247 v4l2_buffer.field = V4L2_FIELD_NONE;
2248 do_gettimeofday(&timeval);
2249 timeval2 = timeval;
2250
2251 v4l2_buffer.timestamp = timeval2;
2252 v4l2_buffer.sequence = peasycap->isequence++;
2253 v4l2_buffer.memory = V4L2_MEMORY_MMAP;
2254 v4l2_buffer.m.offset = v4l2_buffer.index * FRAME_BUFFER_SIZE;
2255 v4l2_buffer.length = FRAME_BUFFER_SIZE;
2256
2257 JOM(16, " %10i=index\n", v4l2_buffer.index);
2258 JOM(16, " 0x%08X=type\n", v4l2_buffer.type);
2259 JOM(16, " %10i=bytesused\n", v4l2_buffer.bytesused);
2260 JOM(16, " 0x%08X=flags\n", v4l2_buffer.flags);
2261 JOM(16, " %10i=field\n", v4l2_buffer.field);
2262 JOM(16, " %10li=timestamp.tv_sec\n",
2263 (long)v4l2_buffer.timestamp.tv_sec);
2264 JOM(16, " %10li=timestamp.tv_usec\n",
2265 (long)v4l2_buffer.timestamp.tv_usec);
2266 JOM(16, " %10i=sequence\n", v4l2_buffer.sequence);
2267 JOM(16, " 0x%08X=memory\n", v4l2_buffer.memory);
2268 JOM(16, " %10i=m.offset\n", v4l2_buffer.m.offset);
2269 JOM(16, " %10i=length\n", v4l2_buffer.length);
2270
2271 if (copy_to_user((void __user *)arg, &v4l2_buffer,
2272 sizeof(struct v4l2_buffer))) {
2273 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2274 return -EFAULT;
2275 }
2276
2277 input = peasycap->frame_buffer[peasycap->frame_read][0].input;
2278 if (0x08 & input) {
2279 JOM(8, "user is offered frame buffer %i, input %i\n",
2280 peasycap->frame_read, (0x07 & input));
2281 } else {
2282 JOM(8, "user is offered frame buffer %i\n",
2283 peasycap->frame_read);
2284 }
2285 peasycap->frame_lock = 1;
2286 JOM(8, "%i=peasycap->frame_fill\n", peasycap->frame_fill);
2287 if (peasycap->frame_read == peasycap->frame_fill) {
2288 if (peasycap->frame_lock) {
2289 JOM(8, "WORRY: filling frame buffer "
2290 "while offered to user\n");
2291 }
2292 }
2293 break;
2294 }
2295/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2296 case VIDIOC_STREAMON: {
2297 int i;
2298
2299 JOM(8, "VIDIOC_STREAMON\n");
2300
2301 peasycap->isequence = 0;
2302 for (i = 0; i < 180; i++)
2303 peasycap->merit[i] = 0;
2304 if (!peasycap->pusb_device) {
2305 SAM("ERROR: peasycap->pusb_device is NULL\n");
2306 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2307 return -EFAULT;
2308 }
2309 easycap_video_submit_urbs(peasycap);
2310 peasycap->video_idle = 0;
2311 peasycap->audio_idle = 0;
2312 peasycap->video_eof = 0;
2313 peasycap->audio_eof = 0;
2314 break;
2315 }
2316/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2317 case VIDIOC_STREAMOFF: {
2318 JOM(8, "VIDIOC_STREAMOFF\n");
2319
2320 if (!peasycap->pusb_device) {
2321 SAM("ERROR: peasycap->pusb_device is NULL\n");
2322 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2323 return -EFAULT;
2324 }
2325
2326 peasycap->video_idle = 1;
2327 peasycap->audio_idle = 1;
2328/*---------------------------------------------------------------------------*/
2329/*
2330 * IF THE WAIT QUEUES ARE NOT CLEARED IN RESPONSE TO THE STREAMOFF COMMAND
2331 * THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT. BEWARE.
2332 */
2333/*---------------------------------------------------------------------------*/
2334 JOM(8, "calling wake_up on wq_video and wq_audio\n");
2335 wake_up_interruptible(&(peasycap->wq_video));
2336 if (peasycap->psubstream)
2337 snd_pcm_period_elapsed(peasycap->psubstream);
2338 break;
2339 }
2340/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2341 case VIDIOC_G_PARM: {
2342 struct v4l2_streamparm *pv4l2_streamparm;
2343
2344 JOM(8, "VIDIOC_G_PARM\n");
2345 pv4l2_streamparm = memdup_user((void __user *)arg,
2346 sizeof(struct v4l2_streamparm));
2347 if (IS_ERR(pv4l2_streamparm)) {
2348 SAM("ERROR: copy from user failed\n");
2349 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2350 return PTR_ERR(pv4l2_streamparm);
2351 }
2352
2353 if (pv4l2_streamparm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2354 kfree(pv4l2_streamparm);
2355 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2356 return -EINVAL;
2357 }
2358 pv4l2_streamparm->parm.capture.capability = 0;
2359 pv4l2_streamparm->parm.capture.capturemode = 0;
2360 pv4l2_streamparm->parm.capture.timeperframe.numerator = 1;
2361
2362 if (peasycap->fps) {
2363 pv4l2_streamparm->parm.capture.timeperframe.
2364 denominator = peasycap->fps;
2365 } else {
2366 if (peasycap->ntsc) {
2367 pv4l2_streamparm->parm.capture.timeperframe.
2368 denominator = 30;
2369 } else {
2370 pv4l2_streamparm->parm.capture.timeperframe.
2371 denominator = 25;
2372 }
2373 }
2374
2375 pv4l2_streamparm->parm.capture.readbuffers =
2376 peasycap->frame_buffer_many;
2377 pv4l2_streamparm->parm.capture.extendedmode = 0;
2378 if (copy_to_user((void __user *)arg,
2379 pv4l2_streamparm,
2380 sizeof(struct v4l2_streamparm))) {
2381 kfree(pv4l2_streamparm);
2382 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2383 return -EFAULT;
2384 }
2385 kfree(pv4l2_streamparm);
2386 break;
2387 }
2388/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2389 case VIDIOC_S_PARM: {
2390 JOM(8, "VIDIOC_S_PARM unsupported\n");
2391 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2392 return -EINVAL;
2393 }
2394/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2395 case VIDIOC_G_AUDIO: {
2396 JOM(8, "VIDIOC_G_AUDIO unsupported\n");
2397 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2398 return -EINVAL;
2399 }
2400/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2401 case VIDIOC_S_AUDIO: {
2402 JOM(8, "VIDIOC_S_AUDIO unsupported\n");
2403 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2404 return -EINVAL;
2405 }
2406/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2407 case VIDIOC_S_TUNER: {
2408 JOM(8, "VIDIOC_S_TUNER unsupported\n");
2409 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2410 return -EINVAL;
2411 }
2412/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2413 case VIDIOC_G_FBUF:
2414 case VIDIOC_S_FBUF:
2415 case VIDIOC_OVERLAY: {
2416 JOM(8, "VIDIOC_G_FBUF|VIDIOC_S_FBUF|VIDIOC_OVERLAY unsupported\n");
2417 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2418 return -EINVAL;
2419 }
2420/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2421 case VIDIOC_G_TUNER: {
2422 JOM(8, "VIDIOC_G_TUNER unsupported\n");
2423 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2424 return -EINVAL;
2425 }
2426 case VIDIOC_G_FREQUENCY:
2427 case VIDIOC_S_FREQUENCY: {
2428 JOM(8, "VIDIOC_G_FREQUENCY|VIDIOC_S_FREQUENCY unsupported\n");
2429 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2430 return -EINVAL;
2431 }
2432/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
2433 default: {
2434 JOM(8, "ERROR: unrecognized V4L2 IOCTL command: 0x%08X\n", cmd);
2435 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2436 return -ENOIOCTLCMD;
2437 }
2438 }
2439 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
2440 JOM(4, "unlocked easycapdc60_dongle[%i].mutex_video\n", kd);
2441 return 0;
2442}
2443/*****************************************************************************/
diff --git a/drivers/staging/media/easycap/easycap_low.c b/drivers/staging/media/easycap/easycap_low.c
deleted file mode 100644
index 0380babed22c..000000000000
--- a/drivers/staging/media/easycap/easycap_low.c
+++ /dev/null
@@ -1,968 +0,0 @@
1/*****************************************************************************
2* *
3* *
4* easycap_low.c *
5* *
6* *
7*****************************************************************************/
8/*
9 *
10 * Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
11 *
12 *
13 * This is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * The software is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this software; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 *
27*/
28/*****************************************************************************/
29/*
30 * ACKNOWLEGEMENTS AND REFERENCES
31 * ------------------------------
32 * This driver makes use of register information contained in the Syntek
33 * Semicon DC-1125 driver hosted at
34 * http://sourceforge.net/projects/syntekdriver/.
35 * Particularly useful has been a patch to the latter driver provided by
36 * Ivor Hewitt in January 2009. The NTSC implementation is taken from the
37 * work of Ben Trask.
38*/
39/****************************************************************************/
40
41#include "easycap.h"
42
43
44#define GET(X, Y, Z) do { \
45 int __rc; \
46 *(Z) = (u16)0; \
47 __rc = regget(X, Y, Z, sizeof(u8)); \
48 if (0 > __rc) { \
49 JOT(8, ":-(%i\n", __LINE__); return __rc; \
50 } \
51} while (0)
52
53#define SET(X, Y, Z) do { \
54 int __rc; \
55 __rc = regset(X, Y, Z); \
56 if (0 > __rc) { \
57 JOT(8, ":-(%i\n", __LINE__); return __rc; \
58 } \
59} while (0)
60
61/*--------------------------------------------------------------------------*/
62static const struct stk1160config {
63 u16 reg;
64 u16 set;
65} stk1160configPAL[] = {
66 {0x000, 0x0098},
67 {0x002, 0x0093},
68
69 {0x001, 0x0003},
70 {0x003, 0x0080},
71 {0x00D, 0x0000},
72 {0x00F, 0x0002},
73 {0x018, 0x0010},
74 {0x019, 0x0000},
75 {0x01A, 0x0014},
76 {0x01B, 0x000E},
77 {0x01C, 0x0046},
78
79 {0x100, 0x0033},
80 {0x103, 0x0000},
81 {0x104, 0x0000},
82 {0x105, 0x0000},
83 {0x106, 0x0000},
84
85/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
86/*
87 * RESOLUTION 640x480
88*/
89/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
90 {0x110, 0x0008},
91 {0x111, 0x0000},
92 {0x112, 0x0020},
93 {0x113, 0x0000},
94 {0x114, 0x0508},
95 {0x115, 0x0005},
96 {0x116, 0x0110},
97 {0x117, 0x0001},
98/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
99
100 {0x202, 0x000F},
101 {0x203, 0x004A},
102 {0x2FF, 0x0000},
103
104 {0xFFF, 0xFFFF}
105};
106/*--------------------------------------------------------------------------*/
107static const struct stk1160config stk1160configNTSC[] = {
108 {0x000, 0x0098},
109 {0x002, 0x0093},
110
111 {0x001, 0x0003},
112 {0x003, 0x0080},
113 {0x00D, 0x0000},
114 {0x00F, 0x0002},
115 {0x018, 0x0010},
116 {0x019, 0x0000},
117 {0x01A, 0x0014},
118 {0x01B, 0x000E},
119 {0x01C, 0x0046},
120
121 {0x100, 0x0033},
122 {0x103, 0x0000},
123 {0x104, 0x0000},
124 {0x105, 0x0000},
125 {0x106, 0x0000},
126
127/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
128/*
129 * RESOLUTION 640x480
130*/
131/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
132 {0x110, 0x0008},
133 {0x111, 0x0000},
134 {0x112, 0x0003},
135 {0x113, 0x0000},
136 {0x114, 0x0508},
137 {0x115, 0x0005},
138 {0x116, 0x00F3},
139 {0x117, 0x0000},
140/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
141
142 {0x202, 0x000F},
143 {0x203, 0x004A},
144 {0x2FF, 0x0000},
145
146 {0xFFF, 0xFFFF}
147};
148/*--------------------------------------------------------------------------*/
149static const struct saa7113config {
150 u8 reg;
151 u8 set;
152} saa7113configPAL[] = {
153 {0x01, 0x08},
154 {0x02, 0x80},
155 {0x03, 0x33},
156 {0x04, 0x00},
157 {0x05, 0x00},
158 {0x06, 0xE9},
159 {0x07, 0x0D},
160 {0x08, 0x38},
161 {0x09, 0x00},
162 {0x0A, SAA_0A_DEFAULT},
163 {0x0B, SAA_0B_DEFAULT},
164 {0x0C, SAA_0C_DEFAULT},
165 {0x0D, SAA_0D_DEFAULT},
166 {0x0E, 0x01},
167 {0x0F, 0x36},
168 {0x10, 0x00},
169 {0x11, 0x0C},
170 {0x12, 0xE7},
171 {0x13, 0x00},
172 {0x15, 0x00},
173 {0x16, 0x00},
174 {0x40, 0x02},
175 {0x41, 0xFF},
176 {0x42, 0xFF},
177 {0x43, 0xFF},
178 {0x44, 0xFF},
179 {0x45, 0xFF},
180 {0x46, 0xFF},
181 {0x47, 0xFF},
182 {0x48, 0xFF},
183 {0x49, 0xFF},
184 {0x4A, 0xFF},
185 {0x4B, 0xFF},
186 {0x4C, 0xFF},
187 {0x4D, 0xFF},
188 {0x4E, 0xFF},
189 {0x4F, 0xFF},
190 {0x50, 0xFF},
191 {0x51, 0xFF},
192 {0x52, 0xFF},
193 {0x53, 0xFF},
194 {0x54, 0xFF},
195 {0x55, 0xFF},
196 {0x56, 0xFF},
197 {0x57, 0xFF},
198 {0x58, 0x40},
199 {0x59, 0x54},
200 {0x5A, 0x07},
201 {0x5B, 0x83},
202
203 {0xFF, 0xFF}
204};
205/*--------------------------------------------------------------------------*/
206static const struct saa7113config saa7113configNTSC[] = {
207 {0x01, 0x08},
208 {0x02, 0x80},
209 {0x03, 0x33},
210 {0x04, 0x00},
211 {0x05, 0x00},
212 {0x06, 0xE9},
213 {0x07, 0x0D},
214 {0x08, 0x78},
215 {0x09, 0x00},
216 {0x0A, SAA_0A_DEFAULT},
217 {0x0B, SAA_0B_DEFAULT},
218 {0x0C, SAA_0C_DEFAULT},
219 {0x0D, SAA_0D_DEFAULT},
220 {0x0E, 0x01},
221 {0x0F, 0x36},
222 {0x10, 0x00},
223 {0x11, 0x0C},
224 {0x12, 0xE7},
225 {0x13, 0x00},
226 {0x15, 0x00},
227 {0x16, 0x00},
228 {0x40, 0x82},
229 {0x41, 0xFF},
230 {0x42, 0xFF},
231 {0x43, 0xFF},
232 {0x44, 0xFF},
233 {0x45, 0xFF},
234 {0x46, 0xFF},
235 {0x47, 0xFF},
236 {0x48, 0xFF},
237 {0x49, 0xFF},
238 {0x4A, 0xFF},
239 {0x4B, 0xFF},
240 {0x4C, 0xFF},
241 {0x4D, 0xFF},
242 {0x4E, 0xFF},
243 {0x4F, 0xFF},
244 {0x50, 0xFF},
245 {0x51, 0xFF},
246 {0x52, 0xFF},
247 {0x53, 0xFF},
248 {0x54, 0xFF},
249 {0x55, 0xFF},
250 {0x56, 0xFF},
251 {0x57, 0xFF},
252 {0x58, 0x40},
253 {0x59, 0x54},
254 {0x5A, 0x0A},
255 {0x5B, 0x83},
256
257 {0xFF, 0xFF}
258};
259
260static int regget(struct usb_device *pusb_device,
261 u16 index, void *reg, int reg_size)
262{
263 int rc;
264
265 if (!pusb_device)
266 return -ENODEV;
267
268 rc = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0),
269 0x00,
270 (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE),
271 0x00,
272 index, reg, reg_size, 50000);
273
274 return rc;
275}
276
277static int regset(struct usb_device *pusb_device, u16 index, u16 value)
278{
279 int rc;
280
281 if (!pusb_device)
282 return -ENODEV;
283
284 rc = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0),
285 0x01,
286 (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE),
287 value, index, NULL, 0, 500);
288
289 if (rc < 0)
290 return rc;
291
292 if (easycap_readback) {
293 u16 igot = 0;
294 rc = regget(pusb_device, index, &igot, sizeof(igot));
295 igot = 0xFF & igot;
296 switch (index) {
297 case 0x000:
298 case 0x500:
299 case 0x502:
300 case 0x503:
301 case 0x504:
302 case 0x506:
303 case 0x507:
304 break;
305
306 case 0x204:
307 case 0x205:
308 case 0x350:
309 case 0x351:
310 if (igot)
311 JOT(8, "unexpected 0x%02X "
312 "for STK register 0x%03X\n",
313 igot, index);
314 break;
315
316 default:
317 if ((0xFF & value) != igot)
318 JOT(8, "unexpected 0x%02X != 0x%02X "
319 "for STK register 0x%03X\n",
320 igot, value, index);
321 break;
322 }
323 }
324
325 return rc;
326}
327/*--------------------------------------------------------------------------*/
328/*
329 * FUNCTION wait_i2c() RETURNS 0 ON SUCCESS
330*/
331/*--------------------------------------------------------------------------*/
332static int wait_i2c(struct usb_device *p)
333{
334 u16 get0;
335 u8 igot;
336 const int max = 2;
337 int k;
338
339 if (!p)
340 return -ENODEV;
341
342 for (k = 0; k < max; k++) {
343 GET(p, 0x0201, &igot); get0 = igot;
344 switch (get0) {
345 case 0x04:
346 case 0x01:
347 return 0;
348 case 0x00:
349 msleep(20);
350 continue;
351 default:
352 return get0 - 1;
353 }
354 }
355 return -1;
356}
357
358/****************************************************************************/
359int write_saa(struct usb_device *p, u16 reg0, u16 set0)
360{
361 if (!p)
362 return -ENODEV;
363 SET(p, 0x200, 0x00);
364 SET(p, 0x204, reg0);
365 SET(p, 0x205, set0);
366 SET(p, 0x200, 0x01);
367 return wait_i2c(p);
368}
369/****************************************************************************/
370/*--------------------------------------------------------------------------*/
371/*
372 * REGISTER 500: SETTING VALUE TO 0x008B READS FROM VT1612A (?)
373 * REGISTER 500: SETTING VALUE TO 0x008C WRITES TO VT1612A
374 * REGISTER 502: LEAST SIGNIFICANT BYTE OF VALUE TO SET
375 * REGISTER 503: MOST SIGNIFICANT BYTE OF VALUE TO SET
376 * REGISTER 504: TARGET ADDRESS ON VT1612A
377 */
378/*--------------------------------------------------------------------------*/
379static int write_vt(struct usb_device *p, u16 reg0, u16 set0)
380{
381 u8 igot;
382 u16 got502, got503;
383 u16 set502, set503;
384
385 if (!p)
386 return -ENODEV;
387 SET(p, 0x0504, reg0);
388 SET(p, 0x0500, 0x008B);
389
390 GET(p, 0x0502, &igot); got502 = (0xFF & igot);
391 GET(p, 0x0503, &igot); got503 = (0xFF & igot);
392
393 JOT(16, "write_vt(., 0x%04X, 0x%04X): was 0x%04X\n",
394 reg0, set0, ((got503 << 8) | got502));
395
396 set502 = (0x00FF & set0);
397 set503 = ((0xFF00 & set0) >> 8);
398
399 SET(p, 0x0504, reg0);
400 SET(p, 0x0502, set502);
401 SET(p, 0x0503, set503);
402 SET(p, 0x0500, 0x008C);
403
404 return 0;
405}
406/****************************************************************************/
407/*--------------------------------------------------------------------------*/
408/*
409 * REGISTER 500: SETTING VALUE TO 0x008B READS FROM VT1612A (?)
410 * REGISTER 500: SETTING VALUE TO 0x008C WRITES TO VT1612A
411 * REGISTER 502: LEAST SIGNIFICANT BYTE OF VALUE TO GET
412 * REGISTER 503: MOST SIGNIFICANT BYTE OF VALUE TO GET
413 * REGISTER 504: TARGET ADDRESS ON VT1612A
414 */
415/*--------------------------------------------------------------------------*/
416static int read_vt(struct usb_device *p, u16 reg0)
417{
418 u8 igot;
419 u16 got502, got503;
420
421 if (!p)
422 return -ENODEV;
423 SET(p, 0x0504, reg0);
424 SET(p, 0x0500, 0x008B);
425
426 GET(p, 0x0502, &igot); got502 = (0xFF & igot);
427 GET(p, 0x0503, &igot); got503 = (0xFF & igot);
428
429 JOT(16, "read_vt(., 0x%04X): has 0x%04X\n",
430 reg0, ((got503 << 8) | got502));
431
432 return (got503 << 8) | got502;
433}
434/****************************************************************************/
435/*--------------------------------------------------------------------------*/
436/*
437 * THESE APPEAR TO HAVE NO EFFECT ON EITHER VIDEO OR AUDIO.
438 */
439/*--------------------------------------------------------------------------*/
440static int write_300(struct usb_device *p)
441{
442 if (!p)
443 return -ENODEV;
444 SET(p, 0x300, 0x0012);
445 SET(p, 0x350, 0x002D);
446 SET(p, 0x351, 0x0001);
447 SET(p, 0x352, 0x0000);
448 SET(p, 0x353, 0x0000);
449 SET(p, 0x300, 0x0080);
450 return 0;
451}
452/****************************************************************************/
453/****************************************************************************/
454int setup_stk(struct usb_device *p, bool ntsc)
455{
456 int i;
457 const struct stk1160config *cfg;
458 if (!p)
459 return -ENODEV;
460 cfg = (ntsc) ? stk1160configNTSC : stk1160configPAL;
461 for (i = 0; cfg[i].reg != 0xFFF; i++)
462 SET(p, cfg[i].reg, cfg[i].set);
463
464 write_300(p);
465
466 return 0;
467}
468/****************************************************************************/
469int setup_saa(struct usb_device *p, bool ntsc)
470{
471 int i, rc;
472 const struct saa7113config *cfg;
473 if (!p)
474 return -ENODEV;
475 cfg = (ntsc) ? saa7113configNTSC : saa7113configPAL;
476 for (i = 0; cfg[i].reg != 0xFF; i++) {
477 rc = write_saa(p, cfg[i].reg, cfg[i].set);
478 if (rc)
479 dev_err(&p->dev,
480 "Failed to set SAA register %d", cfg[i].reg);
481 }
482 return 0;
483}
484/****************************************************************************/
485int merit_saa(struct usb_device *p)
486{
487 int rc;
488
489 if (!p)
490 return -ENODEV;
491 rc = read_saa(p, 0x1F);
492 return ((0 > rc) || (0x02 & rc)) ? 1 : 0;
493}
494/****************************************************************************/
495int ready_saa(struct usb_device *p)
496{
497 int j, rc, rate;
498 const int max = 5, marktime = PATIENCE/5;
499/*--------------------------------------------------------------------------*/
500/*
501 * RETURNS 0 FOR INTERLACED 50 Hz
502 * 1 FOR NON-INTERLACED 50 Hz
503 * 2 FOR INTERLACED 60 Hz
504 * 3 FOR NON-INTERLACED 60 Hz
505*/
506/*--------------------------------------------------------------------------*/
507 if (!p)
508 return -ENODEV;
509 j = 0;
510 while (max > j) {
511 rc = read_saa(p, 0x1F);
512 if (0 <= rc) {
513 if (0 == (0x40 & rc))
514 break;
515 if (1 == (0x01 & rc))
516 break;
517 }
518 msleep(marktime);
519 j++;
520 }
521
522 if (max == j)
523 return -1;
524
525 if (0x20 & rc) {
526 rate = 2;
527 JOT(8, "hardware detects 60 Hz\n");
528 } else {
529 rate = 0;
530 JOT(8, "hardware detects 50 Hz\n");
531 }
532 if (0x80 & rc)
533 JOT(8, "hardware detects interlacing\n");
534 else {
535 rate++;
536 JOT(8, "hardware detects no interlacing\n");
537 }
538 return 0;
539}
540/****************************************************************************/
541int read_saa(struct usb_device *p, u16 reg0)
542{
543 u8 igot;
544
545 if (!p)
546 return -ENODEV;
547 SET(p, 0x208, reg0);
548 SET(p, 0x200, 0x20);
549 if (0 != wait_i2c(p))
550 return -1;
551 igot = 0;
552 GET(p, 0x0209, &igot);
553 return igot;
554}
555/****************************************************************************/
556static int read_stk(struct usb_device *p, u32 reg0)
557{
558 u8 igot;
559
560 if (!p)
561 return -ENODEV;
562 igot = 0;
563 GET(p, reg0, &igot);
564 return igot;
565}
566int select_input(struct usb_device *p, int input, int mode)
567{
568 int ir;
569
570 if (!p)
571 return -ENODEV;
572 stop_100(p);
573 switch (input) {
574 case 0:
575 case 1: {
576 if (0 != write_saa(p, 0x02, 0x80))
577 SAY("ERROR: failed to set SAA register 0x02 "
578 "for input %i\n", input);
579
580 SET(p, 0x0000, 0x0098);
581 SET(p, 0x0002, 0x0078);
582 break;
583 }
584 case 2: {
585 if (0 != write_saa(p, 0x02, 0x80))
586 SAY("ERROR: failed to set SAA register 0x02 "
587 "for input %i\n", input);
588
589 SET(p, 0x0000, 0x0090);
590 SET(p, 0x0002, 0x0078);
591 break;
592 }
593 case 3: {
594 if (0 != write_saa(p, 0x02, 0x80))
595 SAY("ERROR: failed to set SAA register 0x02 "
596 " for input %i\n", input);
597
598 SET(p, 0x0000, 0x0088);
599 SET(p, 0x0002, 0x0078);
600 break;
601 }
602 case 4: {
603 if (0 != write_saa(p, 0x02, 0x80)) {
604 SAY("ERROR: failed to set SAA register 0x02 "
605 "for input %i\n", input);
606 }
607 SET(p, 0x0000, 0x0080);
608 SET(p, 0x0002, 0x0078);
609 break;
610 }
611 case 5: {
612 if (9 != mode)
613 mode = 7;
614 switch (mode) {
615 case 7: {
616 if (0 != write_saa(p, 0x02, 0x87))
617 SAY("ERROR: failed to set SAA register 0x02 "
618 "for input %i\n", input);
619
620 if (0 != write_saa(p, 0x05, 0xFF))
621 SAY("ERROR: failed to set SAA register 0x05 "
622 "for input %i\n", input);
623
624 break;
625 }
626 case 9: {
627 if (0 != write_saa(p, 0x02, 0x89))
628 SAY("ERROR: failed to set SAA register 0x02 "
629 "for input %i\n", input);
630
631 if (0 != write_saa(p, 0x05, 0x00))
632 SAY("ERROR: failed to set SAA register 0x05 "
633 "for input %i\n", input);
634
635 break;
636 }
637 default:
638 SAY("MISTAKE: bad mode: %i\n", mode);
639 return -1;
640 }
641
642 if (0 != write_saa(p, 0x04, 0x00))
643 SAY("ERROR: failed to set SAA register 0x04 "
644 "for input %i\n", input);
645
646 if (0 != write_saa(p, 0x09, 0x80))
647 SAY("ERROR: failed to set SAA register 0x09 "
648 "for input %i\n", input);
649
650 SET(p, 0x0002, 0x0093);
651 break;
652 }
653 default:
654 SAY("ERROR: bad input: %i\n", input);
655 return -1;
656 }
657
658 ir = read_stk(p, 0x00);
659 JOT(8, "STK register 0x00 has 0x%02X\n", ir);
660 ir = read_saa(p, 0x02);
661 JOT(8, "SAA register 0x02 has 0x%02X\n", ir);
662
663 start_100(p);
664
665 return 0;
666}
667/****************************************************************************/
668int set_resolution(struct usb_device *p,
669 u16 set0, u16 set1, u16 set2, u16 set3)
670{
671 u16 u0x0111, u0x0113, u0x0115, u0x0117;
672
673 if (!p)
674 return -ENODEV;
675 u0x0111 = ((0xFF00 & set0) >> 8);
676 u0x0113 = ((0xFF00 & set1) >> 8);
677 u0x0115 = ((0xFF00 & set2) >> 8);
678 u0x0117 = ((0xFF00 & set3) >> 8);
679
680 SET(p, 0x0110, (0x00FF & set0));
681 SET(p, 0x0111, u0x0111);
682 SET(p, 0x0112, (0x00FF & set1));
683 SET(p, 0x0113, u0x0113);
684 SET(p, 0x0114, (0x00FF & set2));
685 SET(p, 0x0115, u0x0115);
686 SET(p, 0x0116, (0x00FF & set3));
687 SET(p, 0x0117, u0x0117);
688
689 return 0;
690}
691/****************************************************************************/
692int start_100(struct usb_device *p)
693{
694 u16 get116, get117, get0;
695 u8 igot116, igot117, igot;
696
697 if (!p)
698 return -ENODEV;
699 GET(p, 0x0116, &igot116);
700 get116 = igot116;
701 GET(p, 0x0117, &igot117);
702 get117 = igot117;
703 SET(p, 0x0116, 0x0000);
704 SET(p, 0x0117, 0x0000);
705
706 GET(p, 0x0100, &igot);
707 get0 = igot;
708 SET(p, 0x0100, (0x80 | get0));
709
710 SET(p, 0x0116, get116);
711 SET(p, 0x0117, get117);
712
713 return 0;
714}
715/****************************************************************************/
716int stop_100(struct usb_device *p)
717{
718 u16 get0;
719 u8 igot;
720
721 if (!p)
722 return -ENODEV;
723 GET(p, 0x0100, &igot);
724 get0 = igot;
725 SET(p, 0x0100, (0x7F & get0));
726 return 0;
727}
728/****************************************************************************/
729/****************************************************************************/
730/*****************************************************************************/
731int easycap_wakeup_device(struct usb_device *pusb_device)
732{
733 if (!pusb_device)
734 return -ENODEV;
735
736 return usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0),
737 USB_REQ_SET_FEATURE,
738 USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
739 USB_DEVICE_REMOTE_WAKEUP,
740 0, NULL, 0, 50000);
741}
742/*****************************************************************************/
743int easycap_audio_setup(struct easycap *peasycap)
744{
745 struct usb_device *pusb_device;
746 u8 buffer[1];
747 int rc, id1, id2;
748/*---------------------------------------------------------------------------*/
749/*
750 * IMPORTANT:
751 * THE MESSAGE OF TYPE (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE)
752 * CAUSES MUTING IF THE VALUE 0x0100 IS SENT.
753 * TO ENABLE AUDIO THE VALUE 0x0200 MUST BE SENT.
754 */
755/*---------------------------------------------------------------------------*/
756 const u8 request = 0x01;
757 const u8 requesttype = USB_DIR_OUT |
758 USB_TYPE_CLASS |
759 USB_RECIP_INTERFACE;
760 const u16 value_unmute = 0x0200;
761 const u16 index = 0x0301;
762 const u16 length = 1;
763
764 if (!peasycap)
765 return -EFAULT;
766
767 pusb_device = peasycap->pusb_device;
768 if (!pusb_device)
769 return -ENODEV;
770
771 JOM(8, "%02X %02X %02X %02X %02X %02X %02X %02X\n",
772 requesttype, request,
773 (0x00FF & value_unmute),
774 (0xFF00 & value_unmute) >> 8,
775 (0x00FF & index),
776 (0xFF00 & index) >> 8,
777 (0x00FF & length),
778 (0xFF00 & length) >> 8);
779
780 buffer[0] = 0x01;
781
782 rc = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0),
783 request, requesttype, value_unmute,
784 index, &buffer[0], length, 50000);
785
786 JOT(8, "0x%02X=buffer\n", buffer[0]);
787 if (rc != (int)length) {
788 switch (rc) {
789 case -EPIPE:
790 SAY("usb_control_msg returned -EPIPE\n");
791 break;
792 default:
793 SAY("ERROR: usb_control_msg returned %i\n", rc);
794 break;
795 }
796 }
797/*--------------------------------------------------------------------------*/
798/*
799 * REGISTER 500: SETTING VALUE TO 0x0094 RESETS AUDIO CONFIGURATION ???
800 * REGISTER 506: ANALOGUE AUDIO ATTENTUATOR ???
801 * FOR THE CVBS+S-VIDEO HARDWARE:
802 * SETTING VALUE TO 0x0000 GIVES QUIET SOUND.
803 * THE UPPER BYTE SEEMS TO HAVE NO EFFECT.
804 * FOR THE FOUR-CVBS HARDWARE:
805 * SETTING VALUE TO 0x0000 SEEMS TO HAVE NO EFFECT.
806 * REGISTER 507: ANALOGUE AUDIO PREAMPLIFIER ON/OFF ???
807 * FOR THE CVBS-S-VIDEO HARDWARE:
808 * SETTING VALUE TO 0x0001 GIVES VERY LOUD, DISTORTED SOUND.
809 * THE UPPER BYTE SEEMS TO HAVE NO EFFECT.
810 */
811/*--------------------------------------------------------------------------*/
812 SET(pusb_device, 0x0500, 0x0094);
813 SET(pusb_device, 0x0500, 0x008C);
814 SET(pusb_device, 0x0506, 0x0001);
815 SET(pusb_device, 0x0507, 0x0000);
816 id1 = read_vt(pusb_device, 0x007C);
817 id2 = read_vt(pusb_device, 0x007E);
818 SAM("0x%04X:0x%04X is audio vendor id\n", id1, id2);
819/*---------------------------------------------------------------------------*/
820/*
821 * SELECT AUDIO SOURCE "LINE IN" AND SET THE AUDIO GAIN.
822*/
823/*---------------------------------------------------------------------------*/
824 if (easycap_audio_gainset(pusb_device, peasycap->gain))
825 SAY("ERROR: audio_gainset() failed\n");
826 check_vt(pusb_device);
827 return 0;
828}
829/*****************************************************************************/
830int check_vt(struct usb_device *pusb_device)
831{
832 int igot;
833
834 if (!pusb_device)
835 return -ENODEV;
836 igot = read_vt(pusb_device, 0x0002);
837 if (0 > igot)
838 SAY("ERROR: failed to read VT1612A register 0x02\n");
839 if (0x8000 & igot)
840 SAY("register 0x%02X muted\n", 0x02);
841
842 igot = read_vt(pusb_device, 0x000E);
843 if (0 > igot)
844 SAY("ERROR: failed to read VT1612A register 0x0E\n");
845 if (0x8000 & igot)
846 SAY("register 0x%02X muted\n", 0x0E);
847
848 igot = read_vt(pusb_device, 0x0010);
849 if (0 > igot)
850 SAY("ERROR: failed to read VT1612A register 0x10\n");
851 if (0x8000 & igot)
852 SAY("register 0x%02X muted\n", 0x10);
853
854 igot = read_vt(pusb_device, 0x0012);
855 if (0 > igot)
856 SAY("ERROR: failed to read VT1612A register 0x12\n");
857 if (0x8000 & igot)
858 SAY("register 0x%02X muted\n", 0x12);
859
860 igot = read_vt(pusb_device, 0x0014);
861 if (0 > igot)
862 SAY("ERROR: failed to read VT1612A register 0x14\n");
863 if (0x8000 & igot)
864 SAY("register 0x%02X muted\n", 0x14);
865
866 igot = read_vt(pusb_device, 0x0016);
867 if (0 > igot)
868 SAY("ERROR: failed to read VT1612A register 0x16\n");
869 if (0x8000 & igot)
870 SAY("register 0x%02X muted\n", 0x16);
871
872 igot = read_vt(pusb_device, 0x0018);
873 if (0 > igot)
874 SAY("ERROR: failed to read VT1612A register 0x18\n");
875 if (0x8000 & igot)
876 SAY("register 0x%02X muted\n", 0x18);
877
878 igot = read_vt(pusb_device, 0x001C);
879 if (0 > igot)
880 SAY("ERROR: failed to read VT1612A register 0x1C\n");
881 if (0x8000 & igot)
882 SAY("register 0x%02X muted\n", 0x1C);
883
884 return 0;
885}
886/*****************************************************************************/
887/*---------------------------------------------------------------------------*/
888/* NOTE: THIS DOES INCREASE THE VOLUME DRAMATICALLY:
889 * audio_gainset(pusb_device, 0x000F);
890 *
891 * loud dB register 0x10 dB register 0x1C dB total
892 * 0 -34.5 0 -34.5
893 * .. .... . ....
894 * 15 10.5 0 10.5
895 * 16 12.0 0 12.0
896 * 17 12.0 1.5 13.5
897 * .. .... .... ....
898 * 31 12.0 22.5 34.5
899*/
900/*---------------------------------------------------------------------------*/
901int easycap_audio_gainset(struct usb_device *pusb_device, s8 loud)
902{
903 int igot;
904 u8 tmp;
905 u16 mute;
906
907 if (!pusb_device)
908 return -ENODEV;
909 if (0 > loud)
910 loud = 0;
911 if (31 < loud)
912 loud = 31;
913
914 write_vt(pusb_device, 0x0002, 0x8000);
915/*---------------------------------------------------------------------------*/
916 igot = read_vt(pusb_device, 0x000E);
917 if (0 > igot) {
918 SAY("ERROR: failed to read VT1612A register 0x0E\n");
919 mute = 0x0000;
920 } else
921 mute = 0x8000 & ((unsigned int)igot);
922 mute = 0;
923
924 if (16 > loud)
925 tmp = 0x01 | (0x001F & (((u8)(15 - loud)) << 1));
926 else
927 tmp = 0;
928
929 JOT(8, "0x%04X=(mute|tmp) for VT1612A register 0x0E\n", mute | tmp);
930 write_vt(pusb_device, 0x000E, (mute | tmp));
931/*---------------------------------------------------------------------------*/
932 igot = read_vt(pusb_device, 0x0010);
933 if (0 > igot) {
934 SAY("ERROR: failed to read VT1612A register 0x10\n");
935 mute = 0x0000;
936 } else
937 mute = 0x8000 & ((unsigned int)igot);
938 mute = 0;
939
940 JOT(8, "0x%04X=(mute|tmp|(tmp<<8)) for VT1612A register 0x10,...0x18\n",
941 mute | tmp | (tmp << 8));
942 write_vt(pusb_device, 0x0010, (mute | tmp | (tmp << 8)));
943 write_vt(pusb_device, 0x0012, (mute | tmp | (tmp << 8)));
944 write_vt(pusb_device, 0x0014, (mute | tmp | (tmp << 8)));
945 write_vt(pusb_device, 0x0016, (mute | tmp | (tmp << 8)));
946 write_vt(pusb_device, 0x0018, (mute | tmp | (tmp << 8)));
947/*---------------------------------------------------------------------------*/
948 igot = read_vt(pusb_device, 0x001C);
949 if (0 > igot) {
950 SAY("ERROR: failed to read VT1612A register 0x1C\n");
951 mute = 0x0000;
952 } else
953 mute = 0x8000 & ((unsigned int)igot);
954 mute = 0;
955
956 if (16 <= loud)
957 tmp = 0x000F & (u8)(loud - 16);
958 else
959 tmp = 0;
960
961 JOT(8, "0x%04X=(mute|tmp|(tmp<<8)) for VT1612A register 0x1C\n",
962 mute | tmp | (tmp << 8));
963 write_vt(pusb_device, 0x001C, (mute | tmp | (tmp << 8)));
964 write_vt(pusb_device, 0x001A, 0x0404);
965 write_vt(pusb_device, 0x0002, 0x0000);
966 return 0;
967}
968/*****************************************************************************/
diff --git a/drivers/staging/media/easycap/easycap_main.c b/drivers/staging/media/easycap/easycap_main.c
deleted file mode 100644
index 8269c77dbf7d..000000000000
--- a/drivers/staging/media/easycap/easycap_main.c
+++ /dev/null
@@ -1,4239 +0,0 @@
1/******************************************************************************
2* *
3* easycap_main.c *
4* *
5* Video driver for EasyCAP USB2.0 Video Capture Device DC60 *
6* *
7* *
8******************************************************************************/
9/*
10 *
11 * Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
12 *
13 *
14 * This is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * The software is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this software; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 *
28*/
29/*****************************************************************************/
30
31#include "easycap.h"
32#include <linux/usb/audio.h>
33
34
35MODULE_LICENSE("GPL");
36MODULE_AUTHOR("R.M. Thomas <rmthomas@sciolus.org>");
37MODULE_DESCRIPTION(EASYCAP_DRIVER_DESCRIPTION);
38MODULE_VERSION(EASYCAP_DRIVER_VERSION);
39
40#ifdef CONFIG_EASYCAP_DEBUG
41int easycap_debug;
42module_param_named(debug, easycap_debug, int, S_IRUGO | S_IWUSR);
43MODULE_PARM_DESC(debug, "Debug level: 0(default),1,2,...,9");
44#endif /* CONFIG_EASYCAP_DEBUG */
45
46bool easycap_readback;
47module_param_named(readback, easycap_readback, bool, S_IRUGO | S_IWUSR);
48MODULE_PARM_DESC(readback, "read back written registers: (default false)");
49
50static int easycap_bars = 1;
51module_param_named(bars, easycap_bars, int, S_IRUGO | S_IWUSR);
52MODULE_PARM_DESC(bars,
53 "Testcard bars on input signal failure: 0=>no, 1=>yes(default)");
54
55static int easycap_gain = 16;
56module_param_named(gain, easycap_gain, int, S_IRUGO | S_IWUSR);
57MODULE_PARM_DESC(gain, "Audio gain: 0,...,16(default),...31");
58
59static bool easycap_ntsc;
60module_param_named(ntsc, easycap_ntsc, bool, S_IRUGO | S_IWUSR);
61MODULE_PARM_DESC(ntsc, "NTSC default encoding (default PAL)");
62
63
64
65struct easycap_dongle easycapdc60_dongle[DONGLE_MANY];
66static struct mutex mutex_dongle;
67static void easycap_complete(struct urb *purb);
68static int reset(struct easycap *peasycap);
69static int field2frame(struct easycap *peasycap);
70static int redaub(struct easycap *peasycap,
71 void *pad, void *pex, int much, int more,
72 u8 mask, u8 margin, bool isuy);
73
74const char *strerror(int err)
75{
76#define ERRNOSTR(_e) case _e: return # _e
77 switch (err) {
78 case 0: return "OK";
79 ERRNOSTR(ENOMEM);
80 ERRNOSTR(ENODEV);
81 ERRNOSTR(ENXIO);
82 ERRNOSTR(EINVAL);
83 ERRNOSTR(EAGAIN);
84 ERRNOSTR(EFBIG);
85 ERRNOSTR(EPIPE);
86 ERRNOSTR(EMSGSIZE);
87 ERRNOSTR(ENOSPC);
88 ERRNOSTR(EINPROGRESS);
89 ERRNOSTR(ENOSR);
90 ERRNOSTR(EOVERFLOW);
91 ERRNOSTR(EPROTO);
92 ERRNOSTR(EILSEQ);
93 ERRNOSTR(ETIMEDOUT);
94 ERRNOSTR(EOPNOTSUPP);
95 ERRNOSTR(EPFNOSUPPORT);
96 ERRNOSTR(EAFNOSUPPORT);
97 ERRNOSTR(EADDRINUSE);
98 ERRNOSTR(EADDRNOTAVAIL);
99 ERRNOSTR(ENOBUFS);
100 ERRNOSTR(EISCONN);
101 ERRNOSTR(ENOTCONN);
102 ERRNOSTR(ESHUTDOWN);
103 ERRNOSTR(ENOENT);
104 ERRNOSTR(ECONNRESET);
105 ERRNOSTR(ETIME);
106 ERRNOSTR(ECOMM);
107 ERRNOSTR(EREMOTEIO);
108 ERRNOSTR(EXDEV);
109 ERRNOSTR(EPERM);
110 default: return "unknown";
111 }
112
113#undef ERRNOSTR
114}
115
116/****************************************************************************/
117/*---------------------------------------------------------------------------*/
118/*
119 * THIS ROUTINE DOES NOT DETECT DUPLICATE OCCURRENCES OF POINTER peasycap
120*/
121/*---------------------------------------------------------------------------*/
122int easycap_isdongle(struct easycap *peasycap)
123{
124 int k;
125 if (!peasycap)
126 return -2;
127 for (k = 0; k < DONGLE_MANY; k++) {
128 if (easycapdc60_dongle[k].peasycap == peasycap) {
129 peasycap->isdongle = k;
130 return k;
131 }
132 }
133 return -1;
134}
135/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
136static int easycap_open(struct inode *inode, struct file *file)
137{
138 struct video_device *pvideo_device;
139 struct easycap *peasycap;
140 int rc;
141
142 JOT(4, "\n");
143 SAY("==========OPEN=========\n");
144
145 pvideo_device = video_devdata(file);
146 if (!pvideo_device) {
147 SAY("ERROR: pvideo_device is NULL.\n");
148 return -EFAULT;
149 }
150 peasycap = (struct easycap *)video_get_drvdata(pvideo_device);
151 if (!peasycap) {
152 SAY("ERROR: peasycap is NULL\n");
153 return -EFAULT;
154 }
155 if (!peasycap->pusb_device) {
156 SAM("ERROR: peasycap->pusb_device is NULL\n");
157 return -EFAULT;
158 }
159
160 JOM(16, "peasycap->pusb_device=%p\n", peasycap->pusb_device);
161
162 file->private_data = peasycap;
163 rc = easycap_wakeup_device(peasycap->pusb_device);
164 if (rc) {
165 SAM("ERROR: wakeup_device() rc = %i\n", rc);
166 if (-ENODEV == rc)
167 SAM("ERROR: wakeup_device() returned -ENODEV\n");
168 else
169 SAM("ERROR: wakeup_device() rc = %i\n", rc);
170 return rc;
171 }
172 JOM(8, "wakeup_device() OK\n");
173 peasycap->input = 0;
174 rc = reset(peasycap);
175 if (rc) {
176 SAM("ERROR: reset() rc = %i\n", rc);
177 return -EFAULT;
178 }
179 return 0;
180}
181
182/*****************************************************************************/
183/*---------------------------------------------------------------------------*/
184/*
185 * RESET THE HARDWARE TO ITS REFERENCE STATE.
186 *
187 * THIS ROUTINE MAY BE CALLED REPEATEDLY IF easycap_complete() DETECTS
188 * A BAD VIDEO FRAME SIZE.
189*/
190/*---------------------------------------------------------------------------*/
191static int reset(struct easycap *peasycap)
192{
193 struct easycap_standard const *peasycap_standard;
194 int fmtidx, input, rate;
195 bool ntsc, other;
196 int rc;
197
198 if (!peasycap) {
199 SAY("ERROR: peasycap is NULL\n");
200 return -EFAULT;
201 }
202 input = peasycap->input;
203
204/*---------------------------------------------------------------------------*/
205/*
206 * IF THE SAA7113H HAS ALREADY ACQUIRED SYNC, USE ITS HARDWARE-DETECTED
207 * FIELD FREQUENCY TO DISTINGUISH NTSC FROM PAL. THIS IS ESSENTIAL FOR
208 * gstreamer AND OTHER USERSPACE PROGRAMS WHICH MAY NOT ATTEMPT TO INITIATE
209 * A SWITCH BETWEEN PAL AND NTSC.
210 *
211 * FUNCTION ready_saa() MAY REQUIRE A SUBSTANTIAL FRACTION OF A SECOND TO
212 * COMPLETE, SO SHOULD NOT BE INVOKED WITHOUT GOOD REASON.
213*/
214/*---------------------------------------------------------------------------*/
215 other = false;
216 JOM(8, "peasycap->ntsc=%d\n", peasycap->ntsc);
217
218 rate = ready_saa(peasycap->pusb_device);
219 if (rate < 0) {
220 JOM(8, "not ready to capture after %i ms ...\n", PATIENCE);
221 ntsc = !peasycap->ntsc;
222 JOM(8, "... trying %s ..\n", ntsc ? "NTSC" : "PAL");
223 rc = setup_stk(peasycap->pusb_device, ntsc);
224 if (rc) {
225 SAM("ERROR: setup_stk() rc = %i\n", rc);
226 return -EFAULT;
227 }
228 rc = setup_saa(peasycap->pusb_device, ntsc);
229 if (rc) {
230 SAM("ERROR: setup_saa() rc = %i\n", rc);
231 return -EFAULT;
232 }
233
234 rate = ready_saa(peasycap->pusb_device);
235 if (rate < 0) {
236 JOM(8, "not ready to capture after %i ms\n", PATIENCE);
237 JOM(8, "... saa register 0x1F has 0x%02X\n",
238 read_saa(peasycap->pusb_device, 0x1F));
239 ntsc = peasycap->ntsc;
240 } else {
241 JOM(8, "... success at second try: %i=rate\n", rate);
242 ntsc = (0 < (rate/2)) ? true : false ;
243 other = true;
244 }
245 } else {
246 JOM(8, "... success at first try: %i=rate\n", rate);
247 ntsc = (0 < rate/2) ? true : false ;
248 }
249 JOM(8, "ntsc=%d\n", ntsc);
250/*---------------------------------------------------------------------------*/
251
252 rc = setup_stk(peasycap->pusb_device, ntsc);
253 if (rc) {
254 SAM("ERROR: setup_stk() rc = %i\n", rc);
255 return -EFAULT;
256 }
257 rc = setup_saa(peasycap->pusb_device, ntsc);
258 if (rc) {
259 SAM("ERROR: setup_saa() rc = %i\n", rc);
260 return -EFAULT;
261 }
262
263 memset(peasycap->merit, 0, sizeof(peasycap->merit));
264
265 peasycap->video_eof = 0;
266 peasycap->audio_eof = 0;
267/*---------------------------------------------------------------------------*/
268/*
269 * RESTORE INPUT AND FORCE REFRESH OF STANDARD, FORMAT, ETC.
270 *
271 * WHILE THIS PROCEDURE IS IN PROGRESS, SOME IOCTL COMMANDS WILL RETURN -EBUSY.
272*/
273/*---------------------------------------------------------------------------*/
274 peasycap->input = -8192;
275 peasycap->standard_offset = -8192;
276 fmtidx = ntsc ? NTSC_M : PAL_BGHIN;
277 if (other) {
278 peasycap_standard = &easycap_standard[0];
279 while (0xFFFF != peasycap_standard->mask) {
280 if (fmtidx == peasycap_standard->v4l2_standard.index) {
281 peasycap->inputset[input].standard_offset =
282 peasycap_standard - easycap_standard;
283 break;
284 }
285 peasycap_standard++;
286 }
287 if (0xFFFF == peasycap_standard->mask) {
288 SAM("ERROR: standard not found\n");
289 return -EINVAL;
290 }
291 JOM(8, "%i=peasycap->inputset[%i].standard_offset\n",
292 peasycap->inputset[input].standard_offset, input);
293 }
294 peasycap->format_offset = -8192;
295 peasycap->brightness = -8192;
296 peasycap->contrast = -8192;
297 peasycap->saturation = -8192;
298 peasycap->hue = -8192;
299
300 rc = easycap_newinput(peasycap, input);
301
302 if (rc) {
303 SAM("ERROR: newinput(.,%i) rc = %i\n", rc, input);
304 return -EFAULT;
305 }
306 JOM(4, "restored input, standard and format\n");
307
308 JOM(8, "true=peasycap->ntsc %d\n", peasycap->ntsc);
309
310 if (0 > peasycap->input) {
311 SAM("MISTAKE: %i=peasycap->input\n", peasycap->input);
312 return -ENOENT;
313 }
314 if (0 > peasycap->standard_offset) {
315 SAM("MISTAKE: %i=peasycap->standard_offset\n",
316 peasycap->standard_offset);
317 return -ENOENT;
318 }
319 if (0 > peasycap->format_offset) {
320 SAM("MISTAKE: %i=peasycap->format_offset\n",
321 peasycap->format_offset);
322 return -ENOENT;
323 }
324 if (0 > peasycap->brightness) {
325 SAM("MISTAKE: %i=peasycap->brightness\n",
326 peasycap->brightness);
327 return -ENOENT;
328 }
329 if (0 > peasycap->contrast) {
330 SAM("MISTAKE: %i=peasycap->contrast\n", peasycap->contrast);
331 return -ENOENT;
332 }
333 if (0 > peasycap->saturation) {
334 SAM("MISTAKE: %i=peasycap->saturation\n",
335 peasycap->saturation);
336 return -ENOENT;
337 }
338 if (0 > peasycap->hue) {
339 SAM("MISTAKE: %i=peasycap->hue\n", peasycap->hue);
340 return -ENOENT;
341 }
342 return 0;
343}
344/*****************************************************************************/
345/*---------------------------------------------------------------------------*/
346/*
347 * IF THE REQUESTED INPUT IS THE SAME AS THE EXISTING INPUT, DO NOTHING.
348 * OTHERWISE:
349 * KILL URBS, CLEAR FIELD AND FRAME BUFFERS AND RESET THEIR
350 * _read AND _fill POINTERS.
351 * SELECT THE NEW INPUT.
352 * ADJUST THE STANDARD, FORMAT, BRIGHTNESS, CONTRAST, SATURATION AND HUE
353 * ON THE BASIS OF INFORMATION IN STRUCTURE easycap.inputset[input].
354 * RESUBMIT THE URBS IF STREAMING WAS ALREADY IN PROGRESS.
355 *
356 * NOTE:
357 * THIS ROUTINE MAY BE CALLED FREQUENTLY BY ZONEMINDER VIA IOCTL,
358 * SO IT SHOULD WRITE ONLY SPARINGLY TO THE LOGFILE.
359*/
360/*---------------------------------------------------------------------------*/
361int easycap_newinput(struct easycap *peasycap, int input)
362{
363 int rc, k, m, mood, off;
364 int inputnow, video_idlenow, audio_idlenow;
365 bool resubmit;
366
367 if (!peasycap) {
368 SAY("ERROR: peasycap is NULL\n");
369 return -EFAULT;
370 }
371 JOM(8, "%i=input sought\n", input);
372
373 if (0 > input && INPUT_MANY <= input)
374 return -ENOENT;
375 inputnow = peasycap->input;
376 if (input == inputnow)
377 return 0;
378/*---------------------------------------------------------------------------*/
379/*
380 * IF STREAMING IS IN PROGRESS THE URBS ARE KILLED AT THIS
381 * STAGE AND WILL BE RESUBMITTED PRIOR TO EXIT FROM THE ROUTINE.
382 * IF NO STREAMING IS IN PROGRESS NO URBS WILL BE SUBMITTED BY THE
383 * ROUTINE.
384*/
385/*---------------------------------------------------------------------------*/
386 video_idlenow = peasycap->video_idle;
387 audio_idlenow = peasycap->audio_idle;
388
389 peasycap->video_idle = 1;
390 peasycap->audio_idle = 1;
391 if (peasycap->video_isoc_streaming) {
392 resubmit = true;
393 easycap_video_kill_urbs(peasycap);
394 } else {
395 resubmit = false;
396 }
397/*---------------------------------------------------------------------------*/
398 if (!peasycap->pusb_device) {
399 SAM("ERROR: peasycap->pusb_device is NULL\n");
400 return -ENODEV;
401 }
402 rc = usb_set_interface(peasycap->pusb_device,
403 peasycap->video_interface,
404 peasycap->video_altsetting_off);
405 if (rc) {
406 SAM("ERROR: usb_set_interface() rc = %i\n", rc);
407 return -EFAULT;
408 }
409 rc = stop_100(peasycap->pusb_device);
410 if (rc) {
411 SAM("ERROR: stop_100() rc = %i\n", rc);
412 return -EFAULT;
413 }
414 for (k = 0; k < FIELD_BUFFER_MANY; k++) {
415 for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++)
416 memset(peasycap->field_buffer[k][m].pgo, 0, PAGE_SIZE);
417 }
418 for (k = 0; k < FRAME_BUFFER_MANY; k++) {
419 for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++)
420 memset(peasycap->frame_buffer[k][m].pgo, 0, PAGE_SIZE);
421 }
422 peasycap->field_page = 0;
423 peasycap->field_read = 0;
424 peasycap->field_fill = 0;
425
426 peasycap->frame_read = 0;
427 peasycap->frame_fill = 0;
428 for (k = 0; k < peasycap->input; k++) {
429 (peasycap->frame_fill)++;
430 if (peasycap->frame_buffer_many <= peasycap->frame_fill)
431 peasycap->frame_fill = 0;
432 }
433 peasycap->input = input;
434 select_input(peasycap->pusb_device, peasycap->input, 9);
435/*---------------------------------------------------------------------------*/
436 if (input == peasycap->inputset[input].input) {
437 off = peasycap->inputset[input].standard_offset;
438 if (off != peasycap->standard_offset) {
439 rc = adjust_standard(peasycap,
440 easycap_standard[off].v4l2_standard.id);
441 if (rc) {
442 SAM("ERROR: adjust_standard() rc = %i\n", rc);
443 return -EFAULT;
444 }
445 JOM(8, "%i=peasycap->standard_offset\n",
446 peasycap->standard_offset);
447 } else {
448 JOM(8, "%i=peasycap->standard_offset unchanged\n",
449 peasycap->standard_offset);
450 }
451 off = peasycap->inputset[input].format_offset;
452 if (off != peasycap->format_offset) {
453 struct v4l2_pix_format *pix =
454 &easycap_format[off].v4l2_format.fmt.pix;
455 rc = adjust_format(peasycap,
456 pix->width, pix->height,
457 pix->pixelformat, pix->field, false);
458 if (0 > rc) {
459 SAM("ERROR: adjust_format() rc = %i\n", rc);
460 return -EFAULT;
461 }
462 JOM(8, "%i=peasycap->format_offset\n",
463 peasycap->format_offset);
464 } else {
465 JOM(8, "%i=peasycap->format_offset unchanged\n",
466 peasycap->format_offset);
467 }
468 mood = peasycap->inputset[input].brightness;
469 if (mood != peasycap->brightness) {
470 rc = adjust_brightness(peasycap, mood);
471 if (rc) {
472 SAM("ERROR: adjust_brightness rc = %i\n", rc);
473 return -EFAULT;
474 }
475 JOM(8, "%i=peasycap->brightness\n",
476 peasycap->brightness);
477 }
478 mood = peasycap->inputset[input].contrast;
479 if (mood != peasycap->contrast) {
480 rc = adjust_contrast(peasycap, mood);
481 if (rc) {
482 SAM("ERROR: adjust_contrast rc = %i\n", rc);
483 return -EFAULT;
484 }
485 JOM(8, "%i=peasycap->contrast\n", peasycap->contrast);
486 }
487 mood = peasycap->inputset[input].saturation;
488 if (mood != peasycap->saturation) {
489 rc = adjust_saturation(peasycap, mood);
490 if (rc) {
491 SAM("ERROR: adjust_saturation rc = %i\n", rc);
492 return -EFAULT;
493 }
494 JOM(8, "%i=peasycap->saturation\n",
495 peasycap->saturation);
496 }
497 mood = peasycap->inputset[input].hue;
498 if (mood != peasycap->hue) {
499 rc = adjust_hue(peasycap, mood);
500 if (rc) {
501 SAM("ERROR: adjust_hue rc = %i\n", rc);
502 return -EFAULT;
503 }
504 JOM(8, "%i=peasycap->hue\n", peasycap->hue);
505 }
506 } else {
507 SAM("MISTAKE: easycap.inputset[%i] unpopulated\n", input);
508 return -ENOENT;
509 }
510/*---------------------------------------------------------------------------*/
511 if (!peasycap->pusb_device) {
512 SAM("ERROR: peasycap->pusb_device is NULL\n");
513 return -ENODEV;
514 }
515 rc = usb_set_interface(peasycap->pusb_device,
516 peasycap->video_interface,
517 peasycap->video_altsetting_on);
518 if (rc) {
519 SAM("ERROR: usb_set_interface() rc = %i\n", rc);
520 return -EFAULT;
521 }
522 rc = start_100(peasycap->pusb_device);
523 if (rc) {
524 SAM("ERROR: start_100() rc = %i\n", rc);
525 return -EFAULT;
526 }
527 if (resubmit)
528 easycap_video_submit_urbs(peasycap);
529
530 peasycap->video_isoc_sequence = VIDEO_ISOC_BUFFER_MANY - 1;
531 peasycap->video_idle = video_idlenow;
532 peasycap->audio_idle = audio_idlenow;
533 peasycap->video_junk = 0;
534
535 return 0;
536}
537/*****************************************************************************/
538int easycap_video_submit_urbs(struct easycap *peasycap)
539{
540 struct data_urb *pdata_urb;
541 struct urb *purb;
542 struct list_head *plist_head;
543 int j, isbad, nospc, m, rc;
544 int isbuf;
545
546 if (!peasycap) {
547 SAY("ERROR: peasycap is NULL\n");
548 return -EFAULT;
549 }
550
551 if (!peasycap->purb_video_head) {
552 SAY("ERROR: peasycap->urb_video_head uninitialized\n");
553 return -EFAULT;
554 }
555 if (!peasycap->pusb_device) {
556 SAY("ERROR: peasycap->pusb_device is NULL\n");
557 return -ENODEV;
558 }
559 if (!peasycap->video_isoc_streaming) {
560 JOM(4, "submission of all video urbs\n");
561 isbad = 0; nospc = 0; m = 0;
562 list_for_each(plist_head, (peasycap->purb_video_head)) {
563 pdata_urb = list_entry(plist_head,
564 struct data_urb, list_head);
565 if (pdata_urb && pdata_urb->purb) {
566 purb = pdata_urb->purb;
567 isbuf = pdata_urb->isbuf;
568 purb->interval = 1;
569 purb->dev = peasycap->pusb_device;
570 purb->pipe =
571 usb_rcvisocpipe(peasycap->pusb_device,
572 peasycap->video_endpointnumber);
573 purb->transfer_flags = URB_ISO_ASAP;
574 purb->transfer_buffer =
575 peasycap->video_isoc_buffer[isbuf].pgo;
576 purb->transfer_buffer_length =
577 peasycap->video_isoc_buffer_size;
578 purb->complete = easycap_complete;
579 purb->context = peasycap;
580 purb->start_frame = 0;
581 purb->number_of_packets =
582 peasycap->video_isoc_framesperdesc;
583
584 for (j = 0; j < peasycap->video_isoc_framesperdesc; j++) {
585 purb->iso_frame_desc[j]. offset =
586 j * peasycap->video_isoc_maxframesize;
587 purb->iso_frame_desc[j]. length =
588 peasycap->video_isoc_maxframesize;
589 }
590
591 rc = usb_submit_urb(purb, GFP_KERNEL);
592 if (rc) {
593 isbad++;
594 SAM("ERROR: usb_submit_urb() failed "
595 "for urb with rc:-%s\n",
596 strerror(rc));
597 if (rc == -ENOSPC)
598 nospc++;
599 } else {
600 m++;
601 }
602 } else {
603 isbad++;
604 }
605 }
606 if (nospc) {
607 SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc);
608 SAM("..... possibly inadequate USB bandwidth\n");
609 peasycap->video_eof = 1;
610 }
611
612 if (isbad)
613 easycap_video_kill_urbs(peasycap);
614 else
615 peasycap->video_isoc_streaming = 1;
616 } else {
617 JOM(4, "already streaming video urbs\n");
618 }
619 return 0;
620}
621/*****************************************************************************/
622int easycap_audio_kill_urbs(struct easycap *peasycap)
623{
624 int m;
625 struct list_head *plist_head;
626 struct data_urb *pdata_urb;
627
628 if (!peasycap->audio_isoc_streaming)
629 return 0;
630
631 if (!peasycap->purb_audio_head) {
632 SAM("ERROR: peasycap->purb_audio_head is NULL\n");
633 return -EFAULT;
634 }
635
636 peasycap->audio_isoc_streaming = 0;
637 m = 0;
638 list_for_each(plist_head, peasycap->purb_audio_head) {
639 pdata_urb = list_entry(plist_head, struct data_urb, list_head);
640 if (pdata_urb && pdata_urb->purb) {
641 usb_kill_urb(pdata_urb->purb);
642 m++;
643 }
644 }
645
646 JOM(4, "%i audio urbs killed\n", m);
647
648 return 0;
649}
650int easycap_video_kill_urbs(struct easycap *peasycap)
651{
652 int m;
653 struct list_head *plist_head;
654 struct data_urb *pdata_urb;
655
656 if (!peasycap->video_isoc_streaming)
657 return 0;
658
659 if (!peasycap->purb_video_head) {
660 SAM("ERROR: peasycap->purb_video_head is NULL\n");
661 return -EFAULT;
662 }
663
664 peasycap->video_isoc_streaming = 0;
665 JOM(4, "killing video urbs\n");
666 m = 0;
667 list_for_each(plist_head, (peasycap->purb_video_head)) {
668 pdata_urb = list_entry(plist_head, struct data_urb, list_head);
669 if (pdata_urb && pdata_urb->purb) {
670 usb_kill_urb(pdata_urb->purb);
671 m++;
672 }
673 }
674 JOM(4, "%i video urbs killed\n", m);
675
676 return 0;
677}
678/****************************************************************************/
679/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
680/*--------------------------------------------------------------------------*/
681static int easycap_open_noinode(struct file *file)
682{
683 return easycap_open(NULL, file);
684}
685
686static int videodev_release(struct video_device *pvideo_device)
687{
688 struct easycap *peasycap;
689
690 peasycap = video_get_drvdata(pvideo_device);
691 if (!peasycap) {
692 SAY("ERROR: peasycap is NULL\n");
693 SAY("ending unsuccessfully\n");
694 return -EFAULT;
695 }
696 if (easycap_video_kill_urbs(peasycap)) {
697 SAM("ERROR: easycap_video_kill_urbs() failed\n");
698 return -EFAULT;
699 }
700 JOM(4, "ending successfully\n");
701 return 0;
702}
703
704/*****************************************************************************/
705static unsigned int easycap_poll(struct file *file, poll_table *wait)
706{
707 struct easycap *peasycap;
708 int rc, kd;
709
710 JOT(8, "\n");
711
712 if (NULL == ((poll_table *)wait))
713 JOT(8, "WARNING: poll table pointer is NULL ... continuing\n");
714 if (!file) {
715 SAY("ERROR: file pointer is NULL\n");
716 return -ERESTARTSYS;
717 }
718 peasycap = file->private_data;
719 if (!peasycap) {
720 SAY("ERROR: peasycap is NULL\n");
721 return -EFAULT;
722 }
723 if (!peasycap->pusb_device) {
724 SAY("ERROR: peasycap->pusb_device is NULL\n");
725 return -EFAULT;
726 }
727/*---------------------------------------------------------------------------*/
728 kd = easycap_isdongle(peasycap);
729 if (0 <= kd && DONGLE_MANY > kd) {
730 if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) {
731 SAY("ERROR: cannot down dongle[%i].mutex_video\n", kd);
732 return -ERESTARTSYS;
733 }
734 JOM(4, "locked dongle[%i].mutex_video\n", kd);
735 /*
736 * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER
737 * peasycap, IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL.
738 * IF NECESSARY, BAIL OUT.
739 */
740 if (kd != easycap_isdongle(peasycap)) {
741 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
742 return -ERESTARTSYS;
743 }
744 if (!file) {
745 SAY("ERROR: file is NULL\n");
746 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
747 return -ERESTARTSYS;
748 }
749 peasycap = file->private_data;
750 if (!peasycap) {
751 SAY("ERROR: peasycap is NULL\n");
752 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
753 return -ERESTARTSYS;
754 }
755 if (!peasycap->pusb_device) {
756 SAM("ERROR: peasycap->pusb_device is NULL\n");
757 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
758 return -ERESTARTSYS;
759 }
760 } else
761 /*
762 * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap
763 * BEFORE THE ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL
764 * HAVE FAILED. BAIL OUT.
765 */
766 return -ERESTARTSYS;
767/*---------------------------------------------------------------------------*/
768 rc = easycap_video_dqbuf(peasycap, 0);
769 peasycap->polled = 1;
770 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
771 if (rc)
772 return POLLERR;
773
774 return POLLIN | POLLRDNORM;
775}
776/*****************************************************************************/
777/*---------------------------------------------------------------------------*/
778/*
779 * IF mode IS NONZERO THIS ROUTINE RETURNS -EAGAIN RATHER THAN BLOCKING.
780 */
781/*---------------------------------------------------------------------------*/
782int easycap_video_dqbuf(struct easycap *peasycap, int mode)
783{
784 int input, ifield, miss, rc;
785
786
787 if (!peasycap) {
788 SAY("ERROR: peasycap is NULL\n");
789 return -EFAULT;
790 }
791 if (!peasycap->pusb_device) {
792 SAY("ERROR: peasycap->pusb_device is NULL\n");
793 return -EFAULT;
794 }
795 ifield = 0;
796 JOM(8, "%i=ifield\n", ifield);
797/*---------------------------------------------------------------------------*/
798/*
799 * CHECK FOR LOST INPUT SIGNAL.
800 *
801 * FOR THE FOUR-CVBS EasyCAP, THIS DOES NOT WORK AS EXPECTED.
802 * IF INPUT 0 IS PRESENT AND SYNC ACQUIRED, UNPLUGGING INPUT 4 DOES NOT
803 * RESULT IN SETTING BIT 0x40 ON REGISTER 0x1F, PRESUMABLY BECAUSE THERE
804 * IS FLYWHEELING ON INPUT 0. THE UPSHOT IS:
805 *
806 * INPUT 0 PLUGGED, INPUT 4 PLUGGED => SCREEN 0 OK, SCREEN 4 OK
807 * INPUT 0 PLUGGED, INPUT 4 UNPLUGGED => SCREEN 0 OK, SCREEN 4 BLACK
808 * INPUT 0 UNPLUGGED, INPUT 4 PLUGGED => SCREEN 0 BARS, SCREEN 4 OK
809 * INPUT 0 UNPLUGGED, INPUT 4 UNPLUGGED => SCREEN 0 BARS, SCREEN 4 BARS
810*/
811/*---------------------------------------------------------------------------*/
812 input = peasycap->input;
813 if (0 <= input && INPUT_MANY > input) {
814 rc = read_saa(peasycap->pusb_device, 0x1F);
815 if (0 <= rc) {
816 if (rc & 0x40)
817 peasycap->lost[input] += 1;
818 else
819 peasycap->lost[input] -= 2;
820
821 if (0 > peasycap->lost[input])
822 peasycap->lost[input] = 0;
823 else if ((2 * VIDEO_LOST_TOLERATE) < peasycap->lost[input])
824 peasycap->lost[input] = (2 * VIDEO_LOST_TOLERATE);
825 }
826 }
827/*---------------------------------------------------------------------------*/
828/*
829 * WAIT FOR FIELD ifield (0 => TOP, 1 => BOTTOM)
830 */
831/*---------------------------------------------------------------------------*/
832 miss = 0;
833 while ((peasycap->field_read == peasycap->field_fill) ||
834 (0 != (0xFF00 & peasycap->field_buffer
835 [peasycap->field_read][0].kount)) ||
836 (ifield != (0x00FF & peasycap->field_buffer
837 [peasycap->field_read][0].kount))) {
838 if (mode)
839 return -EAGAIN;
840
841 JOM(8, "first wait on wq_video, %i=field_read %i=field_fill\n",
842 peasycap->field_read, peasycap->field_fill);
843
844 if (0 != (wait_event_interruptible(peasycap->wq_video,
845 (peasycap->video_idle || peasycap->video_eof ||
846 ((peasycap->field_read != peasycap->field_fill) &&
847 (0 == (0xFF00 & peasycap->field_buffer[peasycap->field_read][0].kount)) &&
848 (ifield == (0x00FF & peasycap->field_buffer[peasycap->field_read][0].kount))))))) {
849 SAM("aborted by signal\n");
850 return -EIO;
851 }
852 if (peasycap->video_idle) {
853 JOM(8, "%i=peasycap->video_idle returning -EAGAIN\n",
854 peasycap->video_idle);
855 return -EAGAIN;
856 }
857 if (peasycap->video_eof) {
858 JOM(8, "%i=peasycap->video_eof\n", peasycap->video_eof);
859 #if defined(PERSEVERE)
860 if (1 == peasycap->status) {
861 JOM(8, "persevering ...\n");
862 peasycap->video_eof = 0;
863 peasycap->audio_eof = 0;
864 if (0 != reset(peasycap)) {
865 JOM(8, " ... failed returning -EIO\n");
866 peasycap->video_eof = 1;
867 peasycap->audio_eof = 1;
868 easycap_video_kill_urbs(peasycap);
869 return -EIO;
870 }
871 peasycap->status = 0;
872 JOM(8, " ... OK returning -EAGAIN\n");
873 return -EAGAIN;
874 }
875 #endif /*PERSEVERE*/
876 peasycap->video_eof = 1;
877 peasycap->audio_eof = 1;
878 easycap_video_kill_urbs(peasycap);
879 JOM(8, "returning -EIO\n");
880 return -EIO;
881 }
882 miss++;
883 }
884 JOM(8, "first awakening on wq_video after %i waits\n", miss);
885
886 rc = field2frame(peasycap);
887 if (rc)
888 SAM("ERROR: field2frame() rc = %i\n", rc);
889/*---------------------------------------------------------------------------*/
890/*
891 * WAIT FOR THE OTHER FIELD
892 */
893/*---------------------------------------------------------------------------*/
894 if (ifield)
895 ifield = 0;
896 else
897 ifield = 1;
898 miss = 0;
899 while ((peasycap->field_read == peasycap->field_fill) ||
900 (0 != (0xFF00 & peasycap->field_buffer[peasycap->field_read][0].kount)) ||
901 (ifield != (0x00FF & peasycap->field_buffer[peasycap->field_read][0].kount))) {
902 if (mode)
903 return -EAGAIN;
904
905 JOM(8, "second wait on wq_video %i=field_read %i=field_fill\n",
906 peasycap->field_read, peasycap->field_fill);
907 if (0 != (wait_event_interruptible(peasycap->wq_video,
908 (peasycap->video_idle || peasycap->video_eof ||
909 ((peasycap->field_read != peasycap->field_fill) &&
910 (0 == (0xFF00 & peasycap->field_buffer[peasycap->field_read][0].kount)) &&
911 (ifield == (0x00FF & peasycap->field_buffer[peasycap->field_read][0].kount))))))) {
912 SAM("aborted by signal\n");
913 return -EIO;
914 }
915 if (peasycap->video_idle) {
916 JOM(8, "%i=peasycap->video_idle returning -EAGAIN\n",
917 peasycap->video_idle);
918 return -EAGAIN;
919 }
920 if (peasycap->video_eof) {
921 JOM(8, "%i=peasycap->video_eof\n", peasycap->video_eof);
922#if defined(PERSEVERE)
923 if (1 == peasycap->status) {
924 JOM(8, "persevering ...\n");
925 peasycap->video_eof = 0;
926 peasycap->audio_eof = 0;
927 if (0 != reset(peasycap)) {
928 JOM(8, " ... failed returning -EIO\n");
929 peasycap->video_eof = 1;
930 peasycap->audio_eof = 1;
931 easycap_video_kill_urbs(peasycap);
932 return -EIO;
933 }
934 peasycap->status = 0;
935 JOM(8, " ... OK ... returning -EAGAIN\n");
936 return -EAGAIN;
937 }
938#endif /*PERSEVERE*/
939 peasycap->video_eof = 1;
940 peasycap->audio_eof = 1;
941 easycap_video_kill_urbs(peasycap);
942 JOM(8, "returning -EIO\n");
943 return -EIO;
944 }
945 miss++;
946 }
947 JOM(8, "second awakening on wq_video after %i waits\n", miss);
948
949 rc = field2frame(peasycap);
950 if (rc)
951 SAM("ERROR: field2frame() rc = %i\n", rc);
952/*---------------------------------------------------------------------------*/
953/*
954 * WASTE THIS FRAME
955*/
956/*---------------------------------------------------------------------------*/
957 if (peasycap->skip) {
958 peasycap->skipped++;
959 if (peasycap->skip != peasycap->skipped)
960 return peasycap->skip - peasycap->skipped;
961 else
962 peasycap->skipped = 0;
963 }
964/*---------------------------------------------------------------------------*/
965 peasycap->frame_read = peasycap->frame_fill;
966 peasycap->queued[peasycap->frame_read] = 0;
967 peasycap->done[peasycap->frame_read] = V4L2_BUF_FLAG_DONE;
968
969 peasycap->frame_fill++;
970 if (peasycap->frame_buffer_many <= peasycap->frame_fill)
971 peasycap->frame_fill = 0;
972
973 if (0x01 & easycap_standard[peasycap->standard_offset].mask)
974 peasycap->frame_buffer[peasycap->frame_read][0].kount =
975 V4L2_FIELD_TOP;
976 else
977 peasycap->frame_buffer[peasycap->frame_read][0].kount =
978 V4L2_FIELD_BOTTOM;
979
980
981 JOM(8, "setting: %i=peasycap->frame_read\n", peasycap->frame_read);
982 JOM(8, "bumped to: %i=peasycap->frame_fill\n", peasycap->frame_fill);
983
984 return 0;
985}
986/*****************************************************************************/
987/*---------------------------------------------------------------------------*/
988/*
989 * BY DEFINITION, odd IS true FOR THE FIELD OCCUPYING LINES 1,3,5,...,479
990 * odd IS false FOR THE FIELD OCCUPYING LINES 0,2,4,...,478
991 *
992 * WHEN BOOLEAN PARAMETER decimatepixel IS true, ONLY THE FIELD FOR WHICH
993 * odd==false IS TRANSFERRED TO THE FRAME BUFFER.
994 *
995 */
996/*---------------------------------------------------------------------------*/
997static int field2frame(struct easycap *peasycap)
998{
999
1000 void *pex, *pad;
1001 int kex, kad, mex, mad, rex, rad, rad2;
1002 int c2, c3, w2, w3, cz, wz;
1003 int rc, bytesperpixel, multiplier;
1004 int much, more, over, rump, caches, input;
1005 u8 mask, margin;
1006 bool odd, isuy, decimatepixel, badinput;
1007
1008 if (!peasycap) {
1009 SAY("ERROR: peasycap is NULL\n");
1010 return -EFAULT;
1011 }
1012
1013 badinput = false;
1014 input = 0x07 & peasycap->field_buffer[peasycap->field_read][0].input;
1015
1016 JOM(8, "===== parity %i, input 0x%02X, field buffer %i --> "
1017 "frame buffer %i\n",
1018 peasycap->field_buffer[peasycap->field_read][0].kount,
1019 peasycap->field_buffer[peasycap->field_read][0].input,
1020 peasycap->field_read, peasycap->frame_fill);
1021 JOM(8, "===== %i=bytesperpixel\n", peasycap->bytesperpixel);
1022
1023/*---------------------------------------------------------------------------*/
1024/*
1025 * REJECT OR CLEAN BAD FIELDS
1026 */
1027/*---------------------------------------------------------------------------*/
1028 if (peasycap->field_read == peasycap->field_fill) {
1029 SAM("ERROR: on entry, still filling field buffer %i\n",
1030 peasycap->field_read);
1031 return 0;
1032 }
1033#ifdef EASYCAP_TESTCARD
1034 easycap_testcard(peasycap, peasycap->field_read);
1035#else
1036 if (0 <= input && INPUT_MANY > input) {
1037 if (easycap_bars && VIDEO_LOST_TOLERATE <= peasycap->lost[input])
1038 easycap_testcard(peasycap, peasycap->field_read);
1039 }
1040#endif /*EASYCAP_TESTCARD*/
1041/*---------------------------------------------------------------------------*/
1042
1043 bytesperpixel = peasycap->bytesperpixel;
1044 decimatepixel = peasycap->decimatepixel;
1045
1046 if ((2 != bytesperpixel) &&
1047 (3 != bytesperpixel) &&
1048 (4 != bytesperpixel)) {
1049 SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel);
1050 return -EFAULT;
1051 }
1052 if (decimatepixel)
1053 multiplier = 2;
1054 else
1055 multiplier = 1;
1056
1057 w2 = 2 * multiplier * (peasycap->width);
1058 w3 = bytesperpixel * multiplier * (peasycap->width);
1059 wz = multiplier * (peasycap->height) *
1060 multiplier * (peasycap->width);
1061
1062 kex = peasycap->field_read; mex = 0;
1063 kad = peasycap->frame_fill; mad = 0;
1064
1065 pex = peasycap->field_buffer[kex][0].pgo; rex = PAGE_SIZE;
1066 pad = peasycap->frame_buffer[kad][0].pgo; rad = PAGE_SIZE;
1067 odd = !!(peasycap->field_buffer[kex][0].kount);
1068
1069 if (odd && (!decimatepixel)) {
1070 JOM(8, "initial skipping %4i bytes p.%4i\n",
1071 w3/multiplier, mad);
1072 pad += (w3 / multiplier); rad -= (w3 / multiplier);
1073 }
1074 isuy = true;
1075 mask = 0; rump = 0; caches = 0;
1076
1077 cz = 0;
1078 while (cz < wz) {
1079 /*
1080 * PROCESS ONE LINE OF FRAME AT FULL RESOLUTION:
1081 * READ w2 BYTES FROM FIELD BUFFER,
1082 * WRITE w3 BYTES TO FRAME BUFFER
1083 */
1084 if (!decimatepixel) {
1085 over = w2;
1086 do {
1087 much = over; more = 0;
1088 margin = 0; mask = 0x00;
1089 if (rex < much)
1090 much = rex;
1091 rump = 0;
1092
1093 if (much % 2) {
1094 SAM("MISTAKE: much is odd\n");
1095 return -EFAULT;
1096 }
1097
1098 more = (bytesperpixel *
1099 much) / 2;
1100/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1101 if (1 < bytesperpixel) {
1102 if (rad * 2 < much * bytesperpixel) {
1103 /*
1104 * INJUDICIOUS ALTERATION OF
1105 * THIS STATEMENT BLOCK WILL
1106 * CAUSE BREAKAGE. BEWARE.
1107 */
1108 rad2 = rad + bytesperpixel - 1;
1109 much = ((((2 * rad2)/bytesperpixel)/2) * 2);
1110 rump = ((bytesperpixel * much) / 2) - rad;
1111 more = rad;
1112 }
1113 mask = (u8)rump;
1114 margin = 0;
1115 if (much == rex) {
1116 mask |= 0x04;
1117 if ((mex + 1) < FIELD_BUFFER_SIZE / PAGE_SIZE)
1118 margin = *((u8 *)(peasycap->field_buffer[kex][mex + 1].pgo));
1119 else
1120 mask |= 0x08;
1121 }
1122 } else {
1123 SAM("MISTAKE: %i=bytesperpixel\n",
1124 bytesperpixel);
1125 return -EFAULT;
1126 }
1127 if (rump)
1128 caches++;
1129 if (badinput) {
1130 JOM(8, "ERROR: 0x%02X=->field_buffer"
1131 "[%i][%i].input, "
1132 "0x%02X=(0x08|->input)\n",
1133 peasycap->field_buffer
1134 [kex][mex].input, kex, mex,
1135 (0x08|peasycap->input));
1136 }
1137 rc = redaub(peasycap, pad, pex, much, more,
1138 mask, margin, isuy);
1139 if (0 > rc) {
1140 SAM("ERROR: redaub() failed\n");
1141 return -EFAULT;
1142 }
1143 if (much % 4)
1144 isuy = !isuy;
1145
1146 over -= much; cz += much;
1147 pex += much; rex -= much;
1148 if (!rex) {
1149 mex++;
1150 pex = peasycap->field_buffer[kex][mex].pgo;
1151 rex = PAGE_SIZE;
1152 if (peasycap->field_buffer[kex][mex].input != (0x08|peasycap->input))
1153 badinput = true;
1154 }
1155 pad += more;
1156 rad -= more;
1157 if (!rad) {
1158 mad++;
1159 pad = peasycap->frame_buffer[kad][mad].pgo;
1160 rad = PAGE_SIZE;
1161 if (rump) {
1162 pad += rump;
1163 rad -= rump;
1164 }
1165 }
1166 } while (over);
1167/*---------------------------------------------------------------------------*/
1168/*
1169 * SKIP w3 BYTES IN TARGET FRAME BUFFER,
1170 * UNLESS IT IS THE LAST LINE OF AN ODD FRAME
1171 */
1172/*---------------------------------------------------------------------------*/
1173 if (!odd || (cz != wz)) {
1174 over = w3;
1175 do {
1176 if (!rad) {
1177 mad++;
1178 pad = peasycap->frame_buffer
1179 [kad][mad].pgo;
1180 rad = PAGE_SIZE;
1181 }
1182 more = over;
1183 if (rad < more)
1184 more = rad;
1185 over -= more;
1186 pad += more;
1187 rad -= more;
1188 } while (over);
1189 }
1190/*---------------------------------------------------------------------------*/
1191/*
1192 * PROCESS ONE LINE OF FRAME AT REDUCED RESOLUTION:
1193 * ONLY IF false==odd,
1194 * READ w2 BYTES FROM FIELD BUFFER,
1195 * WRITE w3 / 2 BYTES TO FRAME BUFFER
1196 */
1197/*---------------------------------------------------------------------------*/
1198 } else if (!odd) {
1199 over = w2;
1200 do {
1201 much = over; more = 0; margin = 0; mask = 0x00;
1202 if (rex < much)
1203 much = rex;
1204 rump = 0;
1205
1206 if (much % 2) {
1207 SAM("MISTAKE: much is odd\n");
1208 return -EFAULT;
1209 }
1210
1211 more = (bytesperpixel * much) / 4;
1212/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1213 if (1 < bytesperpixel) {
1214 if (rad * 4 < much * bytesperpixel) {
1215 /*
1216 * INJUDICIOUS ALTERATION OF
1217 * THIS STATEMENT BLOCK
1218 * WILL CAUSE BREAKAGE.
1219 * BEWARE.
1220 */
1221 rad2 = rad + bytesperpixel - 1;
1222 much = ((((2 * rad2) / bytesperpixel) / 2) * 4);
1223 rump = ((bytesperpixel * much) / 4) - rad;
1224 more = rad;
1225 }
1226 mask = (u8)rump;
1227 margin = 0;
1228 if (much == rex) {
1229 mask |= 0x04;
1230 if ((mex + 1) < FIELD_BUFFER_SIZE / PAGE_SIZE)
1231 margin = *((u8 *)(peasycap->field_buffer[kex][mex + 1].pgo));
1232 else
1233 mask |= 0x08;
1234 }
1235/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1236 } else {
1237 SAM("MISTAKE: %i=bytesperpixel\n",
1238 bytesperpixel);
1239 return -EFAULT;
1240 }
1241/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1242 if (rump)
1243 caches++;
1244
1245 if (badinput) {
1246 JOM(8, "ERROR: 0x%02X=->field_buffer"
1247 "[%i][%i].input, "
1248 "0x%02X=(0x08|->input)\n",
1249 peasycap->field_buffer
1250 [kex][mex].input, kex, mex,
1251 (0x08|peasycap->input));
1252 }
1253 rc = redaub(peasycap, pad, pex, much, more,
1254 mask, margin, isuy);
1255 if (0 > rc) {
1256 SAM("ERROR: redaub() failed\n");
1257 return -EFAULT;
1258 }
1259 over -= much; cz += much;
1260 pex += much; rex -= much;
1261 if (!rex) {
1262 mex++;
1263 pex = peasycap->field_buffer[kex][mex].pgo;
1264 rex = PAGE_SIZE;
1265 if (peasycap->field_buffer[kex][mex].input !=
1266 (0x08|peasycap->input))
1267 badinput = true;
1268 }
1269 pad += more;
1270 rad -= more;
1271 if (!rad) {
1272 mad++;
1273 pad = peasycap->frame_buffer[kad][mad].pgo;
1274 rad = PAGE_SIZE;
1275 if (rump) {
1276 pad += rump;
1277 rad -= rump;
1278 }
1279 }
1280 } while (over);
1281/*---------------------------------------------------------------------------*/
1282/*
1283 * OTHERWISE JUST
1284 * READ w2 BYTES FROM FIELD BUFFER AND DISCARD THEM
1285 */
1286/*---------------------------------------------------------------------------*/
1287 } else {
1288 over = w2;
1289 do {
1290 if (!rex) {
1291 mex++;
1292 pex = peasycap->field_buffer[kex][mex].pgo;
1293 rex = PAGE_SIZE;
1294 if (peasycap->field_buffer[kex][mex].input !=
1295 (0x08|peasycap->input)) {
1296 JOM(8, "ERROR: 0x%02X=->field_buffer"
1297 "[%i][%i].input, "
1298 "0x%02X=(0x08|->input)\n",
1299 peasycap->field_buffer
1300 [kex][mex].input, kex, mex,
1301 (0x08|peasycap->input));
1302 badinput = true;
1303 }
1304 }
1305 much = over;
1306 if (rex < much)
1307 much = rex;
1308 over -= much;
1309 cz += much;
1310 pex += much;
1311 rex -= much;
1312 } while (over);
1313 }
1314 }
1315/*---------------------------------------------------------------------------*/
1316/*
1317 * SANITY CHECKS
1318 */
1319/*---------------------------------------------------------------------------*/
1320 c2 = (mex + 1)*PAGE_SIZE - rex;
1321 if (cz != c2)
1322 SAM("ERROR: discrepancy %i in bytes read\n", c2 - cz);
1323 c3 = (mad + 1)*PAGE_SIZE - rad;
1324
1325 if (!decimatepixel) {
1326 if (bytesperpixel * cz != c3)
1327 SAM("ERROR: discrepancy %i in bytes written\n",
1328 c3 - (bytesperpixel * cz));
1329 } else {
1330 if (!odd) {
1331 if (bytesperpixel *
1332 cz != (4 * c3))
1333 SAM("ERROR: discrepancy %i in bytes written\n",
1334 (2*c3)-(bytesperpixel * cz));
1335 } else {
1336 if (0 != c3)
1337 SAM("ERROR: discrepancy %i "
1338 "in bytes written\n", c3);
1339 }
1340 }
1341 if (rump)
1342 SAM("WORRY: undischarged cache at end of line in frame buffer\n");
1343
1344 JOM(8, "===== field2frame(): %i bytes --> %i bytes (incl skip)\n", c2, c3);
1345 JOM(8, "===== field2frame(): %i=mad %i=rad\n", mad, rad);
1346
1347 if (odd)
1348 JOM(8, "+++++ field2frame(): frame buffer %i is full\n", kad);
1349
1350 if (peasycap->field_read == peasycap->field_fill)
1351 SAM("WARNING: on exit, filling field buffer %i\n",
1352 peasycap->field_read);
1353
1354 if (caches)
1355 JOM(8, "%i=caches\n", caches);
1356 return 0;
1357}
1358/*---------------------------------------------------------------------------*/
1359/*
1360 * DECIMATION AND COLOURSPACE CONVERSION.
1361 *
1362 * THIS ROUTINE REQUIRES THAT ALL THE DATA TO BE READ RESIDES ON ONE PAGE
1363 * AND THAT ALL THE DATA TO BE WRITTEN RESIDES ON ONE (DIFFERENT) PAGE.
1364 * THE CALLING ROUTINE MUST ENSURE THAT THIS REQUIREMENT IS MET, AND MUST
1365 * ALSO ENSURE THAT much IS EVEN.
1366 *
1367 * much BYTES ARE READ, AT LEAST (bytesperpixel * much)/2 BYTES ARE WRITTEN
1368 * IF THERE IS NO DECIMATION, HALF THIS AMOUNT IF THERE IS DECIMATION.
1369 *
1370 * mask IS ZERO WHEN NO SPECIAL BEHAVIOUR REQUIRED. OTHERWISE IT IS SET THUS:
1371 * 0x03 & mask = number of bytes to be written to cache instead of to
1372 * frame buffer
1373 * 0x04 & mask => use argument margin to set the chrominance for last pixel
1374 * 0x08 & mask => do not set the chrominance for last pixel
1375 *
1376 * YUV to RGB CONVERSION IS (OR SHOULD BE) ITU-R BT 601.
1377 *
1378 * THERE IS A LOT OF CODE REPETITION IN THIS ROUTINE IN ORDER TO AVOID
1379 * INEFFICIENT SWITCHING INSIDE INNER LOOPS. REARRANGING THE LOGIC TO
1380 * REDUCE CODE LENGTH WILL GENERALLY IMPAIR RUNTIME PERFORMANCE. BEWARE.
1381 */
1382/*---------------------------------------------------------------------------*/
1383static int redaub(struct easycap *peasycap,
1384 void *pad, void *pex, int much, int more,
1385 u8 mask, u8 margin, bool isuy)
1386{
1387 static s32 ay[256], bu[256], rv[256], gu[256], gv[256];
1388 u8 *pcache;
1389 u8 r, g, b, y, u, v, c, *p2, *p3, *pz, *pr;
1390 int bytesperpixel;
1391 bool byteswaporder, decimatepixel, last;
1392 int j, rump;
1393 s32 tmp;
1394
1395 if (much % 2) {
1396 SAM("MISTAKE: much is odd\n");
1397 return -EFAULT;
1398 }
1399 bytesperpixel = peasycap->bytesperpixel;
1400 byteswaporder = peasycap->byteswaporder;
1401 decimatepixel = peasycap->decimatepixel;
1402
1403/*---------------------------------------------------------------------------*/
1404 if (!bu[255]) {
1405 for (j = 0; j < 112; j++) {
1406 tmp = (0xFF00 & (453 * j)) >> 8;
1407 bu[j + 128] = tmp; bu[127 - j] = -tmp;
1408 tmp = (0xFF00 & (359 * j)) >> 8;
1409 rv[j + 128] = tmp; rv[127 - j] = -tmp;
1410 tmp = (0xFF00 & (88 * j)) >> 8;
1411 gu[j + 128] = tmp; gu[127 - j] = -tmp;
1412 tmp = (0xFF00 & (183 * j)) >> 8;
1413 gv[j + 128] = tmp; gv[127 - j] = -tmp;
1414 }
1415 for (j = 0; j < 16; j++) {
1416 bu[j] = bu[16]; rv[j] = rv[16];
1417 gu[j] = gu[16]; gv[j] = gv[16];
1418 }
1419 for (j = 240; j < 256; j++) {
1420 bu[j] = bu[239]; rv[j] = rv[239];
1421 gu[j] = gu[239]; gv[j] = gv[239];
1422 }
1423 for (j = 16; j < 236; j++)
1424 ay[j] = j;
1425 for (j = 0; j < 16; j++)
1426 ay[j] = ay[16];
1427 for (j = 236; j < 256; j++)
1428 ay[j] = ay[235];
1429 JOM(8, "lookup tables are prepared\n");
1430 }
1431 pcache = peasycap->pcache;
1432 if (!pcache)
1433 pcache = &peasycap->cache[0];
1434/*---------------------------------------------------------------------------*/
1435/*
1436 * TRANSFER CONTENTS OF CACHE TO THE FRAME BUFFER
1437 */
1438/*---------------------------------------------------------------------------*/
1439 if (!pcache) {
1440 SAM("MISTAKE: pcache is NULL\n");
1441 return -EFAULT;
1442 }
1443
1444 if (pcache != &peasycap->cache[0])
1445 JOM(16, "cache has %i bytes\n", (int)(pcache - &peasycap->cache[0]));
1446 p2 = &peasycap->cache[0];
1447 p3 = (u8 *)pad - (int)(pcache - &peasycap->cache[0]);
1448 while (p2 < pcache) {
1449 *p3++ = *p2; p2++;
1450 }
1451 pcache = &peasycap->cache[0];
1452 if (p3 != pad) {
1453 SAM("MISTAKE: pointer misalignment\n");
1454 return -EFAULT;
1455 }
1456/*---------------------------------------------------------------------------*/
1457 rump = (int)(0x03 & mask);
1458 u = 0; v = 0;
1459 p2 = (u8 *)pex; pz = p2 + much; pr = p3 + more; last = false;
1460 p2++;
1461
1462 if (isuy)
1463 u = *(p2 - 1);
1464 else
1465 v = *(p2 - 1);
1466
1467 if (rump)
1468 JOM(16, "%4i=much %4i=more %i=rump\n", much, more, rump);
1469
1470/*---------------------------------------------------------------------------*/
1471 switch (bytesperpixel) {
1472 case 2: {
1473 if (!decimatepixel) {
1474 memcpy(pad, pex, (size_t)much);
1475 if (!byteswaporder) {
1476 /* UYVY */
1477 return 0;
1478 } else {
1479 /* YUYV */
1480 p3 = (u8 *)pad; pz = p3 + much;
1481 while (pz > p3) {
1482 c = *p3;
1483 *p3 = *(p3 + 1);
1484 *(p3 + 1) = c;
1485 p3 += 2;
1486 }
1487 return 0;
1488 }
1489 } else {
1490 if (!byteswaporder) {
1491 /* UYVY DECIMATED */
1492 p2 = (u8 *)pex; p3 = (u8 *)pad; pz = p2 + much;
1493 while (pz > p2) {
1494 *p3 = *p2;
1495 *(p3 + 1) = *(p2 + 1);
1496 *(p3 + 2) = *(p2 + 2);
1497 *(p3 + 3) = *(p2 + 3);
1498 p3 += 4; p2 += 8;
1499 }
1500 return 0;
1501 } else {
1502 /* YUYV DECIMATED */
1503 p2 = (u8 *)pex; p3 = (u8 *)pad; pz = p2 + much;
1504 while (pz > p2) {
1505 *p3 = *(p2 + 1);
1506 *(p3 + 1) = *p2;
1507 *(p3 + 2) = *(p2 + 3);
1508 *(p3 + 3) = *(p2 + 2);
1509 p3 += 4; p2 += 8;
1510 }
1511 return 0;
1512 }
1513 }
1514 break;
1515 }
1516 case 3:
1517 {
1518 if (!decimatepixel) {
1519 if (!byteswaporder) {
1520 /* RGB */
1521 while (pz > p2) {
1522 if (pr <= (p3 + bytesperpixel))
1523 last = true;
1524 else
1525 last = false;
1526 y = *p2;
1527 if (last && (0x0C & mask)) {
1528 if (0x04 & mask) {
1529 if (isuy)
1530 v = margin;
1531 else
1532 u = margin;
1533 } else
1534 if (0x08 & mask)
1535 ;
1536 } else {
1537 if (isuy)
1538 v = *(p2 + 1);
1539 else
1540 u = *(p2 + 1);
1541 }
1542
1543 tmp = ay[(int)y] + rv[(int)v];
1544 r = (255 < tmp) ? 255 : ((0 > tmp) ?
1545 0 : (u8)tmp);
1546 tmp = ay[(int)y] - gu[(int)u] - gv[(int)v];
1547 g = (255 < tmp) ? 255 : ((0 > tmp) ?
1548 0 : (u8)tmp);
1549 tmp = ay[(int)y] + bu[(int)u];
1550 b = (255 < tmp) ? 255 : ((0 > tmp) ?
1551 0 : (u8)tmp);
1552
1553 if (last && rump) {
1554 pcache = &peasycap->cache[0];
1555 switch (bytesperpixel - rump) {
1556 case 1: {
1557 *p3 = r;
1558 *pcache++ = g;
1559 *pcache++ = b;
1560 break;
1561 }
1562 case 2: {
1563 *p3 = r;
1564 *(p3 + 1) = g;
1565 *pcache++ = b;
1566 break;
1567 }
1568 default: {
1569 SAM("MISTAKE: %i=rump\n",
1570 bytesperpixel - rump);
1571 return -EFAULT;
1572 }
1573 }
1574 } else {
1575 *p3 = r;
1576 *(p3 + 1) = g;
1577 *(p3 + 2) = b;
1578 }
1579 p2 += 2;
1580 if (isuy)
1581 isuy = false;
1582 else
1583 isuy = true;
1584 p3 += bytesperpixel;
1585 }
1586 return 0;
1587 } else {
1588 /* BGR */
1589 while (pz > p2) {
1590 if (pr <= (p3 + bytesperpixel))
1591 last = true;
1592 else
1593 last = false;
1594 y = *p2;
1595 if (last && (0x0C & mask)) {
1596 if (0x04 & mask) {
1597 if (isuy)
1598 v = margin;
1599 else
1600 u = margin;
1601 }
1602 else
1603 if (0x08 & mask)
1604 ;
1605 } else {
1606 if (isuy)
1607 v = *(p2 + 1);
1608 else
1609 u = *(p2 + 1);
1610 }
1611
1612 tmp = ay[(int)y] + rv[(int)v];
1613 r = (255 < tmp) ? 255 : ((0 > tmp) ?
1614 0 : (u8)tmp);
1615 tmp = ay[(int)y] - gu[(int)u] - gv[(int)v];
1616 g = (255 < tmp) ? 255 : ((0 > tmp) ?
1617 0 : (u8)tmp);
1618 tmp = ay[(int)y] + bu[(int)u];
1619 b = (255 < tmp) ? 255 : ((0 > tmp) ?
1620 0 : (u8)tmp);
1621
1622 if (last && rump) {
1623 pcache = &peasycap->cache[0];
1624 switch (bytesperpixel - rump) {
1625 case 1: {
1626 *p3 = b;
1627 *pcache++ = g;
1628 *pcache++ = r;
1629 break;
1630 }
1631 case 2: {
1632 *p3 = b;
1633 *(p3 + 1) = g;
1634 *pcache++ = r;
1635 break;
1636 }
1637 default: {
1638 SAM("MISTAKE: %i=rump\n",
1639 bytesperpixel - rump);
1640 return -EFAULT;
1641 }
1642 }
1643 } else {
1644 *p3 = b;
1645 *(p3 + 1) = g;
1646 *(p3 + 2) = r;
1647 }
1648 p2 += 2;
1649 if (isuy)
1650 isuy = false;
1651 else
1652 isuy = true;
1653 p3 += bytesperpixel;
1654 }
1655 }
1656 return 0;
1657 } else {
1658 if (!byteswaporder) {
1659 /* RGB DECIMATED */
1660 while (pz > p2) {
1661 if (pr <= (p3 + bytesperpixel))
1662 last = true;
1663 else
1664 last = false;
1665 y = *p2;
1666 if (last && (0x0C & mask)) {
1667 if (0x04 & mask) {
1668 if (isuy)
1669 v = margin;
1670 else
1671 u = margin;
1672 } else
1673 if (0x08 & mask)
1674 ;
1675 } else {
1676 if (isuy)
1677 v = *(p2 + 1);
1678 else
1679 u = *(p2 + 1);
1680 }
1681
1682 if (isuy) {
1683 tmp = ay[(int)y] + rv[(int)v];
1684 r = (255 < tmp) ? 255 : ((0 > tmp) ?
1685 0 : (u8)tmp);
1686 tmp = ay[(int)y] - gu[(int)u] -
1687 gv[(int)v];
1688 g = (255 < tmp) ? 255 : ((0 > tmp) ?
1689 0 : (u8)tmp);
1690 tmp = ay[(int)y] + bu[(int)u];
1691 b = (255 < tmp) ? 255 : ((0 > tmp) ?
1692 0 : (u8)tmp);
1693
1694 if (last && rump) {
1695 pcache = &peasycap->cache[0];
1696 switch (bytesperpixel - rump) {
1697 case 1: {
1698 *p3 = r;
1699 *pcache++ = g;
1700 *pcache++ = b;
1701 break;
1702 }
1703 case 2: {
1704 *p3 = r;
1705 *(p3 + 1) = g;
1706 *pcache++ = b;
1707 break;
1708 }
1709 default: {
1710 SAM("MISTAKE: "
1711 "%i=rump\n",
1712 bytesperpixel - rump);
1713 return -EFAULT;
1714 }
1715 }
1716 } else {
1717 *p3 = r;
1718 *(p3 + 1) = g;
1719 *(p3 + 2) = b;
1720 }
1721 isuy = false;
1722 p3 += bytesperpixel;
1723 } else {
1724 isuy = true;
1725 }
1726 p2 += 2;
1727 }
1728 return 0;
1729 } else {
1730 /* BGR DECIMATED */
1731 while (pz > p2) {
1732 if (pr <= (p3 + bytesperpixel))
1733 last = true;
1734 else
1735 last = false;
1736 y = *p2;
1737 if (last && (0x0C & mask)) {
1738 if (0x04 & mask) {
1739 if (isuy)
1740 v = margin;
1741 else
1742 u = margin;
1743 } else
1744 if (0x08 & mask)
1745 ;
1746 } else {
1747 if (isuy)
1748 v = *(p2 + 1);
1749 else
1750 u = *(p2 + 1);
1751 }
1752
1753 if (isuy) {
1754
1755 tmp = ay[(int)y] + rv[(int)v];
1756 r = (255 < tmp) ? 255 : ((0 > tmp) ?
1757 0 : (u8)tmp);
1758 tmp = ay[(int)y] - gu[(int)u] -
1759 gv[(int)v];
1760 g = (255 < tmp) ? 255 : ((0 > tmp) ?
1761 0 : (u8)tmp);
1762 tmp = ay[(int)y] + bu[(int)u];
1763 b = (255 < tmp) ? 255 : ((0 > tmp) ?
1764 0 : (u8)tmp);
1765
1766 if (last && rump) {
1767 pcache = &peasycap->cache[0];
1768 switch (bytesperpixel - rump) {
1769 case 1: {
1770 *p3 = b;
1771 *pcache++ = g;
1772 *pcache++ = r;
1773 break;
1774 }
1775 case 2: {
1776 *p3 = b;
1777 *(p3 + 1) = g;
1778 *pcache++ = r;
1779 break;
1780 }
1781 default: {
1782 SAM("MISTAKE: "
1783 "%i=rump\n",
1784 bytesperpixel - rump);
1785 return -EFAULT;
1786 }
1787 }
1788 } else {
1789 *p3 = b;
1790 *(p3 + 1) = g;
1791 *(p3 + 2) = r;
1792 }
1793 isuy = false;
1794 p3 += bytesperpixel;
1795 }
1796 else
1797 isuy = true;
1798 p2 += 2;
1799 }
1800 return 0;
1801 }
1802 }
1803 break;
1804 }
1805 case 4:
1806 {
1807 if (!decimatepixel) {
1808 if (!byteswaporder) {
1809 /* RGBA */
1810 while (pz > p2) {
1811 if (pr <= (p3 + bytesperpixel))
1812 last = true;
1813 else
1814 last = false;
1815 y = *p2;
1816 if (last && (0x0C & mask)) {
1817 if (0x04 & mask) {
1818 if (isuy)
1819 v = margin;
1820 else
1821 u = margin;
1822 } else
1823 if (0x08 & mask)
1824 ;
1825 } else {
1826 if (isuy)
1827 v = *(p2 + 1);
1828 else
1829 u = *(p2 + 1);
1830 }
1831
1832 tmp = ay[(int)y] + rv[(int)v];
1833 r = (255 < tmp) ? 255 : ((0 > tmp) ?
1834 0 : (u8)tmp);
1835 tmp = ay[(int)y] - gu[(int)u] - gv[(int)v];
1836 g = (255 < tmp) ? 255 : ((0 > tmp) ?
1837 0 : (u8)tmp);
1838 tmp = ay[(int)y] + bu[(int)u];
1839 b = (255 < tmp) ? 255 : ((0 > tmp) ?
1840 0 : (u8)tmp);
1841
1842 if (last && rump) {
1843 pcache = &peasycap->cache[0];
1844 switch (bytesperpixel - rump) {
1845 case 1: {
1846 *p3 = r;
1847 *pcache++ = g;
1848 *pcache++ = b;
1849 *pcache++ = 0;
1850 break;
1851 }
1852 case 2: {
1853 *p3 = r;
1854 *(p3 + 1) = g;
1855 *pcache++ = b;
1856 *pcache++ = 0;
1857 break;
1858 }
1859 case 3: {
1860 *p3 = r;
1861 *(p3 + 1) = g;
1862 *(p3 + 2) = b;
1863 *pcache++ = 0;
1864 break;
1865 }
1866 default: {
1867 SAM("MISTAKE: %i=rump\n",
1868 bytesperpixel - rump);
1869 return -EFAULT;
1870 }
1871 }
1872 } else {
1873 *p3 = r;
1874 *(p3 + 1) = g;
1875 *(p3 + 2) = b;
1876 *(p3 + 3) = 0;
1877 }
1878 p2 += 2;
1879 if (isuy)
1880 isuy = false;
1881 else
1882 isuy = true;
1883 p3 += bytesperpixel;
1884 }
1885 return 0;
1886 } else {
1887 /*
1888 * BGRA
1889 */
1890 while (pz > p2) {
1891 if (pr <= (p3 + bytesperpixel))
1892 last = true;
1893 else
1894 last = false;
1895 y = *p2;
1896 if (last && (0x0C & mask)) {
1897 if (0x04 & mask) {
1898 if (isuy)
1899 v = margin;
1900 else
1901 u = margin;
1902 } else
1903 if (0x08 & mask)
1904 ;
1905 } else {
1906 if (isuy)
1907 v = *(p2 + 1);
1908 else
1909 u = *(p2 + 1);
1910 }
1911
1912 tmp = ay[(int)y] + rv[(int)v];
1913 r = (255 < tmp) ? 255 : ((0 > tmp) ?
1914 0 : (u8)tmp);
1915 tmp = ay[(int)y] - gu[(int)u] - gv[(int)v];
1916 g = (255 < tmp) ? 255 : ((0 > tmp) ?
1917 0 : (u8)tmp);
1918 tmp = ay[(int)y] + bu[(int)u];
1919 b = (255 < tmp) ? 255 : ((0 > tmp) ?
1920 0 : (u8)tmp);
1921
1922 if (last && rump) {
1923 pcache = &peasycap->cache[0];
1924 switch (bytesperpixel - rump) {
1925 case 1: {
1926 *p3 = b;
1927 *pcache++ = g;
1928 *pcache++ = r;
1929 *pcache++ = 0;
1930 break;
1931 }
1932 case 2: {
1933 *p3 = b;
1934 *(p3 + 1) = g;
1935 *pcache++ = r;
1936 *pcache++ = 0;
1937 break;
1938 }
1939 case 3: {
1940 *p3 = b;
1941 *(p3 + 1) = g;
1942 *(p3 + 2) = r;
1943 *pcache++ = 0;
1944 break;
1945 }
1946 default:
1947 SAM("MISTAKE: %i=rump\n",
1948 bytesperpixel - rump);
1949 return -EFAULT;
1950 }
1951 } else {
1952 *p3 = b;
1953 *(p3 + 1) = g;
1954 *(p3 + 2) = r;
1955 *(p3 + 3) = 0;
1956 }
1957 p2 += 2;
1958 if (isuy)
1959 isuy = false;
1960 else
1961 isuy = true;
1962 p3 += bytesperpixel;
1963 }
1964 }
1965 return 0;
1966 } else {
1967 if (!byteswaporder) {
1968 /*
1969 * RGBA DECIMATED
1970 */
1971 while (pz > p2) {
1972 if (pr <= (p3 + bytesperpixel))
1973 last = true;
1974 else
1975 last = false;
1976 y = *p2;
1977 if (last && (0x0C & mask)) {
1978 if (0x04 & mask) {
1979 if (isuy)
1980 v = margin;
1981 else
1982 u = margin;
1983 } else
1984 if (0x08 & mask)
1985 ;
1986 } else {
1987 if (isuy)
1988 v = *(p2 + 1);
1989 else
1990 u = *(p2 + 1);
1991 }
1992
1993 if (isuy) {
1994
1995 tmp = ay[(int)y] + rv[(int)v];
1996 r = (255 < tmp) ? 255 : ((0 > tmp) ?
1997 0 : (u8)tmp);
1998 tmp = ay[(int)y] - gu[(int)u] -
1999 gv[(int)v];
2000 g = (255 < tmp) ? 255 : ((0 > tmp) ?
2001 0 : (u8)tmp);
2002 tmp = ay[(int)y] + bu[(int)u];
2003 b = (255 < tmp) ? 255 : ((0 > tmp) ?
2004 0 : (u8)tmp);
2005
2006 if (last && rump) {
2007 pcache = &peasycap->cache[0];
2008 switch (bytesperpixel - rump) {
2009 case 1: {
2010 *p3 = r;
2011 *pcache++ = g;
2012 *pcache++ = b;
2013 *pcache++ = 0;
2014 break;
2015 }
2016 case 2: {
2017 *p3 = r;
2018 *(p3 + 1) = g;
2019 *pcache++ = b;
2020 *pcache++ = 0;
2021 break;
2022 }
2023 case 3: {
2024 *p3 = r;
2025 *(p3 + 1) = g;
2026 *(p3 + 2) = b;
2027 *pcache++ = 0;
2028 break;
2029 }
2030 default: {
2031 SAM("MISTAKE: "
2032 "%i=rump\n",
2033 bytesperpixel -
2034 rump);
2035 return -EFAULT;
2036 }
2037 }
2038 } else {
2039 *p3 = r;
2040 *(p3 + 1) = g;
2041 *(p3 + 2) = b;
2042 *(p3 + 3) = 0;
2043 }
2044 isuy = false;
2045 p3 += bytesperpixel;
2046 } else
2047 isuy = true;
2048 p2 += 2;
2049 }
2050 return 0;
2051 } else {
2052 /*
2053 * BGRA DECIMATED
2054 */
2055 while (pz > p2) {
2056 if (pr <= (p3 + bytesperpixel))
2057 last = true;
2058 else
2059 last = false;
2060 y = *p2;
2061 if (last && (0x0C & mask)) {
2062 if (0x04 & mask) {
2063 if (isuy)
2064 v = margin;
2065 else
2066 u = margin;
2067 } else
2068 if (0x08 & mask)
2069 ;
2070 } else {
2071 if (isuy)
2072 v = *(p2 + 1);
2073 else
2074 u = *(p2 + 1);
2075 }
2076
2077 if (isuy) {
2078 tmp = ay[(int)y] + rv[(int)v];
2079 r = (255 < tmp) ? 255 : ((0 > tmp) ?
2080 0 : (u8)tmp);
2081 tmp = ay[(int)y] - gu[(int)u] -
2082 gv[(int)v];
2083 g = (255 < tmp) ? 255 : ((0 > tmp) ?
2084 0 : (u8)tmp);
2085 tmp = ay[(int)y] + bu[(int)u];
2086 b = (255 < tmp) ? 255 : ((0 > tmp) ?
2087 0 : (u8)tmp);
2088
2089 if (last && rump) {
2090 pcache = &peasycap->cache[0];
2091 switch (bytesperpixel - rump) {
2092 case 1: {
2093 *p3 = b;
2094 *pcache++ = g;
2095 *pcache++ = r;
2096 *pcache++ = 0;
2097 break;
2098 }
2099 case 2: {
2100 *p3 = b;
2101 *(p3 + 1) = g;
2102 *pcache++ = r;
2103 *pcache++ = 0;
2104 break;
2105 }
2106 case 3: {
2107 *p3 = b;
2108 *(p3 + 1) = g;
2109 *(p3 + 2) = r;
2110 *pcache++ = 0;
2111 break;
2112 }
2113 default: {
2114 SAM("MISTAKE: "
2115 "%i=rump\n",
2116 bytesperpixel - rump);
2117 return -EFAULT;
2118 }
2119 }
2120 } else {
2121 *p3 = b;
2122 *(p3 + 1) = g;
2123 *(p3 + 2) = r;
2124 *(p3 + 3) = 0;
2125 }
2126 isuy = false;
2127 p3 += bytesperpixel;
2128 } else
2129 isuy = true;
2130 p2 += 2;
2131 }
2132 return 0;
2133 }
2134 }
2135 break;
2136 }
2137 default: {
2138 SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel);
2139 return -EFAULT;
2140 }
2141 }
2142 return 0;
2143}
2144/*****************************************************************************/
2145/*
2146 * SEE CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGES 430-434
2147 */
2148/*****************************************************************************/
2149static void easycap_vma_open(struct vm_area_struct *pvma)
2150{
2151 struct easycap *peasycap;
2152
2153 peasycap = pvma->vm_private_data;
2154 if (!peasycap) {
2155 SAY("ERROR: peasycap is NULL\n");
2156 return;
2157 }
2158 peasycap->vma_many++;
2159 JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many);
2160 return;
2161}
2162/*****************************************************************************/
2163static void easycap_vma_close(struct vm_area_struct *pvma)
2164{
2165 struct easycap *peasycap;
2166
2167 peasycap = pvma->vm_private_data;
2168 if (!peasycap) {
2169 SAY("ERROR: peasycap is NULL\n");
2170 return;
2171 }
2172 peasycap->vma_many--;
2173 JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many);
2174 return;
2175}
2176/*****************************************************************************/
2177static int easycap_vma_fault(struct vm_area_struct *pvma, struct vm_fault *pvmf)
2178{
2179 int k, m, retcode;
2180 void *pbuf;
2181 struct page *page;
2182 struct easycap *peasycap;
2183
2184 retcode = VM_FAULT_NOPAGE;
2185
2186 if (!pvma) {
2187 SAY("pvma is NULL\n");
2188 return retcode;
2189 }
2190 if (!pvmf) {
2191 SAY("pvmf is NULL\n");
2192 return retcode;
2193 }
2194
2195 k = (pvmf->pgoff) / (FRAME_BUFFER_SIZE/PAGE_SIZE);
2196 m = (pvmf->pgoff) % (FRAME_BUFFER_SIZE/PAGE_SIZE);
2197
2198 if (!m)
2199 JOT(4, "%4i=k, %4i=m\n", k, m);
2200 else
2201 JOT(16, "%4i=k, %4i=m\n", k, m);
2202
2203 if ((0 > k) || (FRAME_BUFFER_MANY <= k)) {
2204 SAY("ERROR: buffer index %i out of range\n", k);
2205 return retcode;
2206 }
2207 if ((0 > m) || (FRAME_BUFFER_SIZE/PAGE_SIZE <= m)) {
2208 SAY("ERROR: page number %i out of range\n", m);
2209 return retcode;
2210 }
2211 peasycap = pvma->vm_private_data;
2212 if (!peasycap) {
2213 SAY("ERROR: peasycap is NULL\n");
2214 return retcode;
2215 }
2216/*---------------------------------------------------------------------------*/
2217 pbuf = peasycap->frame_buffer[k][m].pgo;
2218 if (!pbuf) {
2219 SAM("ERROR: pbuf is NULL\n");
2220 return retcode;
2221 }
2222 page = virt_to_page(pbuf);
2223 if (!page) {
2224 SAM("ERROR: page is NULL\n");
2225 return retcode;
2226 }
2227 get_page(page);
2228/*---------------------------------------------------------------------------*/
2229 if (!page) {
2230 SAM("ERROR: page is NULL after get_page(page)\n");
2231 } else {
2232 pvmf->page = page;
2233 retcode = VM_FAULT_MINOR;
2234 }
2235 return retcode;
2236}
2237
2238static const struct vm_operations_struct easycap_vm_ops = {
2239 .open = easycap_vma_open,
2240 .close = easycap_vma_close,
2241 .fault = easycap_vma_fault,
2242};
2243
2244static int easycap_mmap(struct file *file, struct vm_area_struct *pvma)
2245{
2246 JOT(8, "\n");
2247
2248 pvma->vm_ops = &easycap_vm_ops;
2249 pvma->vm_flags |= VM_RESERVED;
2250 if (file)
2251 pvma->vm_private_data = file->private_data;
2252 easycap_vma_open(pvma);
2253 return 0;
2254}
2255/*****************************************************************************/
2256/*---------------------------------------------------------------------------*/
2257/*
2258 * ON COMPLETION OF A VIDEO URB ITS DATA IS COPIED TO THE FIELD BUFFERS
2259 * PROVIDED peasycap->video_idle IS ZERO. REGARDLESS OF THIS BEING TRUE,
2260 * IT IS RESUBMITTED PROVIDED peasycap->video_isoc_streaming IS NOT ZERO.
2261 *
2262 * THIS FUNCTION IS AN INTERRUPT SERVICE ROUTINE AND MUST NOT SLEEP.
2263 *
2264 * INFORMATION ABOUT THE VALIDITY OF THE CONTENTS OF THE FIELD BUFFER ARE
2265 * STORED IN THE TWO-BYTE STATUS PARAMETER
2266 * peasycap->field_buffer[peasycap->field_fill][0].kount
2267 * NOTICE THAT THE INFORMATION IS STORED ONLY WITH PAGE 0 OF THE FIELD BUFFER.
2268 *
2269 * THE LOWER BYTE CONTAINS THE FIELD PARITY BYTE FURNISHED BY THE SAA7113H
2270 * CHIP.
2271 *
2272 * THE UPPER BYTE IS ZERO IF NO PROBLEMS, OTHERWISE:
2273 * 0 != (kount & 0x8000) => AT LEAST ONE URB COMPLETED WITH ERRORS
2274 * 0 != (kount & 0x4000) => BUFFER HAS TOO MUCH DATA
2275 * 0 != (kount & 0x2000) => BUFFER HAS NOT ENOUGH DATA
2276 * 0 != (kount & 0x1000) => BUFFER HAS DATA FROM DISPARATE INPUTS
2277 * 0 != (kount & 0x0400) => RESERVED
2278 * 0 != (kount & 0x0200) => FIELD BUFFER NOT YET CHECKED
2279 * 0 != (kount & 0x0100) => BUFFER HAS TWO EXTRA BYTES - WHY?
2280 */
2281/*---------------------------------------------------------------------------*/
2282static void easycap_complete(struct urb *purb)
2283{
2284 struct easycap *peasycap;
2285 struct data_buffer *pfield_buffer;
2286 char errbuf[16];
2287 int i, more, much, leap, rc, last;
2288 int videofieldamount;
2289 unsigned int override, bad;
2290 int framestatus, framelength, frameactual, frameoffset;
2291 u8 *pu;
2292
2293 if (!purb) {
2294 SAY("ERROR: easycap_complete(): purb is NULL\n");
2295 return;
2296 }
2297 peasycap = purb->context;
2298 if (!peasycap) {
2299 SAY("ERROR: easycap_complete(): peasycap is NULL\n");
2300 return;
2301 }
2302 if (peasycap->video_eof)
2303 return;
2304 for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++)
2305 if (purb->transfer_buffer == peasycap->video_isoc_buffer[i].pgo)
2306 break;
2307 JOM(16, "%2i=urb\n", i);
2308 last = peasycap->video_isoc_sequence;
2309 if ((((VIDEO_ISOC_BUFFER_MANY - 1) == last) && (0 != i)) ||
2310 (((VIDEO_ISOC_BUFFER_MANY - 1) != last) && ((last + 1) != i))) {
2311 JOM(16, "ERROR: out-of-order urbs %i,%i ... continuing\n",
2312 last, i);
2313 }
2314 peasycap->video_isoc_sequence = i;
2315
2316 if (peasycap->video_idle) {
2317 JOM(16, "%i=video_idle %i=video_isoc_streaming\n",
2318 peasycap->video_idle, peasycap->video_isoc_streaming);
2319 if (peasycap->video_isoc_streaming) {
2320 rc = usb_submit_urb(purb, GFP_ATOMIC);
2321 if (rc) {
2322 SAM("%s:%d ENOMEM\n", strerror(rc), rc);
2323 if (-ENODEV != rc)
2324 SAM("ERROR: while %i=video_idle, "
2325 "usb_submit_urb() "
2326 "failed with rc:\n",
2327 peasycap->video_idle);
2328 }
2329 }
2330 return;
2331 }
2332 override = 0;
2333/*---------------------------------------------------------------------------*/
2334 if (FIELD_BUFFER_MANY <= peasycap->field_fill) {
2335 SAM("ERROR: bad peasycap->field_fill\n");
2336 return;
2337 }
2338 if (purb->status) {
2339 if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) {
2340 JOM(8, "urb status -ESHUTDOWN or -ENOENT\n");
2341 return;
2342 }
2343
2344 (peasycap->field_buffer[peasycap->field_fill][0].kount) |= 0x8000 ;
2345 SAM("ERROR: bad urb status -%s: %d\n",
2346 strerror(purb->status), purb->status);
2347/*---------------------------------------------------------------------------*/
2348 } else {
2349 for (i = 0; i < purb->number_of_packets; i++) {
2350 if (0 != purb->iso_frame_desc[i].status) {
2351 (peasycap->field_buffer
2352 [peasycap->field_fill][0].kount) |= 0x8000 ;
2353 /* FIXME: 1. missing '-' check boundaries */
2354 strcpy(&errbuf[0],
2355 strerror(purb->iso_frame_desc[i].status));
2356 }
2357 framestatus = purb->iso_frame_desc[i].status;
2358 framelength = purb->iso_frame_desc[i].length;
2359 frameactual = purb->iso_frame_desc[i].actual_length;
2360 frameoffset = purb->iso_frame_desc[i].offset;
2361
2362 JOM(16, "frame[%2i]:"
2363 "%4i=status "
2364 "%4i=actual "
2365 "%4i=length "
2366 "%5i=offset\n",
2367 i, framestatus, frameactual, framelength, frameoffset);
2368 if (!purb->iso_frame_desc[i].status) {
2369 more = purb->iso_frame_desc[i].actual_length;
2370 pfield_buffer = &peasycap->field_buffer
2371 [peasycap->field_fill][peasycap->field_page];
2372 videofieldamount = (peasycap->field_page *
2373 PAGE_SIZE) +
2374 (int)(pfield_buffer->pto - pfield_buffer->pgo);
2375 if (4 == more)
2376 peasycap->video_mt++;
2377 if (4 < more) {
2378 if (peasycap->video_mt) {
2379 JOM(8, "%4i empty video urb frames\n",
2380 peasycap->video_mt);
2381 peasycap->video_mt = 0;
2382 }
2383 if (FIELD_BUFFER_MANY <= peasycap->field_fill) {
2384 SAM("ERROR: bad peasycap->field_fill\n");
2385 return;
2386 }
2387 if (FIELD_BUFFER_SIZE/PAGE_SIZE <=
2388 peasycap->field_page) {
2389 SAM("ERROR: bad peasycap->field_page\n");
2390 return;
2391 }
2392 pfield_buffer = &peasycap->field_buffer
2393 [peasycap->field_fill][peasycap->field_page];
2394 pu = (u8 *)(purb->transfer_buffer +
2395 purb->iso_frame_desc[i].offset);
2396 if (0x80 & *pu)
2397 leap = 8;
2398 else
2399 leap = 4;
2400/*--------------------------------------------------------------------------*/
2401/*
2402 * EIGHT-BYTE END-OF-VIDEOFIELD MARKER.
2403 * NOTE: A SUCCESSION OF URB FRAMES FOLLOWING THIS ARE EMPTY,
2404 * CORRESPONDING TO THE FIELD FLYBACK (VERTICAL BLANKING) PERIOD.
2405 *
2406 * PROVIDED THE FIELD BUFFER CONTAINS GOOD DATA AS INDICATED BY A ZERO UPPER
2407 * BYTE OF
2408 * peasycap->field_buffer[peasycap->field_fill][0].kount
2409 * THE CONTENTS OF THE FIELD BUFFER ARE OFFERED TO dqbuf(), field_read IS
2410 * UPDATED AND field_fill IS BUMPED. IF THE FIELD BUFFER CONTAINS BAD DATA
2411 * NOTHING IS OFFERED TO dqbuf().
2412 *
2413 * THE DECISION ON WHETHER THE PARITY OF THE OFFERED FIELD BUFFER IS RIGHT
2414 * RESTS WITH dqbuf().
2415 */
2416/*---------------------------------------------------------------------------*/
2417 if ((8 == more) || override) {
2418 if (videofieldamount >
2419 peasycap->videofieldamount) {
2420 if (2 == videofieldamount -
2421 peasycap->
2422 videofieldamount) {
2423 (peasycap->field_buffer
2424 [peasycap->field_fill]
2425 [0].kount) |= 0x0100;
2426 peasycap->video_junk += (1 +
2427 VIDEO_JUNK_TOLERATE);
2428 } else
2429 (peasycap->field_buffer
2430 [peasycap->field_fill]
2431 [0].kount) |= 0x4000;
2432 } else if (videofieldamount <
2433 peasycap->
2434 videofieldamount) {
2435 (peasycap->field_buffer
2436 [peasycap->field_fill]
2437 [0].kount) |= 0x2000;
2438 }
2439 bad = 0xFF00 & peasycap->field_buffer
2440 [peasycap->field_fill]
2441 [0].kount;
2442 if (!bad) {
2443 (peasycap->video_junk)--;
2444 if (-VIDEO_JUNK_TOLERATE >
2445 peasycap->video_junk)
2446 peasycap->video_junk =
2447 -VIDEO_JUNK_TOLERATE;
2448 peasycap->field_read =
2449 (peasycap->
2450 field_fill)++;
2451 if (FIELD_BUFFER_MANY <=
2452 peasycap->
2453 field_fill)
2454 peasycap->
2455 field_fill = 0;
2456 peasycap->field_page = 0;
2457 pfield_buffer = &peasycap->
2458 field_buffer
2459 [peasycap->
2460 field_fill]
2461 [peasycap->
2462 field_page];
2463 pfield_buffer->pto =
2464 pfield_buffer->pgo;
2465 JOM(8, "bumped to: %i="
2466 "peasycap->"
2467 "field_fill %i="
2468 "parity\n",
2469 peasycap->field_fill,
2470 0x00FF &
2471 pfield_buffer->kount);
2472 JOM(8, "field buffer %i has "
2473 "%i bytes fit to be "
2474 "read\n",
2475 peasycap->field_read,
2476 videofieldamount);
2477 JOM(8, "wakeup call to "
2478 "wq_video, "
2479 "%i=field_read "
2480 "%i=field_fill "
2481 "%i=parity\n",
2482 peasycap->field_read,
2483 peasycap->field_fill,
2484 0x00FF & peasycap->
2485 field_buffer
2486 [peasycap->
2487 field_read][0].kount);
2488 wake_up_interruptible
2489 (&(peasycap->
2490 wq_video));
2491 } else {
2492 peasycap->video_junk++;
2493 if (bad & 0x0010)
2494 peasycap->video_junk +=
2495 (1 + VIDEO_JUNK_TOLERATE/2);
2496 JOM(8, "field buffer %i had %i "
2497 "bytes, now discarded: "
2498 "0x%04X\n",
2499 peasycap->field_fill,
2500 videofieldamount,
2501 (0xFF00 &
2502 peasycap->field_buffer
2503 [peasycap->field_fill][0].
2504 kount));
2505 (peasycap->field_fill)++;
2506
2507 if (FIELD_BUFFER_MANY <=
2508 peasycap->field_fill)
2509 peasycap->field_fill = 0;
2510 peasycap->field_page = 0;
2511 pfield_buffer =
2512 &peasycap->field_buffer
2513 [peasycap->field_fill]
2514 [peasycap->field_page];
2515 pfield_buffer->pto =
2516 pfield_buffer->pgo;
2517
2518 JOM(8, "bumped to: %i=peasycap->"
2519 "field_fill %i=parity\n",
2520 peasycap->field_fill,
2521 0x00FF & pfield_buffer->kount);
2522 }
2523 if (8 == more) {
2524 JOM(8, "end-of-field: received "
2525 "parity byte 0x%02X\n",
2526 (0xFF & *pu));
2527 if (0x40 & *pu)
2528 pfield_buffer->kount = 0x0000;
2529 else
2530 pfield_buffer->kount = 0x0001;
2531 pfield_buffer->input = 0x08 |
2532 (0x07 & peasycap->input);
2533 JOM(8, "end-of-field: 0x%02X=kount\n",
2534 0xFF & pfield_buffer->kount);
2535 }
2536 }
2537/*---------------------------------------------------------------------------*/
2538/*
2539 * COPY more BYTES FROM ISOC BUFFER TO FIELD BUFFER
2540 */
2541/*---------------------------------------------------------------------------*/
2542 pu += leap;
2543 more -= leap;
2544
2545 if (FIELD_BUFFER_MANY <= peasycap->field_fill) {
2546 SAM("ERROR: bad peasycap->field_fill\n");
2547 return;
2548 }
2549 if (FIELD_BUFFER_SIZE/PAGE_SIZE <= peasycap->field_page) {
2550 SAM("ERROR: bad peasycap->field_page\n");
2551 return;
2552 }
2553 pfield_buffer = &peasycap->field_buffer
2554 [peasycap->field_fill][peasycap->field_page];
2555 while (more) {
2556 pfield_buffer = &peasycap->field_buffer
2557 [peasycap->field_fill]
2558 [peasycap->field_page];
2559 if (PAGE_SIZE < (pfield_buffer->pto -
2560 pfield_buffer->pgo)) {
2561 SAM("ERROR: bad pfield_buffer->pto\n");
2562 return;
2563 }
2564 if (PAGE_SIZE == (pfield_buffer->pto -
2565 pfield_buffer->pgo)) {
2566 (peasycap->field_page)++;
2567 if (FIELD_BUFFER_SIZE/PAGE_SIZE <=
2568 peasycap->field_page) {
2569 JOM(16, "wrapping peasycap->"
2570 "field_page\n");
2571 peasycap->field_page = 0;
2572 }
2573 pfield_buffer = &peasycap->
2574 field_buffer
2575 [peasycap->field_fill]
2576 [peasycap->field_page];
2577 pfield_buffer->pto = pfield_buffer->pgo;
2578 pfield_buffer->input = 0x08 |
2579 (0x07 & peasycap->input);
2580 if ((peasycap->field_buffer[peasycap->
2581 field_fill][0]).
2582 input !=
2583 pfield_buffer->input)
2584 (peasycap->field_buffer
2585 [peasycap->field_fill]
2586 [0]).kount |= 0x1000;
2587 }
2588
2589 much = PAGE_SIZE -
2590 (int)(pfield_buffer->pto -
2591 pfield_buffer->pgo);
2592
2593 if (much > more)
2594 much = more;
2595 memcpy(pfield_buffer->pto, pu, much);
2596 pu += much;
2597 (pfield_buffer->pto) += much;
2598 more -= much;
2599 }
2600 }
2601 }
2602 }
2603 }
2604/*---------------------------------------------------------------------------*/
2605/*
2606 * RESUBMIT THIS URB, UNLESS A SEVERE PERSISTENT ERROR CONDITION EXISTS.
2607 *
2608 * IF THE WAIT QUEUES ARE NOT CLEARED IN RESPONSE TO AN ERROR CONDITION
2609 * THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT. BEWARE.
2610 */
2611/*---------------------------------------------------------------------------*/
2612 if (VIDEO_ISOC_BUFFER_MANY <= peasycap->video_junk) {
2613 SAM("easycap driver shutting down on condition green\n");
2614 peasycap->status = 1;
2615 peasycap->video_eof = 1;
2616 peasycap->video_junk = 0;
2617 wake_up_interruptible(&peasycap->wq_video);
2618#if !defined(PERSEVERE)
2619 peasycap->audio_eof = 1;
2620 wake_up_interruptible(&peasycap->wq_audio);
2621#endif /*PERSEVERE*/
2622 return;
2623 }
2624 if (peasycap->video_isoc_streaming) {
2625 rc = usb_submit_urb(purb, GFP_ATOMIC);
2626 if (rc) {
2627 SAM("%s: %d\n", strerror(rc), rc);
2628 if (-ENODEV != rc)
2629 SAM("ERROR: while %i=video_idle, "
2630 "usb_submit_urb() "
2631 "failed with rc:\n",
2632 peasycap->video_idle);
2633 }
2634 }
2635 return;
2636}
2637
2638static struct easycap *alloc_easycap(u8 bInterfaceNumber)
2639{
2640 struct easycap *peasycap;
2641 int i;
2642
2643 peasycap = kzalloc(sizeof(struct easycap), GFP_KERNEL);
2644 if (!peasycap) {
2645 SAY("ERROR: Could not allocate peasycap\n");
2646 return NULL;
2647 }
2648
2649 if (mutex_lock_interruptible(&mutex_dongle)) {
2650 SAY("ERROR: cannot lock mutex_dongle\n");
2651 kfree(peasycap);
2652 return NULL;
2653 }
2654
2655 /* Find a free dongle in easycapdc60_dongle array */
2656 for (i = 0; i < DONGLE_MANY; i++) {
2657
2658 if ((!easycapdc60_dongle[i].peasycap) &&
2659 (!mutex_is_locked(&easycapdc60_dongle[i].mutex_video)) &&
2660 (!mutex_is_locked(&easycapdc60_dongle[i].mutex_audio))) {
2661
2662 easycapdc60_dongle[i].peasycap = peasycap;
2663 peasycap->isdongle = i;
2664 JOM(8, "intf[%i]: peasycap-->easycap"
2665 "_dongle[%i].peasycap\n",
2666 bInterfaceNumber, i);
2667 break;
2668 }
2669 }
2670
2671 mutex_unlock(&mutex_dongle);
2672
2673 if (i >= DONGLE_MANY) {
2674 SAM("ERROR: too many dongles\n");
2675 kfree(peasycap);
2676 return NULL;
2677 }
2678
2679 return peasycap;
2680}
2681
2682static void free_easycap(struct easycap *peasycap)
2683{
2684 int allocation_video_urb;
2685 int allocation_video_page;
2686 int allocation_video_struct;
2687 int allocation_audio_urb;
2688 int allocation_audio_page;
2689 int allocation_audio_struct;
2690 int registered_video, registered_audio;
2691 int kd;
2692
2693 JOM(4, "freeing easycap structure.\n");
2694 allocation_video_urb = peasycap->allocation_video_urb;
2695 allocation_video_page = peasycap->allocation_video_page;
2696 allocation_video_struct = peasycap->allocation_video_struct;
2697 registered_video = peasycap->registered_video;
2698 allocation_audio_urb = peasycap->allocation_audio_urb;
2699 allocation_audio_page = peasycap->allocation_audio_page;
2700 allocation_audio_struct = peasycap->allocation_audio_struct;
2701 registered_audio = peasycap->registered_audio;
2702
2703 kd = easycap_isdongle(peasycap);
2704 if (0 <= kd && DONGLE_MANY > kd) {
2705 if (mutex_lock_interruptible(&mutex_dongle)) {
2706 SAY("ERROR: cannot down mutex_dongle\n");
2707 } else {
2708 JOM(4, "locked mutex_dongle\n");
2709 easycapdc60_dongle[kd].peasycap = NULL;
2710 mutex_unlock(&mutex_dongle);
2711 JOM(4, "unlocked mutex_dongle\n");
2712 JOT(4, " null-->dongle[%i].peasycap\n", kd);
2713 allocation_video_struct -= sizeof(struct easycap);
2714 }
2715 } else {
2716 SAY("ERROR: cannot purge dongle[].peasycap");
2717 }
2718
2719 /* Free device structure */
2720 kfree(peasycap);
2721
2722 SAY("%8i=video urbs after all deletions\n", allocation_video_urb);
2723 SAY("%8i=video pages after all deletions\n", allocation_video_page);
2724 SAY("%8i=video structs after all deletions\n", allocation_video_struct);
2725 SAY("%8i=video devices after all deletions\n", registered_video);
2726 SAY("%8i=audio urbs after all deletions\n", allocation_audio_urb);
2727 SAY("%8i=audio pages after all deletions\n", allocation_audio_page);
2728 SAY("%8i=audio structs after all deletions\n", allocation_audio_struct);
2729 SAY("%8i=audio devices after all deletions\n", registered_audio);
2730}
2731
2732/*
2733 * FIXME: Identify the appropriate pointer peasycap for interfaces
2734 * 1 and 2. The address of peasycap->pusb_device is reluctantly used
2735 * for this purpose.
2736 */
2737static struct easycap *get_easycap(struct usb_device *usbdev,
2738 u8 bInterfaceNumber)
2739{
2740 int i;
2741 struct easycap *peasycap;
2742
2743 for (i = 0; i < DONGLE_MANY; i++) {
2744 if (easycapdc60_dongle[i].peasycap->pusb_device == usbdev) {
2745 peasycap = easycapdc60_dongle[i].peasycap;
2746 JOT(8, "intf[%i]: dongle[%i].peasycap\n",
2747 bInterfaceNumber, i);
2748 break;
2749 }
2750 }
2751 if (i >= DONGLE_MANY) {
2752 SAY("ERROR: peasycap is unknown when probing interface %i\n",
2753 bInterfaceNumber);
2754 return NULL;
2755 }
2756 if (!peasycap) {
2757 SAY("ERROR: peasycap is NULL when probing interface %i\n",
2758 bInterfaceNumber);
2759 return NULL;
2760 }
2761
2762 return peasycap;
2763}
2764
2765static void init_easycap(struct easycap *peasycap,
2766 struct usb_device *usbdev,
2767 struct usb_interface *intf,
2768 u8 bInterfaceNumber)
2769{
2770 /* Save usb_device and usb_interface */
2771 peasycap->pusb_device = usbdev;
2772 peasycap->pusb_interface = intf;
2773
2774 peasycap->minor = -1;
2775 kref_init(&peasycap->kref);
2776 JOM(8, "intf[%i]: after kref_init(..._video) "
2777 "%i=peasycap->kref.refcount.counter\n",
2778 bInterfaceNumber, peasycap->kref.refcount.counter);
2779
2780 /* module params */
2781 peasycap->gain = (s8)clamp(easycap_gain, 0, 31);
2782
2783 init_waitqueue_head(&peasycap->wq_video);
2784 init_waitqueue_head(&peasycap->wq_audio);
2785 init_waitqueue_head(&peasycap->wq_trigger);
2786
2787 peasycap->allocation_video_struct = sizeof(struct easycap);
2788
2789 peasycap->microphone = false;
2790
2791 peasycap->video_interface = -1;
2792 peasycap->video_altsetting_on = -1;
2793 peasycap->video_altsetting_off = -1;
2794 peasycap->video_endpointnumber = -1;
2795 peasycap->video_isoc_maxframesize = -1;
2796 peasycap->video_isoc_buffer_size = -1;
2797
2798 peasycap->audio_interface = -1;
2799 peasycap->audio_altsetting_on = -1;
2800 peasycap->audio_altsetting_off = -1;
2801 peasycap->audio_endpointnumber = -1;
2802 peasycap->audio_isoc_maxframesize = -1;
2803 peasycap->audio_isoc_buffer_size = -1;
2804
2805 peasycap->frame_buffer_many = FRAME_BUFFER_MANY;
2806
2807 peasycap->ntsc = easycap_ntsc;
2808 JOM(8, "defaulting initially to %s\n",
2809 easycap_ntsc ? "NTSC" : "PAL");
2810}
2811
2812static int populate_inputset(struct easycap *peasycap)
2813{
2814 struct inputset *inputset;
2815 struct easycap_format *peasycap_format;
2816 struct v4l2_pix_format *pix;
2817 int m, i, k, mask, fmtidx;
2818 s32 value;
2819
2820 inputset = peasycap->inputset;
2821
2822 fmtidx = peasycap->ntsc ? NTSC_M : PAL_BGHIN;
2823
2824 m = 0;
2825 mask = 0;
2826 for (i = 0; easycap_standard[i].mask != 0xffff; i++) {
2827 if (fmtidx == easycap_standard[i].v4l2_standard.index) {
2828 m++;
2829 for (k = 0; k < INPUT_MANY; k++)
2830 inputset[k].standard_offset = i;
2831 mask = easycap_standard[i].mask;
2832 }
2833 }
2834
2835 if (m != 1) {
2836 SAM("ERROR: inputset->standard_offset unpopulated, %i=m\n", m);
2837 return -ENOENT;
2838 }
2839
2840 peasycap_format = &easycap_format[0];
2841 m = 0;
2842 for (i = 0; peasycap_format->v4l2_format.fmt.pix.width; i++) {
2843 pix = &peasycap_format->v4l2_format.fmt.pix;
2844 if (((peasycap_format->mask & 0x0F) == (mask & 0x0F))
2845 && pix->field == V4L2_FIELD_NONE
2846 && pix->pixelformat == V4L2_PIX_FMT_UYVY
2847 && pix->width == 640 && pix->height == 480) {
2848 m++;
2849 for (k = 0; k < INPUT_MANY; k++)
2850 inputset[k].format_offset = i;
2851 break;
2852 }
2853 peasycap_format++;
2854 }
2855 if (m != 1) {
2856 SAM("ERROR: inputset[]->format_offset unpopulated\n");
2857 return -ENOENT;
2858 }
2859
2860 m = 0;
2861 for (i = 0; easycap_control[i].id != 0xffffffff; i++) {
2862 value = easycap_control[i].default_value;
2863 if (V4L2_CID_BRIGHTNESS == easycap_control[i].id) {
2864 m++;
2865 for (k = 0; k < INPUT_MANY; k++)
2866 inputset[k].brightness = value;
2867 } else if (V4L2_CID_CONTRAST == easycap_control[i].id) {
2868 m++;
2869 for (k = 0; k < INPUT_MANY; k++)
2870 inputset[k].contrast = value;
2871 } else if (V4L2_CID_SATURATION == easycap_control[i].id) {
2872 m++;
2873 for (k = 0; k < INPUT_MANY; k++)
2874 inputset[k].saturation = value;
2875 } else if (V4L2_CID_HUE == easycap_control[i].id) {
2876 m++;
2877 for (k = 0; k < INPUT_MANY; k++)
2878 inputset[k].hue = value;
2879 }
2880 }
2881
2882 if (m != 4) {
2883 SAM("ERROR: inputset[]->brightness underpopulated\n");
2884 return -ENOENT;
2885 }
2886
2887 for (k = 0; k < INPUT_MANY; k++)
2888 inputset[k].input = k;
2889 JOM(4, "populated inputset[]\n");
2890
2891 return 0;
2892}
2893
2894static int alloc_framebuffers(struct easycap *peasycap)
2895{
2896 int i, j;
2897 void *pbuf;
2898
2899 JOM(4, "allocating %i frame buffers of size %li\n",
2900 FRAME_BUFFER_MANY, (long int)FRAME_BUFFER_SIZE);
2901 JOM(4, ".... each scattered over %li pages\n",
2902 FRAME_BUFFER_SIZE/PAGE_SIZE);
2903
2904 for (i = 0; i < FRAME_BUFFER_MANY; i++) {
2905 for (j = 0; j < FRAME_BUFFER_SIZE/PAGE_SIZE; j++) {
2906 if (peasycap->frame_buffer[i][j].pgo)
2907 SAM("attempting to reallocate framebuffers\n");
2908 else {
2909 pbuf = (void *)__get_free_page(GFP_KERNEL);
2910 if (!pbuf) {
2911 SAM("ERROR: Could not allocate "
2912 "framebuffer %i page %i\n", i, j);
2913 return -ENOMEM;
2914 }
2915 peasycap->allocation_video_page += 1;
2916 peasycap->frame_buffer[i][j].pgo = pbuf;
2917 }
2918 peasycap->frame_buffer[i][j].pto =
2919 peasycap->frame_buffer[i][j].pgo;
2920 }
2921 }
2922
2923 peasycap->frame_fill = 0;
2924 peasycap->frame_read = 0;
2925 JOM(4, "allocation of frame buffers done: %i pages\n", i*j);
2926
2927 return 0;
2928}
2929
2930static void free_framebuffers(struct easycap *peasycap)
2931{
2932 int k, m, gone;
2933
2934 JOM(4, "freeing video frame buffers.\n");
2935 gone = 0;
2936 for (k = 0; k < FRAME_BUFFER_MANY; k++) {
2937 for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) {
2938 if (peasycap->frame_buffer[k][m].pgo) {
2939 free_page((unsigned long)
2940 peasycap->frame_buffer[k][m].pgo);
2941 peasycap->frame_buffer[k][m].pgo = NULL;
2942 peasycap->allocation_video_page -= 1;
2943 gone++;
2944 }
2945 }
2946 }
2947 JOM(4, "video frame buffers freed: %i pages\n", gone);
2948}
2949
2950static int alloc_fieldbuffers(struct easycap *peasycap)
2951{
2952 int i, j;
2953 void *pbuf;
2954
2955 JOM(4, "allocating %i field buffers of size %li\n",
2956 FIELD_BUFFER_MANY, (long int)FIELD_BUFFER_SIZE);
2957 JOM(4, ".... each scattered over %li pages\n",
2958 FIELD_BUFFER_SIZE/PAGE_SIZE);
2959
2960 for (i = 0; i < FIELD_BUFFER_MANY; i++) {
2961 for (j = 0; j < FIELD_BUFFER_SIZE/PAGE_SIZE; j++) {
2962 if (peasycap->field_buffer[i][j].pgo) {
2963 SAM("ERROR: attempting to reallocate "
2964 "fieldbuffers\n");
2965 } else {
2966 pbuf = (void *) __get_free_page(GFP_KERNEL);
2967 if (!pbuf) {
2968 SAM("ERROR: Could not allocate "
2969 "fieldbuffer %i page %i\n", i, j);
2970 return -ENOMEM;
2971 }
2972 peasycap->allocation_video_page += 1;
2973 peasycap->field_buffer[i][j].pgo = pbuf;
2974 }
2975 peasycap->field_buffer[i][j].pto =
2976 peasycap->field_buffer[i][j].pgo;
2977 }
2978 /* TODO: Hardcoded 0x0200 meaning? */
2979 peasycap->field_buffer[i][0].kount = 0x0200;
2980 }
2981 peasycap->field_fill = 0;
2982 peasycap->field_page = 0;
2983 peasycap->field_read = 0;
2984 JOM(4, "allocation of field buffers done: %i pages\n", i*j);
2985
2986 return 0;
2987}
2988
2989static void free_fieldbuffers(struct easycap *peasycap)
2990{
2991 int k, m, gone;
2992
2993 JOM(4, "freeing video field buffers.\n");
2994 gone = 0;
2995 for (k = 0; k < FIELD_BUFFER_MANY; k++) {
2996 for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) {
2997 if (peasycap->field_buffer[k][m].pgo) {
2998 free_page((unsigned long)
2999 peasycap->field_buffer[k][m].pgo);
3000 peasycap->field_buffer[k][m].pgo = NULL;
3001 peasycap->allocation_video_page -= 1;
3002 gone++;
3003 }
3004 }
3005 }
3006 JOM(4, "video field buffers freed: %i pages\n", gone);
3007}
3008
3009static int alloc_isocbuffers(struct easycap *peasycap)
3010{
3011 int i;
3012 void *pbuf;
3013
3014 JOM(4, "allocating %i isoc video buffers of size %i\n",
3015 VIDEO_ISOC_BUFFER_MANY,
3016 peasycap->video_isoc_buffer_size);
3017 JOM(4, ".... each occupying contiguous memory pages\n");
3018
3019 for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++) {
3020 pbuf = (void *)__get_free_pages(GFP_KERNEL,
3021 VIDEO_ISOC_ORDER);
3022 if (!pbuf) {
3023 SAM("ERROR: Could not allocate isoc "
3024 "video buffer %i\n", i);
3025 return -ENOMEM;
3026 }
3027 peasycap->allocation_video_page += BIT(VIDEO_ISOC_ORDER);
3028
3029 peasycap->video_isoc_buffer[i].pgo = pbuf;
3030 peasycap->video_isoc_buffer[i].pto =
3031 pbuf + peasycap->video_isoc_buffer_size;
3032 peasycap->video_isoc_buffer[i].kount = i;
3033 }
3034 JOM(4, "allocation of isoc video buffers done: %i pages\n",
3035 i * (0x01 << VIDEO_ISOC_ORDER));
3036 return 0;
3037}
3038
3039static void free_isocbuffers(struct easycap *peasycap)
3040{
3041 int k, m;
3042
3043 JOM(4, "freeing video isoc buffers.\n");
3044 m = 0;
3045 for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) {
3046 if (peasycap->video_isoc_buffer[k].pgo) {
3047 free_pages((unsigned long)
3048 peasycap->video_isoc_buffer[k].pgo,
3049 VIDEO_ISOC_ORDER);
3050 peasycap->video_isoc_buffer[k].pgo = NULL;
3051 peasycap->allocation_video_page -=
3052 BIT(VIDEO_ISOC_ORDER);
3053 m++;
3054 }
3055 }
3056 JOM(4, "isoc video buffers freed: %i pages\n",
3057 m * (0x01 << VIDEO_ISOC_ORDER));
3058}
3059
3060static int create_video_urbs(struct easycap *peasycap)
3061{
3062 struct urb *purb;
3063 struct data_urb *pdata_urb;
3064 int i, j;
3065
3066 JOM(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY);
3067 JOM(4, "using %i=peasycap->video_isoc_framesperdesc\n",
3068 peasycap->video_isoc_framesperdesc);
3069 JOM(4, "using %i=peasycap->video_isoc_maxframesize\n",
3070 peasycap->video_isoc_maxframesize);
3071 JOM(4, "using %i=peasycap->video_isoc_buffer_sizen",
3072 peasycap->video_isoc_buffer_size);
3073
3074 for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++) {
3075 purb = usb_alloc_urb(peasycap->video_isoc_framesperdesc,
3076 GFP_KERNEL);
3077 if (!purb) {
3078 SAM("ERROR: usb_alloc_urb returned NULL for buffer "
3079 "%i\n", i);
3080 return -ENOMEM;
3081 }
3082
3083 peasycap->allocation_video_urb += 1;
3084 pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
3085 if (!pdata_urb) {
3086 usb_free_urb(purb);
3087 SAM("ERROR: Could not allocate struct data_urb.\n");
3088 return -ENOMEM;
3089 }
3090
3091 peasycap->allocation_video_struct +=
3092 sizeof(struct data_urb);
3093
3094 pdata_urb->purb = purb;
3095 pdata_urb->isbuf = i;
3096 pdata_urb->length = 0;
3097 list_add_tail(&(pdata_urb->list_head),
3098 peasycap->purb_video_head);
3099
3100 if (!i) {
3101 JOM(4, "initializing video urbs thus:\n");
3102 JOM(4, " purb->interval = 1;\n");
3103 JOM(4, " purb->dev = peasycap->pusb_device;\n");
3104 JOM(4, " purb->pipe = usb_rcvisocpipe"
3105 "(peasycap->pusb_device,%i);\n",
3106 peasycap->video_endpointnumber);
3107 JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n");
3108 JOM(4, " purb->transfer_buffer = peasycap->"
3109 "video_isoc_buffer[.].pgo;\n");
3110 JOM(4, " purb->transfer_buffer_length = %i;\n",
3111 peasycap->video_isoc_buffer_size);
3112 JOM(4, " purb->complete = easycap_complete;\n");
3113 JOM(4, " purb->context = peasycap;\n");
3114 JOM(4, " purb->start_frame = 0;\n");
3115 JOM(4, " purb->number_of_packets = %i;\n",
3116 peasycap->video_isoc_framesperdesc);
3117 JOM(4, " for (j = 0; j < %i; j++)\n",
3118 peasycap->video_isoc_framesperdesc);
3119 JOM(4, " {\n");
3120 JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n",
3121 peasycap->video_isoc_maxframesize);
3122 JOM(4, " purb->iso_frame_desc[j].length = %i;\n",
3123 peasycap->video_isoc_maxframesize);
3124 JOM(4, " }\n");
3125 }
3126
3127 purb->interval = 1;
3128 purb->dev = peasycap->pusb_device;
3129 purb->pipe = usb_rcvisocpipe(peasycap->pusb_device,
3130 peasycap->video_endpointnumber);
3131
3132 purb->transfer_flags = URB_ISO_ASAP;
3133 purb->transfer_buffer = peasycap->video_isoc_buffer[i].pgo;
3134 purb->transfer_buffer_length =
3135 peasycap->video_isoc_buffer_size;
3136
3137 purb->complete = easycap_complete;
3138 purb->context = peasycap;
3139 purb->start_frame = 0;
3140 purb->number_of_packets = peasycap->video_isoc_framesperdesc;
3141
3142 for (j = 0; j < peasycap->video_isoc_framesperdesc; j++) {
3143 purb->iso_frame_desc[j].offset =
3144 j * peasycap->video_isoc_maxframesize;
3145 purb->iso_frame_desc[j].length =
3146 peasycap->video_isoc_maxframesize;
3147 }
3148 }
3149 JOM(4, "allocation of %i struct urb done.\n", i);
3150 return 0;
3151}
3152
3153static void free_video_urbs(struct easycap *peasycap)
3154{
3155 struct list_head *plist_head, *plist_next;
3156 struct data_urb *pdata_urb;
3157 int m;
3158
3159 if (peasycap->purb_video_head) {
3160 m = 0;
3161 list_for_each(plist_head, peasycap->purb_video_head) {
3162 pdata_urb = list_entry(plist_head,
3163 struct data_urb, list_head);
3164 if (pdata_urb && pdata_urb->purb) {
3165 usb_free_urb(pdata_urb->purb);
3166 pdata_urb->purb = NULL;
3167 peasycap->allocation_video_urb--;
3168 m++;
3169 }
3170 }
3171
3172 JOM(4, "%i video urbs freed\n", m);
3173 JOM(4, "freeing video data_urb structures.\n");
3174 m = 0;
3175 list_for_each_safe(plist_head, plist_next,
3176 peasycap->purb_video_head) {
3177 pdata_urb = list_entry(plist_head,
3178 struct data_urb, list_head);
3179 if (pdata_urb) {
3180 peasycap->allocation_video_struct -=
3181 sizeof(struct data_urb);
3182 kfree(pdata_urb);
3183 m++;
3184 }
3185 }
3186 JOM(4, "%i video data_urb structures freed\n", m);
3187 JOM(4, "setting peasycap->purb_video_head=NULL\n");
3188 peasycap->purb_video_head = NULL;
3189 }
3190}
3191
3192static int alloc_audio_buffers(struct easycap *peasycap)
3193{
3194 void *pbuf;
3195 int k;
3196
3197 JOM(4, "allocating %i isoc audio buffers of size %i\n",
3198 AUDIO_ISOC_BUFFER_MANY,
3199 peasycap->audio_isoc_buffer_size);
3200 JOM(4, ".... each occupying contiguous memory pages\n");
3201
3202 for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) {
3203 pbuf = (void *)__get_free_pages(GFP_KERNEL, AUDIO_ISOC_ORDER);
3204 if (!pbuf) {
3205 SAM("ERROR: Could not allocate isoc audio buffer %i\n",
3206 k);
3207 return -ENOMEM;
3208 }
3209 peasycap->allocation_audio_page += BIT(AUDIO_ISOC_ORDER);
3210
3211 peasycap->audio_isoc_buffer[k].pgo = pbuf;
3212 peasycap->audio_isoc_buffer[k].pto =
3213 pbuf + peasycap->audio_isoc_buffer_size;
3214 peasycap->audio_isoc_buffer[k].kount = k;
3215 }
3216
3217 JOM(4, "allocation of isoc audio buffers done.\n");
3218 return 0;
3219}
3220
3221static void free_audio_buffers(struct easycap *peasycap)
3222{
3223 int k, m;
3224
3225 JOM(4, "freeing audio isoc buffers.\n");
3226 m = 0;
3227 for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) {
3228 if (peasycap->audio_isoc_buffer[k].pgo) {
3229 free_pages((unsigned long)
3230 (peasycap->audio_isoc_buffer[k].pgo),
3231 AUDIO_ISOC_ORDER);
3232 peasycap->audio_isoc_buffer[k].pgo = NULL;
3233 peasycap->allocation_audio_page -=
3234 BIT(AUDIO_ISOC_ORDER);
3235 m++;
3236 }
3237 }
3238 JOM(4, "easyoss_delete(): isoc audio buffers freed: %i pages\n",
3239 m * (0x01 << AUDIO_ISOC_ORDER));
3240}
3241
3242static int create_audio_urbs(struct easycap *peasycap)
3243{
3244 struct urb *purb;
3245 struct data_urb *pdata_urb;
3246 int k, j;
3247
3248 JOM(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY);
3249 JOM(4, "using %i=peasycap->audio_isoc_framesperdesc\n",
3250 peasycap->audio_isoc_framesperdesc);
3251 JOM(4, "using %i=peasycap->audio_isoc_maxframesize\n",
3252 peasycap->audio_isoc_maxframesize);
3253 JOM(4, "using %i=peasycap->audio_isoc_buffer_size\n",
3254 peasycap->audio_isoc_buffer_size);
3255
3256 for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) {
3257 purb = usb_alloc_urb(peasycap->audio_isoc_framesperdesc,
3258 GFP_KERNEL);
3259 if (!purb) {
3260 SAM("ERROR: usb_alloc_urb returned NULL for buffer "
3261 "%i\n", k);
3262 return -ENOMEM;
3263 }
3264 peasycap->allocation_audio_urb += 1 ;
3265 pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL);
3266 if (!pdata_urb) {
3267 usb_free_urb(purb);
3268 SAM("ERROR: Could not allocate struct data_urb.\n");
3269 return -ENOMEM;
3270 }
3271 peasycap->allocation_audio_struct +=
3272 sizeof(struct data_urb);
3273
3274 pdata_urb->purb = purb;
3275 pdata_urb->isbuf = k;
3276 pdata_urb->length = 0;
3277 list_add_tail(&(pdata_urb->list_head),
3278 peasycap->purb_audio_head);
3279
3280 if (!k) {
3281 JOM(4, "initializing audio urbs thus:\n");
3282 JOM(4, " purb->interval = 1;\n");
3283 JOM(4, " purb->dev = peasycap->pusb_device;\n");
3284 JOM(4, " purb->pipe = usb_rcvisocpipe(peasycap->"
3285 "pusb_device,%i);\n",
3286 peasycap->audio_endpointnumber);
3287 JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n");
3288 JOM(4, " purb->transfer_buffer = "
3289 "peasycap->audio_isoc_buffer[.].pgo;\n");
3290 JOM(4, " purb->transfer_buffer_length = %i;\n",
3291 peasycap->audio_isoc_buffer_size);
3292 JOM(4, " purb->complete = easycap_alsa_complete;\n");
3293 JOM(4, " purb->context = peasycap;\n");
3294 JOM(4, " purb->start_frame = 0;\n");
3295 JOM(4, " purb->number_of_packets = %i;\n",
3296 peasycap->audio_isoc_framesperdesc);
3297 JOM(4, " for (j = 0; j < %i; j++)\n",
3298 peasycap->audio_isoc_framesperdesc);
3299 JOM(4, " {\n");
3300 JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n",
3301 peasycap->audio_isoc_maxframesize);
3302 JOM(4, " purb->iso_frame_desc[j].length = %i;\n",
3303 peasycap->audio_isoc_maxframesize);
3304 JOM(4, " }\n");
3305 }
3306
3307 purb->interval = 1;
3308 purb->dev = peasycap->pusb_device;
3309 purb->pipe = usb_rcvisocpipe(peasycap->pusb_device,
3310 peasycap->audio_endpointnumber);
3311 purb->transfer_flags = URB_ISO_ASAP;
3312 purb->transfer_buffer = peasycap->audio_isoc_buffer[k].pgo;
3313 purb->transfer_buffer_length =
3314 peasycap->audio_isoc_buffer_size;
3315 purb->complete = easycap_alsa_complete;
3316 purb->context = peasycap;
3317 purb->start_frame = 0;
3318 purb->number_of_packets = peasycap->audio_isoc_framesperdesc;
3319 for (j = 0; j < peasycap->audio_isoc_framesperdesc; j++) {
3320 purb->iso_frame_desc[j].offset =
3321 j * peasycap->audio_isoc_maxframesize;
3322 purb->iso_frame_desc[j].length =
3323 peasycap->audio_isoc_maxframesize;
3324 }
3325 }
3326 JOM(4, "allocation of %i struct urb done.\n", k);
3327 return 0;
3328}
3329
3330static void free_audio_urbs(struct easycap *peasycap)
3331{
3332 struct list_head *plist_head, *plist_next;
3333 struct data_urb *pdata_urb;
3334 int m;
3335
3336 if (peasycap->purb_audio_head) {
3337 JOM(4, "freeing audio urbs\n");
3338 m = 0;
3339 list_for_each(plist_head, (peasycap->purb_audio_head)) {
3340 pdata_urb = list_entry(plist_head,
3341 struct data_urb, list_head);
3342 if (pdata_urb && pdata_urb->purb) {
3343 usb_free_urb(pdata_urb->purb);
3344 pdata_urb->purb = NULL;
3345 peasycap->allocation_audio_urb--;
3346 m++;
3347 }
3348 }
3349 JOM(4, "%i audio urbs freed\n", m);
3350 JOM(4, "freeing audio data_urb structures.\n");
3351 m = 0;
3352 list_for_each_safe(plist_head, plist_next,
3353 peasycap->purb_audio_head) {
3354 pdata_urb = list_entry(plist_head,
3355 struct data_urb, list_head);
3356 if (pdata_urb) {
3357 peasycap->allocation_audio_struct -=
3358 sizeof(struct data_urb);
3359 kfree(pdata_urb);
3360 m++;
3361 }
3362 }
3363 JOM(4, "%i audio data_urb structures freed\n", m);
3364 JOM(4, "setting peasycap->purb_audio_head=NULL\n");
3365 peasycap->purb_audio_head = NULL;
3366 }
3367}
3368
3369static void config_easycap(struct easycap *peasycap,
3370 u8 bInterfaceNumber,
3371 u8 bInterfaceClass,
3372 u8 bInterfaceSubClass)
3373{
3374 if ((USB_CLASS_VIDEO == bInterfaceClass) ||
3375 (USB_CLASS_VENDOR_SPEC == bInterfaceClass)) {
3376 if (-1 == peasycap->video_interface) {
3377 peasycap->video_interface = bInterfaceNumber;
3378 JOM(4, "setting peasycap->video_interface=%i\n",
3379 peasycap->video_interface);
3380 } else {
3381 if (peasycap->video_interface != bInterfaceNumber) {
3382 SAM("ERROR: attempting to reset "
3383 "peasycap->video_interface\n");
3384 SAM("...... continuing with "
3385 "%i=peasycap->video_interface\n",
3386 peasycap->video_interface);
3387 }
3388 }
3389 } else if ((USB_CLASS_AUDIO == bInterfaceClass) &&
3390 (USB_SUBCLASS_AUDIOSTREAMING == bInterfaceSubClass)) {
3391 if (-1 == peasycap->audio_interface) {
3392 peasycap->audio_interface = bInterfaceNumber;
3393 JOM(4, "setting peasycap->audio_interface=%i\n",
3394 peasycap->audio_interface);
3395 } else {
3396 if (peasycap->audio_interface != bInterfaceNumber) {
3397 SAM("ERROR: attempting to reset "
3398 "peasycap->audio_interface\n");
3399 SAM("...... continuing with "
3400 "%i=peasycap->audio_interface\n",
3401 peasycap->audio_interface);
3402 }
3403 }
3404 }
3405}
3406
3407/*
3408 * This function is called from within easycap_usb_disconnect() and is
3409 * protected by semaphores set and cleared by easycap_usb_disconnect().
3410 * By this stage the device has already been physically unplugged,
3411 * so peasycap->pusb_device is no longer valid.
3412 */
3413static void easycap_delete(struct kref *pkref)
3414{
3415 struct easycap *peasycap;
3416
3417 peasycap = container_of(pkref, struct easycap, kref);
3418 if (!peasycap) {
3419 SAM("ERROR: peasycap is NULL: cannot perform deletions\n");
3420 return;
3421 }
3422
3423 /* Free video urbs */
3424 free_video_urbs(peasycap);
3425
3426 /* Free video isoc buffers */
3427 free_isocbuffers(peasycap);
3428
3429 /* Free video field buffers */
3430 free_fieldbuffers(peasycap);
3431
3432 /* Free video frame buffers */
3433 free_framebuffers(peasycap);
3434
3435 /* Free audio urbs */
3436 free_audio_urbs(peasycap);
3437
3438 /* Free audio isoc buffers */
3439 free_audio_buffers(peasycap);
3440
3441 free_easycap(peasycap);
3442
3443 JOT(4, "ending.\n");
3444}
3445
3446static const struct v4l2_file_operations v4l2_fops = {
3447 .owner = THIS_MODULE,
3448 .open = easycap_open_noinode,
3449 .unlocked_ioctl = easycap_unlocked_ioctl,
3450 .poll = easycap_poll,
3451 .mmap = easycap_mmap,
3452};
3453
3454static int easycap_register_video(struct easycap *peasycap)
3455{
3456 /*
3457 * FIXME: This is believed to be harmless,
3458 * but may well be unnecessary or wrong.
3459 */
3460 peasycap->video_device.v4l2_dev = NULL;
3461
3462 strcpy(&peasycap->video_device.name[0], "easycapdc60");
3463 peasycap->video_device.fops = &v4l2_fops;
3464 peasycap->video_device.minor = -1;
3465 peasycap->video_device.release = (void *)(&videodev_release);
3466
3467 video_set_drvdata(&(peasycap->video_device), (void *)peasycap);
3468
3469 if (0 != (video_register_device(&(peasycap->video_device),
3470 VFL_TYPE_GRABBER, -1))) {
3471 videodev_release(&(peasycap->video_device));
3472 return -ENODEV;
3473 }
3474
3475 peasycap->registered_video++;
3476
3477 SAM("registered with videodev: %i=minor\n",
3478 peasycap->video_device.minor);
3479 peasycap->minor = peasycap->video_device.minor;
3480
3481 return 0;
3482}
3483
3484/*
3485 * When the device is plugged, this function is called three times,
3486 * one for each interface.
3487 */
3488static int easycap_usb_probe(struct usb_interface *intf,
3489 const struct usb_device_id *id)
3490{
3491 struct usb_device *usbdev;
3492 struct usb_host_interface *alt;
3493 struct usb_endpoint_descriptor *ep;
3494 struct usb_interface_descriptor *interface;
3495 struct easycap *peasycap;
3496 int i, j, rc;
3497 u8 bInterfaceNumber;
3498 u8 bInterfaceClass;
3499 u8 bInterfaceSubClass;
3500 int okalt[8], isokalt;
3501 int okepn[8];
3502 int okmps[8];
3503 int maxpacketsize;
3504
3505 usbdev = interface_to_usbdev(intf);
3506
3507 alt = usb_altnum_to_altsetting(intf, 0);
3508 if (!alt) {
3509 SAY("ERROR: usb_host_interface not found\n");
3510 return -EFAULT;
3511 }
3512
3513 interface = &alt->desc;
3514 if (!interface) {
3515 SAY("ERROR: intf_descriptor is NULL\n");
3516 return -EFAULT;
3517 }
3518
3519 /* Get properties of probed interface */
3520 bInterfaceNumber = interface->bInterfaceNumber;
3521 bInterfaceClass = interface->bInterfaceClass;
3522 bInterfaceSubClass = interface->bInterfaceSubClass;
3523
3524 JOT(4, "intf[%i]: num_altsetting=%i\n",
3525 bInterfaceNumber, intf->num_altsetting);
3526 JOT(4, "intf[%i]: cur_altsetting - altsetting=%li\n",
3527 bInterfaceNumber,
3528 (long int)(intf->cur_altsetting - intf->altsetting));
3529 JOT(4, "intf[%i]: bInterfaceClass=0x%02X bInterfaceSubClass=0x%02X\n",
3530 bInterfaceNumber, bInterfaceClass, bInterfaceSubClass);
3531
3532 /*
3533 * A new struct easycap is always allocated when interface 0 is probed.
3534 * It is not possible here to free any existing struct easycap.
3535 * This should have been done by easycap_delete() when the device was
3536 * physically unplugged.
3537 * The allocated struct easycap is saved for later usage when
3538 * interfaces 1 and 2 are probed.
3539 */
3540 if (0 == bInterfaceNumber) {
3541 /*
3542 * Alloc structure and save it in a free slot in
3543 * easycapdc60_dongle array
3544 */
3545 peasycap = alloc_easycap(bInterfaceNumber);
3546 if (!peasycap)
3547 return -ENOMEM;
3548
3549 /* Perform basic struct initialization */
3550 init_easycap(peasycap, usbdev, intf, bInterfaceNumber);
3551
3552 /* Dynamically fill in the available formats */
3553 rc = easycap_video_fillin_formats();
3554 if (0 > rc) {
3555 SAM("ERROR: fillin_formats() rc = %i\n", rc);
3556 return -EFAULT;
3557 }
3558 JOM(4, "%i formats available\n", rc);
3559
3560 /* Populate easycap.inputset[] */
3561 rc = populate_inputset(peasycap);
3562 if (rc < 0)
3563 return rc;
3564 JOM(4, "finished initialization\n");
3565 } else {
3566 peasycap = get_easycap(usbdev, bInterfaceNumber);
3567 if (!peasycap)
3568 return -ENODEV;
3569 }
3570
3571 config_easycap(peasycap, bInterfaceNumber,
3572 bInterfaceClass,
3573 bInterfaceSubClass);
3574
3575 /*
3576 * Investigate all altsettings. This is done in detail
3577 * because USB device 05e1:0408 has disparate incarnations.
3578 */
3579 isokalt = 0;
3580 for (i = 0; i < intf->num_altsetting; i++) {
3581 alt = usb_altnum_to_altsetting(intf, i);
3582 if (!alt) {
3583 SAM("ERROR: alt is NULL\n");
3584 return -EFAULT;
3585 }
3586 interface = &alt->desc;
3587 if (!interface) {
3588 SAM("ERROR: intf_descriptor is NULL\n");
3589 return -EFAULT;
3590 }
3591
3592 if (0 == interface->bNumEndpoints)
3593 JOM(4, "intf[%i]alt[%i] has no endpoints\n",
3594 bInterfaceNumber, i);
3595 for (j = 0; j < interface->bNumEndpoints; j++) {
3596 ep = &alt->endpoint[j].desc;
3597 if (!ep) {
3598 SAM("ERROR: ep is NULL.\n");
3599 SAM("...... skipping\n");
3600 continue;
3601 }
3602
3603 if (!usb_endpoint_is_isoc_in(ep)) {
3604 JOM(4, "intf[%i]alt[%i]end[%i] is a %d endpoint\n",
3605 bInterfaceNumber,
3606 i, j, ep->bmAttributes);
3607 if (usb_endpoint_dir_out(ep)) {
3608 SAM("ERROR: OUT endpoint unexpected\n");
3609 SAM("...... continuing\n");
3610 }
3611 continue;
3612 }
3613 switch (bInterfaceClass) {
3614 case USB_CLASS_VIDEO:
3615 case USB_CLASS_VENDOR_SPEC: {
3616 if (ep->wMaxPacketSize) {
3617 if (8 > isokalt) {
3618 okalt[isokalt] = i;
3619 JOM(4,
3620 "%i=okalt[%i]\n",
3621 okalt[isokalt],
3622 isokalt);
3623 okepn[isokalt] =
3624 ep->
3625 bEndpointAddress &
3626 0x0F;
3627 JOM(4,
3628 "%i=okepn[%i]\n",
3629 okepn[isokalt],
3630 isokalt);
3631 okmps[isokalt] =
3632 le16_to_cpu(ep->
3633 wMaxPacketSize);
3634 JOM(4,
3635 "%i=okmps[%i]\n",
3636 okmps[isokalt],
3637 isokalt);
3638 isokalt++;
3639 }
3640 } else {
3641 if (-1 == peasycap->
3642 video_altsetting_off) {
3643 peasycap->
3644 video_altsetting_off =
3645 i;
3646 JOM(4, "%i=video_"
3647 "altsetting_off "
3648 "<====\n",
3649 peasycap->
3650 video_altsetting_off);
3651 } else {
3652 SAM("ERROR: peasycap"
3653 "->video_altsetting_"
3654 "off already set\n");
3655 SAM("...... "
3656 "continuing with "
3657 "%i=peasycap->video_"
3658 "altsetting_off\n",
3659 peasycap->
3660 video_altsetting_off);
3661 }
3662 }
3663 break;
3664 }
3665 case USB_CLASS_AUDIO: {
3666 if (bInterfaceSubClass !=
3667 USB_SUBCLASS_AUDIOSTREAMING)
3668 break;
3669 if (!peasycap) {
3670 SAM("MISTAKE: "
3671 "peasycap is NULL\n");
3672 return -EFAULT;
3673 }
3674 if (ep->wMaxPacketSize) {
3675 if (8 > isokalt) {
3676 okalt[isokalt] = i ;
3677 JOM(4,
3678 "%i=okalt[%i]\n",
3679 okalt[isokalt],
3680 isokalt);
3681 okepn[isokalt] =
3682 ep->
3683 bEndpointAddress &
3684 0x0F;
3685 JOM(4,
3686 "%i=okepn[%i]\n",
3687 okepn[isokalt],
3688 isokalt);
3689 okmps[isokalt] =
3690 le16_to_cpu(ep->
3691 wMaxPacketSize);
3692 JOM(4,
3693 "%i=okmps[%i]\n",
3694 okmps[isokalt],
3695 isokalt);
3696 isokalt++;
3697 }
3698 } else {
3699 if (-1 == peasycap->
3700 audio_altsetting_off) {
3701 peasycap->
3702 audio_altsetting_off =
3703 i;
3704 JOM(4, "%i=audio_"
3705 "altsetting_off "
3706 "<====\n",
3707 peasycap->
3708 audio_altsetting_off);
3709 } else {
3710 SAM("ERROR: peasycap"
3711 "->audio_altsetting_"
3712 "off already set\n");
3713 SAM("...... "
3714 "continuing with "
3715 "%i=peasycap->"
3716 "audio_altsetting_"
3717 "off\n",
3718 peasycap->
3719 audio_altsetting_off);
3720 }
3721 }
3722 break;
3723 }
3724 default:
3725 break;
3726 }
3727 if (0 == ep->wMaxPacketSize) {
3728 JOM(4, "intf[%i]alt[%i]end[%i] "
3729 "has zero packet size\n",
3730 bInterfaceNumber, i, j);
3731 }
3732 }
3733 }
3734
3735 /* Perform initialization of the probed interface */
3736 JOM(4, "initialization begins for interface %i\n",
3737 interface->bInterfaceNumber);
3738 switch (bInterfaceNumber) {
3739 /* 0: Video interface */
3740 case 0: {
3741 if (!peasycap) {
3742 SAM("MISTAKE: peasycap is NULL\n");
3743 return -EFAULT;
3744 }
3745 if (!isokalt) {
3746 SAM("ERROR: no viable video_altsetting_on\n");
3747 return -ENOENT;
3748 }
3749 peasycap->video_altsetting_on = okalt[isokalt - 1];
3750 JOM(4, "%i=video_altsetting_on <====\n",
3751 peasycap->video_altsetting_on);
3752
3753 /* Decide video streaming parameters */
3754 peasycap->video_endpointnumber = okepn[isokalt - 1];
3755 JOM(4, "%i=video_endpointnumber\n", peasycap->video_endpointnumber);
3756 maxpacketsize = okmps[isokalt - 1];
3757
3758 peasycap->video_isoc_maxframesize =
3759 min(maxpacketsize, USB_2_0_MAXPACKETSIZE);
3760 if (0 >= peasycap->video_isoc_maxframesize) {
3761 SAM("ERROR: bad video_isoc_maxframesize\n");
3762 SAM(" possibly because port is USB 1.1\n");
3763 return -ENOENT;
3764 }
3765 JOM(4, "%i=video_isoc_maxframesize\n",
3766 peasycap->video_isoc_maxframesize);
3767
3768 peasycap->video_isoc_framesperdesc = VIDEO_ISOC_FRAMESPERDESC;
3769 JOM(4, "%i=video_isoc_framesperdesc\n",
3770 peasycap->video_isoc_framesperdesc);
3771 if (0 >= peasycap->video_isoc_framesperdesc) {
3772 SAM("ERROR: bad video_isoc_framesperdesc\n");
3773 return -ENOENT;
3774 }
3775 peasycap->video_isoc_buffer_size =
3776 peasycap->video_isoc_maxframesize *
3777 peasycap->video_isoc_framesperdesc;
3778 JOM(4, "%i=video_isoc_buffer_size\n",
3779 peasycap->video_isoc_buffer_size);
3780 if ((PAGE_SIZE << VIDEO_ISOC_ORDER) <
3781 peasycap->video_isoc_buffer_size) {
3782 SAM("MISTAKE: peasycap->video_isoc_buffer_size too big\n");
3783 return -EFAULT;
3784 }
3785 if (-1 == peasycap->video_interface) {
3786 SAM("MISTAKE: video_interface is unset\n");
3787 return -EFAULT;
3788 }
3789 if (-1 == peasycap->video_altsetting_on) {
3790 SAM("MISTAKE: video_altsetting_on is unset\n");
3791 return -EFAULT;
3792 }
3793 if (-1 == peasycap->video_altsetting_off) {
3794 SAM("MISTAKE: video_interface_off is unset\n");
3795 return -EFAULT;
3796 }
3797 if (-1 == peasycap->video_endpointnumber) {
3798 SAM("MISTAKE: video_endpointnumber is unset\n");
3799 return -EFAULT;
3800 }
3801 if (-1 == peasycap->video_isoc_maxframesize) {
3802 SAM("MISTAKE: video_isoc_maxframesize is unset\n");
3803 return -EFAULT;
3804 }
3805 if (-1 == peasycap->video_isoc_buffer_size) {
3806 SAM("MISTAKE: video_isoc_buffer_size is unset\n");
3807 return -EFAULT;
3808 }
3809
3810 /*
3811 * Allocate memory for video buffers.
3812 * Lists must be initialized first.
3813 */
3814 INIT_LIST_HEAD(&(peasycap->urb_video_head));
3815 peasycap->purb_video_head = &(peasycap->urb_video_head);
3816
3817 rc = alloc_framebuffers(peasycap);
3818 if (rc < 0)
3819 return rc;
3820
3821 rc = alloc_fieldbuffers(peasycap);
3822 if (rc < 0)
3823 return rc;
3824
3825 rc = alloc_isocbuffers(peasycap);
3826 if (rc < 0)
3827 return rc;
3828
3829 /* Allocate and initialize video urbs */
3830 rc = create_video_urbs(peasycap);
3831 if (rc < 0)
3832 return rc;
3833
3834 /* Save pointer peasycap in this interface */
3835 usb_set_intfdata(intf, peasycap);
3836
3837 /*
3838 * It is essential to initialize the hardware before,
3839 * rather than after, the device is registered,
3840 * because some udev rules triggers easycap_open()
3841 * immediately after registration, causing a clash.
3842 */
3843 rc = reset(peasycap);
3844 if (rc) {
3845 SAM("ERROR: reset() rc = %i\n", rc);
3846 return -EFAULT;
3847 }
3848
3849 /* The video device can now be registered */
3850 if (v4l2_device_register(&intf->dev, &peasycap->v4l2_device)) {
3851 SAM("v4l2_device_register() failed\n");
3852 return -ENODEV;
3853 }
3854 JOM(4, "registered device instance: %s\n",
3855 peasycap->v4l2_device.name);
3856
3857 rc = easycap_register_video(peasycap);
3858 if (rc < 0) {
3859 dev_err(&intf->dev,
3860 "Not able to register with videodev\n");
3861 return -ENODEV;
3862 }
3863 break;
3864 }
3865 /* 1: Audio control */
3866 case 1: {
3867 if (!peasycap) {
3868 SAM("MISTAKE: peasycap is NULL\n");
3869 return -EFAULT;
3870 }
3871 /* Save pointer peasycap in this interface */
3872 usb_set_intfdata(intf, peasycap);
3873 JOM(4, "no initialization required for interface %i\n",
3874 interface->bInterfaceNumber);
3875 break;
3876 }
3877 /* 2: Audio streaming */
3878 case 2: {
3879 if (!peasycap) {
3880 SAM("MISTAKE: peasycap is NULL\n");
3881 return -EFAULT;
3882 }
3883 if (!isokalt) {
3884 SAM("ERROR: no viable audio_altsetting_on\n");
3885 return -ENOENT;
3886 }
3887 peasycap->audio_altsetting_on = okalt[isokalt - 1];
3888 JOM(4, "%i=audio_altsetting_on <====\n",
3889 peasycap->audio_altsetting_on);
3890
3891 peasycap->audio_endpointnumber = okepn[isokalt - 1];
3892 JOM(4, "%i=audio_endpointnumber\n", peasycap->audio_endpointnumber);
3893
3894 peasycap->audio_isoc_maxframesize = okmps[isokalt - 1];
3895 JOM(4, "%i=audio_isoc_maxframesize\n",
3896 peasycap->audio_isoc_maxframesize);
3897 if (0 >= peasycap->audio_isoc_maxframesize) {
3898 SAM("ERROR: bad audio_isoc_maxframesize\n");
3899 return -ENOENT;
3900 }
3901 if (9 == peasycap->audio_isoc_maxframesize) {
3902 peasycap->ilk |= 0x02;
3903 SAM("audio hardware is microphone\n");
3904 peasycap->microphone = true;
3905 peasycap->audio_pages_per_fragment =
3906 PAGES_PER_AUDIO_FRAGMENT;
3907 } else if (256 == peasycap->audio_isoc_maxframesize) {
3908 peasycap->ilk &= ~0x02;
3909 SAM("audio hardware is AC'97\n");
3910 peasycap->microphone = false;
3911 peasycap->audio_pages_per_fragment =
3912 PAGES_PER_AUDIO_FRAGMENT;
3913 } else {
3914 SAM("hardware is unidentified:\n");
3915 SAM("%i=audio_isoc_maxframesize\n",
3916 peasycap->audio_isoc_maxframesize);
3917 return -ENOENT;
3918 }
3919
3920 peasycap->audio_bytes_per_fragment =
3921 peasycap->audio_pages_per_fragment * PAGE_SIZE;
3922 peasycap->audio_buffer_page_many = (AUDIO_FRAGMENT_MANY *
3923 peasycap->audio_pages_per_fragment);
3924
3925 JOM(4, "%6i=AUDIO_FRAGMENT_MANY\n", AUDIO_FRAGMENT_MANY);
3926 JOM(4, "%6i=audio_pages_per_fragment\n",
3927 peasycap->audio_pages_per_fragment);
3928 JOM(4, "%6i=audio_bytes_per_fragment\n",
3929 peasycap->audio_bytes_per_fragment);
3930 JOM(4, "%6i=audio_buffer_page_many\n",
3931 peasycap->audio_buffer_page_many);
3932
3933 peasycap->audio_isoc_framesperdesc = AUDIO_ISOC_FRAMESPERDESC;
3934
3935 JOM(4, "%i=audio_isoc_framesperdesc\n",
3936 peasycap->audio_isoc_framesperdesc);
3937 if (0 >= peasycap->audio_isoc_framesperdesc) {
3938 SAM("ERROR: bad audio_isoc_framesperdesc\n");
3939 return -ENOENT;
3940 }
3941
3942 peasycap->audio_isoc_buffer_size =
3943 peasycap->audio_isoc_maxframesize *
3944 peasycap->audio_isoc_framesperdesc;
3945 JOM(4, "%i=audio_isoc_buffer_size\n",
3946 peasycap->audio_isoc_buffer_size);
3947 if (AUDIO_ISOC_BUFFER_SIZE < peasycap->audio_isoc_buffer_size) {
3948 SAM("MISTAKE: audio_isoc_buffer_size bigger "
3949 "than %li=AUDIO_ISOC_BUFFER_SIZE\n",
3950 AUDIO_ISOC_BUFFER_SIZE);
3951 return -EFAULT;
3952 }
3953 if (-1 == peasycap->audio_interface) {
3954 SAM("MISTAKE: audio_interface is unset\n");
3955 return -EFAULT;
3956 }
3957 if (-1 == peasycap->audio_altsetting_on) {
3958 SAM("MISTAKE: audio_altsetting_on is unset\n");
3959 return -EFAULT;
3960 }
3961 if (-1 == peasycap->audio_altsetting_off) {
3962 SAM("MISTAKE: audio_interface_off is unset\n");
3963 return -EFAULT;
3964 }
3965 if (-1 == peasycap->audio_endpointnumber) {
3966 SAM("MISTAKE: audio_endpointnumber is unset\n");
3967 return -EFAULT;
3968 }
3969 if (-1 == peasycap->audio_isoc_maxframesize) {
3970 SAM("MISTAKE: audio_isoc_maxframesize is unset\n");
3971 return -EFAULT;
3972 }
3973 if (-1 == peasycap->audio_isoc_buffer_size) {
3974 SAM("MISTAKE: audio_isoc_buffer_size is unset\n");
3975 return -EFAULT;
3976 }
3977
3978 /*
3979 * Allocate memory for audio buffers.
3980 * Lists must be initialized first.
3981 */
3982 INIT_LIST_HEAD(&(peasycap->urb_audio_head));
3983 peasycap->purb_audio_head = &(peasycap->urb_audio_head);
3984
3985 alloc_audio_buffers(peasycap);
3986 if (rc < 0)
3987 return rc;
3988
3989 /* Allocate and initialize urbs */
3990 rc = create_audio_urbs(peasycap);
3991 if (rc < 0)
3992 return rc;
3993
3994 /* Save pointer peasycap in this interface */
3995 usb_set_intfdata(intf, peasycap);
3996
3997 /* The audio device can now be registered */
3998 JOM(4, "initializing ALSA card\n");
3999
4000 rc = easycap_alsa_probe(peasycap);
4001 if (rc) {
4002 dev_err(&intf->dev, "easycap_alsa_probe() rc = %i\n",
4003 rc);
4004 return -ENODEV;
4005 }
4006
4007
4008 JOM(8, "kref_get() with %i=kref.refcount.counter\n",
4009 peasycap->kref.refcount.counter);
4010 kref_get(&peasycap->kref);
4011 peasycap->registered_audio++;
4012 break;
4013 }
4014 /* Interfaces other than 0,1,2 are unexpected */
4015 default:
4016 JOM(4, "ERROR: unexpected interface %i\n", bInterfaceNumber);
4017 return -EINVAL;
4018 }
4019 SAM("ends successfully for interface %i\n", bInterfaceNumber);
4020 return 0;
4021}
4022
4023/*
4024 * When this function is called the device has already been
4025 * physically unplugged.
4026 * Hence, peasycap->pusb_device is no longer valid.
4027 * This function affects alsa.
4028 */
4029static void easycap_usb_disconnect(struct usb_interface *pusb_interface)
4030{
4031 struct usb_host_interface *pusb_host_interface;
4032 struct usb_interface_descriptor *pusb_interface_descriptor;
4033 struct easycap *peasycap;
4034 int minor, kd;
4035 u8 bInterfaceNumber;
4036
4037 JOT(4, "\n");
4038
4039 pusb_host_interface = pusb_interface->cur_altsetting;
4040 if (!pusb_host_interface) {
4041 JOT(4, "ERROR: pusb_host_interface is NULL\n");
4042 return;
4043 }
4044 pusb_interface_descriptor = &(pusb_host_interface->desc);
4045 if (!pusb_interface_descriptor) {
4046 JOT(4, "ERROR: pusb_interface_descriptor is NULL\n");
4047 return;
4048 }
4049 bInterfaceNumber = pusb_interface_descriptor->bInterfaceNumber;
4050 minor = pusb_interface->minor;
4051 JOT(4, "intf[%i]: minor=%i\n", bInterfaceNumber, minor);
4052
4053 /* There is nothing to do for Interface Number 1 */
4054 if (1 == bInterfaceNumber)
4055 return;
4056
4057 peasycap = usb_get_intfdata(pusb_interface);
4058 if (!peasycap) {
4059 SAY("ERROR: peasycap is NULL\n");
4060 return;
4061 }
4062
4063 /* If the waitqueues are not cleared a deadlock is possible */
4064 peasycap->video_eof = 1;
4065 peasycap->audio_eof = 1;
4066 wake_up_interruptible(&(peasycap->wq_video));
4067 wake_up_interruptible(&(peasycap->wq_audio));
4068
4069 switch (bInterfaceNumber) {
4070 case 0:
4071 easycap_video_kill_urbs(peasycap);
4072 break;
4073 case 2:
4074 easycap_audio_kill_urbs(peasycap);
4075 break;
4076 default:
4077 break;
4078 }
4079
4080 /*
4081 * Deregister
4082 * This procedure will block until easycap_poll(),
4083 * video and audio ioctl are all unlocked.
4084 * If this is not done an oops can occur when an easycap
4085 * is unplugged while the urbs are running.
4086 */
4087 kd = easycap_isdongle(peasycap);
4088 switch (bInterfaceNumber) {
4089 case 0: {
4090 if (0 <= kd && DONGLE_MANY > kd) {
4091 wake_up_interruptible(&peasycap->wq_video);
4092 JOM(4, "about to lock dongle[%i].mutex_video\n", kd);
4093 if (mutex_lock_interruptible(&easycapdc60_dongle[kd].
4094 mutex_video)) {
4095 SAY("ERROR: "
4096 "cannot lock dongle[%i].mutex_video\n", kd);
4097 return;
4098 }
4099 JOM(4, "locked dongle[%i].mutex_video\n", kd);
4100 } else {
4101 SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd);
4102 }
4103 if (!peasycap->v4l2_device.name[0]) {
4104 SAM("ERROR: peasycap->v4l2_device.name is empty\n");
4105 if (0 <= kd && DONGLE_MANY > kd)
4106 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
4107 return;
4108 }
4109 v4l2_device_disconnect(&peasycap->v4l2_device);
4110 JOM(4, "v4l2_device_disconnect() OK\n");
4111 v4l2_device_unregister(&peasycap->v4l2_device);
4112 JOM(4, "v4l2_device_unregister() OK\n");
4113
4114 video_unregister_device(&peasycap->video_device);
4115 JOM(4, "intf[%i]: video_unregister_device() minor=%i\n",
4116 bInterfaceNumber, minor);
4117 peasycap->registered_video--;
4118
4119 if (0 <= kd && DONGLE_MANY > kd) {
4120 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
4121 JOM(4, "unlocked dongle[%i].mutex_video\n", kd);
4122 }
4123 break;
4124 }
4125 case 2: {
4126 if (0 <= kd && DONGLE_MANY > kd) {
4127 wake_up_interruptible(&peasycap->wq_audio);
4128 JOM(4, "about to lock dongle[%i].mutex_audio\n", kd);
4129 if (mutex_lock_interruptible(&easycapdc60_dongle[kd].
4130 mutex_audio)) {
4131 SAY("ERROR: "
4132 "cannot lock dongle[%i].mutex_audio\n", kd);
4133 return;
4134 }
4135 JOM(4, "locked dongle[%i].mutex_audio\n", kd);
4136 } else
4137 SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd);
4138 if (0 != snd_card_free(peasycap->psnd_card)) {
4139 SAY("ERROR: snd_card_free() failed\n");
4140 } else {
4141 peasycap->psnd_card = NULL;
4142 (peasycap->registered_audio)--;
4143 }
4144 if (0 <= kd && DONGLE_MANY > kd) {
4145 mutex_unlock(&easycapdc60_dongle[kd].mutex_audio);
4146 JOM(4, "unlocked dongle[%i].mutex_audio\n", kd);
4147 }
4148 break;
4149 }
4150 default:
4151 break;
4152 }
4153
4154 /*
4155 * If no remaining references to peasycap,
4156 * call easycap_delete.
4157 * (Also when alsa has been in use)
4158 */
4159 if (!peasycap->kref.refcount.counter) {
4160 SAM("ERROR: peasycap->kref.refcount.counter is zero "
4161 "so cannot call kref_put()\n");
4162 SAM("ending unsuccessfully: may cause memory leak\n");
4163 return;
4164 }
4165 if (0 <= kd && DONGLE_MANY > kd) {
4166 JOM(4, "about to lock dongle[%i].mutex_video\n", kd);
4167 if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) {
4168 SAY("ERROR: cannot lock dongle[%i].mutex_video\n", kd);
4169 SAM("ending unsuccessfully: may cause memory leak\n");
4170 return;
4171 }
4172 JOM(4, "locked dongle[%i].mutex_video\n", kd);
4173 JOM(4, "about to lock dongle[%i].mutex_audio\n", kd);
4174 if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_audio)) {
4175 SAY("ERROR: cannot lock dongle[%i].mutex_audio\n", kd);
4176 mutex_unlock(&(easycapdc60_dongle[kd].mutex_video));
4177 JOM(4, "unlocked dongle[%i].mutex_video\n", kd);
4178 SAM("ending unsuccessfully: may cause memory leak\n");
4179 return;
4180 }
4181 JOM(4, "locked dongle[%i].mutex_audio\n", kd);
4182 }
4183 JOM(4, "intf[%i]: %i=peasycap->kref.refcount.counter\n",
4184 bInterfaceNumber, (int)peasycap->kref.refcount.counter);
4185 kref_put(&peasycap->kref, easycap_delete);
4186 JOT(4, "intf[%i]: kref_put() done.\n", bInterfaceNumber);
4187 if (0 <= kd && DONGLE_MANY > kd) {
4188 mutex_unlock(&(easycapdc60_dongle[kd].mutex_audio));
4189 JOT(4, "unlocked dongle[%i].mutex_audio\n", kd);
4190 mutex_unlock(&easycapdc60_dongle[kd].mutex_video);
4191 JOT(4, "unlocked dongle[%i].mutex_video\n", kd);
4192 }
4193 JOM(4, "ends\n");
4194 return;
4195}
4196
4197/* Devices supported by this driver */
4198static struct usb_device_id easycap_usb_device_id_table[] = {
4199 {USB_DEVICE(USB_EASYCAP_VENDOR_ID, USB_EASYCAP_PRODUCT_ID)},
4200 { }
4201};
4202
4203MODULE_DEVICE_TABLE(usb, easycap_usb_device_id_table);
4204static struct usb_driver easycap_usb_driver = {
4205 .name = "easycap",
4206 .id_table = easycap_usb_device_id_table,
4207 .probe = easycap_usb_probe,
4208 .disconnect = easycap_usb_disconnect,
4209};
4210
4211static int __init easycap_module_init(void)
4212{
4213 int k, rc;
4214
4215 printk(KERN_INFO "Easycap version: "EASYCAP_DRIVER_VERSION "\n");
4216
4217 JOT(4, "begins. %i=debug %i=bars %i=gain\n",
4218 easycap_debug, easycap_bars, easycap_gain);
4219
4220 mutex_init(&mutex_dongle);
4221 for (k = 0; k < DONGLE_MANY; k++) {
4222 easycapdc60_dongle[k].peasycap = NULL;
4223 mutex_init(&easycapdc60_dongle[k].mutex_video);
4224 mutex_init(&easycapdc60_dongle[k].mutex_audio);
4225 }
4226 rc = usb_register(&easycap_usb_driver);
4227 if (rc)
4228 printk(KERN_ERR "Easycap: usb_register failed rc=%d\n", rc);
4229
4230 return rc;
4231}
4232
4233static void __exit easycap_module_exit(void)
4234{
4235 usb_deregister(&easycap_usb_driver);
4236}
4237
4238module_init(easycap_module_init);
4239module_exit(easycap_module_exit);
diff --git a/drivers/staging/media/easycap/easycap_settings.c b/drivers/staging/media/easycap/easycap_settings.c
deleted file mode 100644
index 3f5f5b3e5a35..000000000000
--- a/drivers/staging/media/easycap/easycap_settings.c
+++ /dev/null
@@ -1,696 +0,0 @@
1/******************************************************************************
2* *
3* easycap_settings.c *
4* *
5******************************************************************************/
6/*
7 *
8 * Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
9 *
10 *
11 * This is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The software is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this software; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25*/
26/*****************************************************************************/
27
28#include "easycap.h"
29
30/*---------------------------------------------------------------------------*/
31/*
32 * THE LEAST SIGNIFICANT BIT OF easycap_standard.mask HAS MEANING:
33 * 0 => 25 fps
34 * 1 => 30 fps
35 *
36 * THE MOST SIGNIFICANT BIT OF easycap_standard.mask HAS MEANING:
37 * 0 => full framerate
38 * 1 => 20% framerate
39 */
40/*---------------------------------------------------------------------------*/
41const struct easycap_standard easycap_standard[] = {
42 {
43 .mask = 0x00FF & PAL_BGHIN ,
44 .v4l2_standard = {
45 .index = PAL_BGHIN,
46 .id = (V4L2_STD_PAL_B |
47 V4L2_STD_PAL_G | V4L2_STD_PAL_H |
48 V4L2_STD_PAL_I | V4L2_STD_PAL_N),
49 .name = "PAL_BGHIN",
50 .frameperiod = {1, 25},
51 .framelines = 625,
52 .reserved = {0, 0, 0, 0}
53 }
54 },
55/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
56 {
57 .mask = 0x00FF & NTSC_N_443 ,
58 .v4l2_standard = {
59 .index = NTSC_N_443,
60 .id = V4L2_STD_UNKNOWN,
61 .name = "NTSC_N_443",
62 .frameperiod = {1, 25},
63 .framelines = 480,
64 .reserved = {0, 0, 0, 0}
65 }
66 },
67/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
68 {
69 .mask = 0x00FF & PAL_Nc ,
70 .v4l2_standard = {
71 .index = PAL_Nc,
72 .id = V4L2_STD_PAL_Nc,
73 .name = "PAL_Nc",
74 .frameperiod = {1, 25},
75 .framelines = 625,
76 .reserved = {0, 0, 0, 0}
77 }
78 },
79/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
80 {
81 .mask = 0x00FF & NTSC_N ,
82 .v4l2_standard = {
83 .index = NTSC_N,
84 .id = V4L2_STD_UNKNOWN,
85 .name = "NTSC_N",
86 .frameperiod = {1, 25},
87 .framelines = 525,
88 .reserved = {0, 0, 0, 0}
89 }
90 },
91/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
92 {
93 .mask = 0x00FF & SECAM ,
94 .v4l2_standard = {
95 .index = SECAM,
96 .id = V4L2_STD_SECAM,
97 .name = "SECAM",
98 .frameperiod = {1, 25},
99 .framelines = 625,
100 .reserved = {0, 0, 0, 0}
101 }
102 },
103/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
104 {
105 .mask = 0x00FF & NTSC_M ,
106 .v4l2_standard = {
107 .index = NTSC_M,
108 .id = V4L2_STD_NTSC_M,
109 .name = "NTSC_M",
110 .frameperiod = {1, 30},
111 .framelines = 525,
112 .reserved = {0, 0, 0, 0}
113 }
114 },
115/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
116 {
117 .mask = 0x00FF & NTSC_M_JP ,
118 .v4l2_standard = {
119 .index = NTSC_M_JP,
120 .id = V4L2_STD_NTSC_M_JP,
121 .name = "NTSC_M_JP",
122 .frameperiod = {1, 30},
123 .framelines = 525,
124 .reserved = {0, 0, 0, 0}
125 }
126 },
127/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
128 {
129 .mask = 0x00FF & PAL_60 ,
130 .v4l2_standard = {
131 .index = PAL_60,
132 .id = V4L2_STD_PAL_60,
133 .name = "PAL_60",
134 .frameperiod = {1, 30},
135 .framelines = 525,
136 .reserved = {0, 0, 0, 0}
137 }
138 },
139/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
140 {
141 .mask = 0x00FF & NTSC_443 ,
142 .v4l2_standard = {
143 .index = NTSC_443,
144 .id = V4L2_STD_NTSC_443,
145 .name = "NTSC_443",
146 .frameperiod = {1, 30},
147 .framelines = 525,
148 .reserved = {0, 0, 0, 0}
149 }
150 },
151/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
152 {
153 .mask = 0x00FF & PAL_M ,
154 .v4l2_standard = {
155 .index = PAL_M,
156 .id = V4L2_STD_PAL_M,
157 .name = "PAL_M",
158 .frameperiod = {1, 30},
159 .framelines = 525,
160 .reserved = {0, 0, 0, 0}
161 }
162 },
163/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
164 {
165 .mask = 0x8000 | (0x00FF & PAL_BGHIN_SLOW),
166 .v4l2_standard = {
167 .index = PAL_BGHIN_SLOW,
168 .id = (V4L2_STD_PAL_B | V4L2_STD_PAL_G |
169 V4L2_STD_PAL_H |
170 V4L2_STD_PAL_I | V4L2_STD_PAL_N |
171 (((v4l2_std_id)0x01) << 32)),
172 .name = "PAL_BGHIN_SLOW",
173 .frameperiod = {1, 5},
174 .framelines = 625,
175 .reserved = {0, 0, 0, 0}
176 }
177 },
178/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
179 {
180 .mask = 0x8000 | (0x00FF & NTSC_N_443_SLOW),
181 .v4l2_standard = {
182 .index = NTSC_N_443_SLOW,
183 .id = (V4L2_STD_UNKNOWN | (((v4l2_std_id)0x11) << 32)),
184 .name = "NTSC_N_443_SLOW",
185 .frameperiod = {1, 5},
186 .framelines = 480,
187 .reserved = {0, 0, 0, 0}
188 }
189 },
190/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
191 {
192 .mask = 0x8000 | (0x00FF & PAL_Nc_SLOW),
193 .v4l2_standard = {
194 .index = PAL_Nc_SLOW,
195 .id = (V4L2_STD_PAL_Nc | (((v4l2_std_id)0x01) << 32)),
196 .name = "PAL_Nc_SLOW",
197 .frameperiod = {1, 5},
198 .framelines = 625,
199 .reserved = {0, 0, 0, 0}
200 }
201 },
202/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
203 {
204 .mask = 0x8000 | (0x00FF & NTSC_N_SLOW),
205 .v4l2_standard = {
206 .index = NTSC_N_SLOW,
207 .id = (V4L2_STD_UNKNOWN | (((v4l2_std_id)0x21) << 32)),
208 .name = "NTSC_N_SLOW",
209 .frameperiod = {1, 5},
210 .framelines = 525,
211 .reserved = {0, 0, 0, 0}
212 }
213 },
214/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
215 {
216 .mask = 0x8000 | (0x00FF & SECAM_SLOW),
217 .v4l2_standard = {
218 .index = SECAM_SLOW,
219 .id = (V4L2_STD_SECAM | (((v4l2_std_id)0x01) << 32)),
220 .name = "SECAM_SLOW",
221 .frameperiod = {1, 5},
222 .framelines = 625,
223 .reserved = {0, 0, 0, 0}
224 }
225 },
226/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
227 {
228 .mask = 0x8000 | (0x00FF & NTSC_M_SLOW),
229 .v4l2_standard = {
230 .index = NTSC_M_SLOW,
231 .id = (V4L2_STD_NTSC_M | (((v4l2_std_id)0x01) << 32)),
232 .name = "NTSC_M_SLOW",
233 .frameperiod = {1, 6},
234 .framelines = 525,
235 .reserved = {0, 0, 0, 0}
236 }
237 },
238/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
239 {
240 .mask = 0x8000 | (0x00FF & NTSC_M_JP_SLOW),
241 .v4l2_standard = {
242 .index = NTSC_M_JP_SLOW,
243 .id = (V4L2_STD_NTSC_M_JP |
244 (((v4l2_std_id)0x01) << 32)),
245 .name = "NTSC_M_JP_SLOW",
246 .frameperiod = {1, 6},
247 .framelines = 525,
248 .reserved = {0, 0, 0, 0}
249 }
250 },
251/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
252 {
253 .mask = 0x8000 | (0x00FF & PAL_60_SLOW),
254 .v4l2_standard = {
255 .index = PAL_60_SLOW,
256 .id = (V4L2_STD_PAL_60 | (((v4l2_std_id)0x01) << 32)),
257 .name = "PAL_60_SLOW",
258 .frameperiod = {1, 6},
259 .framelines = 525,
260 .reserved = {0, 0, 0, 0}
261 }
262 },
263/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
264 {
265 .mask = 0x8000 | (0x00FF & NTSC_443_SLOW),
266 .v4l2_standard = {
267 .index = NTSC_443_SLOW,
268 .id = (V4L2_STD_NTSC_443 | (((v4l2_std_id)0x01) << 32)),
269 .name = "NTSC_443_SLOW",
270 .frameperiod = {1, 6},
271 .framelines = 525,
272 .reserved = {0, 0, 0, 0}
273 }
274 },
275/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
276 {
277 .mask = 0x8000 | (0x00FF & PAL_M_SLOW),
278 .v4l2_standard = {
279 .index = PAL_M_SLOW,
280 .id = (V4L2_STD_PAL_M | (((v4l2_std_id)0x01) << 32)),
281 .name = "PAL_M_SLOW",
282 .frameperiod = {1, 6},
283 .framelines = 525,
284 .reserved = {0, 0, 0, 0}
285 }
286 },
287/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
288 {
289 .mask = 0xFFFF
290 }
291};
292/*---------------------------------------------------------------------------*/
293/*
294 * THE 16-BIT easycap_format.mask HAS MEANING:
295 * (least significant) BIT 0: 0 => PAL, 25 FPS; 1 => NTSC, 30 FPS
296 * BITS 2-4: RESERVED FOR DIFFERENTIATING STANDARDS
297 * BITS 5-7: NUMBER OF BYTES PER PIXEL
298 * BIT 8: 0 => NATIVE BYTE ORDER; 1 => SWAPPED
299 * BITS 9-10: RESERVED FOR OTHER BYTE PERMUTATIONS
300 * BIT 11: 0 => UNDECIMATED; 1 => DECIMATED
301 * BIT 12: 0 => OFFER FRAMES; 1 => OFFER FIELDS
302 * BIT 13: 0 => FULL FRAMERATE; 1 => REDUCED
303 * (most significant) BITS 14-15: RESERVED FOR OTHER FIELD/FRAME OPTIONS
304 * IT FOLLOWS THAT:
305 * bytesperpixel IS ((0x00E0 & easycap_format.mask) >> 5)
306 * byteswaporder IS true IF (0 != (0x0100 & easycap_format.mask))
307 *
308 * decimatepixel IS true IF (0 != (0x0800 & easycap_format.mask))
309 *
310 * offerfields IS true IF (0 != (0x1000 & easycap_format.mask))
311 */
312/*---------------------------------------------------------------------------*/
313
314struct easycap_format easycap_format[1 + SETTINGS_MANY];
315
316int easycap_video_fillin_formats(void)
317{
318 const char *name1, *name2, *name3, *name4;
319 struct v4l2_format *fmt;
320 int i, j, k, m, n;
321 u32 width, height, pixelformat, bytesperline, sizeimage;
322 u16 mask1, mask2, mask3, mask4;
323 enum v4l2_field field;
324 enum v4l2_colorspace colorspace;
325
326 for (i = 0, n = 0; i < STANDARD_MANY; i++) {
327 mask1 = 0x0000;
328 switch (i) {
329 case PAL_BGHIN: {
330 mask1 = 0x1F & PAL_BGHIN;
331 name1 = "PAL_BGHIN";
332 colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
333 break;
334 }
335 case SECAM: {
336 mask1 = 0x1F & SECAM;
337 name1 = "SECAM";
338 colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
339 break;
340 }
341 case PAL_Nc: {
342 mask1 = 0x1F & PAL_Nc;
343 name1 = "PAL_Nc";
344 colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
345 break;
346 }
347 case PAL_60: {
348 mask1 = 0x1F & PAL_60;
349 name1 = "PAL_60";
350 colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
351 break;
352 }
353 case PAL_M: {
354 mask1 = 0x1F & PAL_M;
355 name1 = "PAL_M";
356 colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
357 break;
358 }
359 case NTSC_M: {
360 mask1 = 0x1F & NTSC_M;
361 name1 = "NTSC_M";
362 colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
363 break;
364 }
365 case NTSC_443: {
366 mask1 = 0x1F & NTSC_443;
367 name1 = "NTSC_443";
368 colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
369 break;
370 }
371 case NTSC_M_JP: {
372 mask1 = 0x1F & NTSC_M_JP;
373 name1 = "NTSC_M_JP";
374 colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
375 break;
376 }
377 case NTSC_N: {
378 mask1 = 0x1F & NTSC_M;
379 name1 = "NTSC_N";
380 colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
381 break;
382 }
383 case NTSC_N_443: {
384 mask1 = 0x1F & NTSC_N_443;
385 name1 = "NTSC_N_443";
386 colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
387 break;
388 }
389 case PAL_BGHIN_SLOW: {
390 mask1 = 0x001F & PAL_BGHIN_SLOW;
391 mask1 |= 0x0200;
392 name1 = "PAL_BGHIN_SLOW";
393 colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
394 break;
395 }
396 case SECAM_SLOW: {
397 mask1 = 0x001F & SECAM_SLOW;
398 mask1 |= 0x0200;
399 name1 = "SECAM_SLOW";
400 colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
401 break;
402 }
403 case PAL_Nc_SLOW: {
404 mask1 = 0x001F & PAL_Nc_SLOW;
405 mask1 |= 0x0200;
406 name1 = "PAL_Nc_SLOW";
407 colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
408 break;
409 }
410 case PAL_60_SLOW: {
411 mask1 = 0x001F & PAL_60_SLOW;
412 mask1 |= 0x0200;
413 name1 = "PAL_60_SLOW";
414 colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
415 break;
416 }
417 case PAL_M_SLOW: {
418 mask1 = 0x001F & PAL_M_SLOW;
419 mask1 |= 0x0200;
420 name1 = "PAL_M_SLOW";
421 colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
422 break;
423 }
424 case NTSC_M_SLOW: {
425 mask1 = 0x001F & NTSC_M_SLOW;
426 mask1 |= 0x0200;
427 name1 = "NTSC_M_SLOW";
428 colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
429 break;
430 }
431 case NTSC_443_SLOW: {
432 mask1 = 0x001F & NTSC_443_SLOW;
433 mask1 |= 0x0200;
434 name1 = "NTSC_443_SLOW";
435 colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
436 break;
437 }
438 case NTSC_M_JP_SLOW: {
439 mask1 = 0x001F & NTSC_M_JP_SLOW;
440 mask1 |= 0x0200;
441 name1 = "NTSC_M_JP_SLOW";
442 colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
443 break;
444 }
445 case NTSC_N_SLOW: {
446 mask1 = 0x001F & NTSC_N_SLOW;
447 mask1 |= 0x0200;
448 name1 = "NTSC_N_SLOW";
449 colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
450 break;
451 }
452 case NTSC_N_443_SLOW: {
453 mask1 = 0x001F & NTSC_N_443_SLOW;
454 mask1 |= 0x0200;
455 name1 = "NTSC_N_443_SLOW";
456 colorspace = V4L2_COLORSPACE_470_SYSTEM_M;
457 break;
458 }
459 default:
460 return -1;
461 }
462
463 for (j = 0; j < RESOLUTION_MANY; j++) {
464 mask2 = 0x0000;
465 switch (j) {
466 case AT_720x576: {
467 if (0x1 & mask1)
468 continue;
469 name2 = "_AT_720x576";
470 width = 720;
471 height = 576;
472 break;
473 }
474 case AT_704x576: {
475 if (0x1 & mask1)
476 continue;
477 name2 = "_AT_704x576";
478 width = 704;
479 height = 576;
480 break;
481 }
482 case AT_640x480: {
483 name2 = "_AT_640x480";
484 width = 640;
485 height = 480;
486 break;
487 }
488 case AT_720x480: {
489 if (!(0x1 & mask1))
490 continue;
491 name2 = "_AT_720x480";
492 width = 720;
493 height = 480;
494 break;
495 }
496 case AT_360x288: {
497 if (0x1 & mask1)
498 continue;
499 name2 = "_AT_360x288";
500 width = 360;
501 height = 288;
502 mask2 = 0x0800;
503 break;
504 }
505 case AT_320x240: {
506 name2 = "_AT_320x240";
507 width = 320;
508 height = 240;
509 mask2 = 0x0800;
510 break;
511 }
512 case AT_360x240: {
513 if (!(0x1 & mask1))
514 continue;
515 name2 = "_AT_360x240";
516 width = 360;
517 height = 240;
518 mask2 = 0x0800;
519 break;
520 }
521 default:
522 return -2;
523 }
524
525 for (k = 0; k < PIXELFORMAT_MANY; k++) {
526 mask3 = 0x0000;
527 switch (k) {
528 case FMT_UYVY: {
529 name3 = __stringify(FMT_UYVY);
530 pixelformat = V4L2_PIX_FMT_UYVY;
531 mask3 |= (0x02 << 5);
532 break;
533 }
534 case FMT_YUY2: {
535 name3 = __stringify(FMT_YUY2);
536 pixelformat = V4L2_PIX_FMT_YUYV;
537 mask3 |= (0x02 << 5);
538 mask3 |= 0x0100;
539 break;
540 }
541 case FMT_RGB24: {
542 name3 = __stringify(FMT_RGB24);
543 pixelformat = V4L2_PIX_FMT_RGB24;
544 mask3 |= (0x03 << 5);
545 break;
546 }
547 case FMT_RGB32: {
548 name3 = __stringify(FMT_RGB32);
549 pixelformat = V4L2_PIX_FMT_RGB32;
550 mask3 |= (0x04 << 5);
551 break;
552 }
553 case FMT_BGR24: {
554 name3 = __stringify(FMT_BGR24);
555 pixelformat = V4L2_PIX_FMT_BGR24;
556 mask3 |= (0x03 << 5);
557 mask3 |= 0x0100;
558 break;
559 }
560 case FMT_BGR32: {
561 name3 = __stringify(FMT_BGR32);
562 pixelformat = V4L2_PIX_FMT_BGR32;
563 mask3 |= (0x04 << 5);
564 mask3 |= 0x0100;
565 break;
566 }
567 default:
568 return -3;
569 }
570 bytesperline = width * ((mask3 & 0x00E0) >> 5);
571 sizeimage = bytesperline * height;
572
573 for (m = 0; m < INTERLACE_MANY; m++) {
574 mask4 = 0x0000;
575 switch (m) {
576 case FIELD_NONE: {
577 name4 = "-n";
578 field = V4L2_FIELD_NONE;
579 break;
580 }
581 case FIELD_INTERLACED: {
582 name4 = "-i";
583 mask4 |= 0x1000;
584 field = V4L2_FIELD_INTERLACED;
585 break;
586 }
587 default:
588 return -4;
589 }
590 if (SETTINGS_MANY <= n)
591 return -5;
592
593 strcpy(easycap_format[n].name, name1);
594 strcat(easycap_format[n].name, name2);
595 strcat(easycap_format[n].name, "_");
596 strcat(easycap_format[n].name, name3);
597 strcat(easycap_format[n].name, name4);
598 easycap_format[n].mask =
599 mask1 | mask2 | mask3 | mask4;
600 fmt = &easycap_format[n].v4l2_format;
601
602 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
603 fmt->fmt.pix.width = width;
604 fmt->fmt.pix.height = height;
605 fmt->fmt.pix.pixelformat = pixelformat;
606 fmt->fmt.pix.field = field;
607 fmt->fmt.pix.bytesperline = bytesperline;
608 fmt->fmt.pix.sizeimage = sizeimage;
609 fmt->fmt.pix.colorspace = colorspace;
610 fmt->fmt.pix.priv = 0;
611 n++;
612 }
613 }
614 }
615 }
616 if ((1 + SETTINGS_MANY) <= n)
617 return -6;
618 easycap_format[n].mask = 0xFFFF;
619 return n;
620}
621/*---------------------------------------------------------------------------*/
622struct v4l2_queryctrl easycap_control[] = {
623 {
624 .id = V4L2_CID_BRIGHTNESS,
625 .type = V4L2_CTRL_TYPE_INTEGER,
626 .name = "Brightness",
627 .minimum = 0,
628 .maximum = 255,
629 .step = 1,
630 .default_value = SAA_0A_DEFAULT,
631 .flags = 0,
632 .reserved = {0, 0}
633 },
634/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
635 {
636 .id = V4L2_CID_CONTRAST,
637 .type = V4L2_CTRL_TYPE_INTEGER,
638 .name = "Contrast",
639 .minimum = 0,
640 .maximum = 255,
641 .step = 1,
642 .default_value = SAA_0B_DEFAULT + 128,
643 .flags = 0,
644 .reserved = {0, 0}
645 },
646/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
647 {
648 .id = V4L2_CID_SATURATION,
649 .type = V4L2_CTRL_TYPE_INTEGER,
650 .name = "Saturation",
651 .minimum = 0,
652 .maximum = 255,
653 .step = 1,
654 .default_value = SAA_0C_DEFAULT + 128,
655 .flags = 0,
656 .reserved = {0, 0}
657 },
658/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
659 {
660 .id = V4L2_CID_HUE,
661 .type = V4L2_CTRL_TYPE_INTEGER,
662 .name = "Hue",
663 .minimum = 0,
664 .maximum = 255,
665 .step = 1,
666 .default_value = SAA_0D_DEFAULT + 128,
667 .flags = 0,
668 .reserved = {0, 0}
669 },
670/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
671 {
672 .id = V4L2_CID_AUDIO_VOLUME,
673 .type = V4L2_CTRL_TYPE_INTEGER,
674 .name = "Volume",
675 .minimum = 0,
676 .maximum = 31,
677 .step = 1,
678 .default_value = 16,
679 .flags = 0,
680 .reserved = {0, 0}
681 },
682/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
683 {
684 .id = V4L2_CID_AUDIO_MUTE,
685 .type = V4L2_CTRL_TYPE_BOOLEAN,
686 .name = "Mute",
687 .default_value = true,
688 .flags = 0,
689 .reserved = {0, 0}
690 },
691/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
692 {
693 .id = 0xFFFFFFFF
694 }
695};
696/*****************************************************************************/
diff --git a/drivers/staging/media/easycap/easycap_sound.c b/drivers/staging/media/easycap/easycap_sound.c
deleted file mode 100644
index 8c8bcae8ded8..000000000000
--- a/drivers/staging/media/easycap/easycap_sound.c
+++ /dev/null
@@ -1,750 +0,0 @@
1/******************************************************************************
2* *
3* easycap_sound.c *
4* *
5* Audio driver for EasyCAP USB2.0 Video Capture Device DC60 *
6* *
7* *
8******************************************************************************/
9/*
10 *
11 * Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
12 *
13 *
14 * This is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * The software is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this software; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 *
28*/
29/*****************************************************************************/
30
31#include "easycap.h"
32
33/*--------------------------------------------------------------------------*/
34/*
35 * PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE
36 */
37/*--------------------------------------------------------------------------*/
38static const struct snd_pcm_hardware alsa_hardware = {
39 .info = SNDRV_PCM_INFO_BLOCK_TRANSFER |
40 SNDRV_PCM_INFO_MMAP |
41 SNDRV_PCM_INFO_INTERLEAVED |
42 SNDRV_PCM_INFO_MMAP_VALID,
43 .formats = SNDRV_PCM_FMTBIT_S16_LE,
44 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
45 .rate_min = 32000,
46 .rate_max = 48000,
47 .channels_min = 2,
48 .channels_max = 2,
49 .buffer_bytes_max = PAGE_SIZE *
50 PAGES_PER_AUDIO_FRAGMENT *
51 AUDIO_FRAGMENT_MANY,
52 .period_bytes_min = PAGE_SIZE * PAGES_PER_AUDIO_FRAGMENT,
53 .period_bytes_max = PAGE_SIZE * PAGES_PER_AUDIO_FRAGMENT * 2,
54 .periods_min = AUDIO_FRAGMENT_MANY,
55 .periods_max = AUDIO_FRAGMENT_MANY * 2,
56};
57
58
59/*---------------------------------------------------------------------------*/
60/*
61 * SUBMIT ALL AUDIO URBS.
62 */
63/*---------------------------------------------------------------------------*/
64static int easycap_audio_submit_urbs(struct easycap *peasycap)
65{
66 struct data_urb *pdata_urb;
67 struct urb *purb;
68 struct list_head *plist_head;
69 int j, isbad, nospc, m, rc;
70 int isbuf;
71
72 if (!peasycap->purb_audio_head) {
73 SAM("ERROR: peasycap->urb_audio_head uninitialized\n");
74 return -EFAULT;
75 }
76 if (!peasycap->pusb_device) {
77 SAM("ERROR: peasycap->pusb_device is NULL\n");
78 return -EFAULT;
79 }
80
81 if (peasycap->audio_isoc_streaming) {
82 JOM(4, "already streaming audio urbs\n");
83 return 0;
84 }
85
86 JOM(4, "initial submission of all audio urbs\n");
87 rc = usb_set_interface(peasycap->pusb_device,
88 peasycap->audio_interface,
89 peasycap->audio_altsetting_on);
90 JOM(8, "usb_set_interface(.,%i,%i) returned %i\n",
91 peasycap->audio_interface,
92 peasycap->audio_altsetting_on, rc);
93
94 isbad = 0;
95 nospc = 0;
96 m = 0;
97 list_for_each(plist_head, peasycap->purb_audio_head) {
98 pdata_urb = list_entry(plist_head, struct data_urb, list_head);
99 if (pdata_urb && pdata_urb->purb) {
100 purb = pdata_urb->purb;
101 isbuf = pdata_urb->isbuf;
102
103 purb->interval = 1;
104 purb->dev = peasycap->pusb_device;
105 purb->pipe = usb_rcvisocpipe(peasycap->pusb_device,
106 peasycap->audio_endpointnumber);
107 purb->transfer_flags = URB_ISO_ASAP;
108 purb->transfer_buffer = peasycap->audio_isoc_buffer[isbuf].pgo;
109 purb->transfer_buffer_length = peasycap->audio_isoc_buffer_size;
110 purb->complete = easycap_alsa_complete;
111 purb->context = peasycap;
112 purb->start_frame = 0;
113 purb->number_of_packets = peasycap->audio_isoc_framesperdesc;
114 for (j = 0; j < peasycap->audio_isoc_framesperdesc; j++) {
115 purb->iso_frame_desc[j].offset = j * peasycap->audio_isoc_maxframesize;
116 purb->iso_frame_desc[j].length = peasycap->audio_isoc_maxframesize;
117 }
118
119 rc = usb_submit_urb(purb, GFP_KERNEL);
120 if (rc) {
121 isbad++;
122 SAM("ERROR: usb_submit_urb() failed"
123 " for urb with rc: -%s: %d\n",
124 strerror(rc), rc);
125 } else {
126 m++;
127 }
128 } else {
129 isbad++;
130 }
131 }
132 if (nospc) {
133 SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc);
134 SAM("..... possibly inadequate USB bandwidth\n");
135 peasycap->audio_eof = 1;
136 }
137
138 if (isbad)
139 easycap_audio_kill_urbs(peasycap);
140 else
141 peasycap->audio_isoc_streaming = m;
142
143 return 0;
144}
145/*---------------------------------------------------------------------------*/
146/*
147 * COMMON AUDIO INITIALIZATION
148 */
149/*---------------------------------------------------------------------------*/
150static int easycap_sound_setup(struct easycap *peasycap)
151{
152 int rc;
153
154 JOM(4, "starting initialization\n");
155
156 if (!peasycap) {
157 SAY("ERROR: peasycap is NULL.\n");
158 return -EFAULT;
159 }
160 if (!peasycap->pusb_device) {
161 SAM("ERROR: peasycap->pusb_device is NULL\n");
162 return -ENODEV;
163 }
164 JOM(16, "0x%08lX=peasycap->pusb_device\n", (long int)peasycap->pusb_device);
165
166 rc = easycap_audio_setup(peasycap);
167 JOM(8, "audio_setup() returned %i\n", rc);
168
169 if (!peasycap->pusb_device) {
170 SAM("ERROR: peasycap->pusb_device has become NULL\n");
171 return -ENODEV;
172 }
173/*---------------------------------------------------------------------------*/
174 if (!peasycap->pusb_device) {
175 SAM("ERROR: peasycap->pusb_device has become NULL\n");
176 return -ENODEV;
177 }
178 rc = usb_set_interface(peasycap->pusb_device, peasycap->audio_interface,
179 peasycap->audio_altsetting_on);
180 JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", peasycap->audio_interface,
181 peasycap->audio_altsetting_on, rc);
182
183 rc = easycap_wakeup_device(peasycap->pusb_device);
184 JOM(8, "wakeup_device() returned %i\n", rc);
185
186 peasycap->audio_eof = 0;
187 peasycap->audio_idle = 0;
188
189 easycap_audio_submit_urbs(peasycap);
190
191 JOM(4, "finished initialization\n");
192 return 0;
193}
194/*****************************************************************************/
195/*---------------------------------------------------------------------------*/
196/*
197 * ON COMPLETION OF AN AUDIO URB ITS DATA IS COPIED TO THE DAM BUFFER
198 * PROVIDED peasycap->audio_idle IS ZERO. REGARDLESS OF THIS BEING TRUE,
199 * IT IS RESUBMITTED PROVIDED peasycap->audio_isoc_streaming IS NOT ZERO.
200 */
201/*---------------------------------------------------------------------------*/
202void easycap_alsa_complete(struct urb *purb)
203{
204 struct easycap *peasycap;
205 struct snd_pcm_substream *pss;
206 struct snd_pcm_runtime *prt;
207 int dma_bytes, fragment_bytes;
208 int isfragment;
209 u8 *p1, *p2;
210 s16 tmp;
211 int i, j, more, much, rc;
212#ifdef UPSAMPLE
213 int k;
214 s16 oldaudio, newaudio, delta;
215#endif /*UPSAMPLE*/
216
217 JOT(16, "\n");
218
219 if (!purb) {
220 SAY("ERROR: purb is NULL\n");
221 return;
222 }
223 peasycap = purb->context;
224 if (!peasycap) {
225 SAY("ERROR: peasycap is NULL\n");
226 return;
227 }
228 much = 0;
229 if (peasycap->audio_idle) {
230 JOM(16, "%i=audio_idle %i=audio_isoc_streaming\n",
231 peasycap->audio_idle, peasycap->audio_isoc_streaming);
232 if (peasycap->audio_isoc_streaming)
233 goto resubmit;
234 }
235/*---------------------------------------------------------------------------*/
236 pss = peasycap->psubstream;
237 if (!pss)
238 goto resubmit;
239 prt = pss->runtime;
240 if (!prt)
241 goto resubmit;
242 dma_bytes = (int)prt->dma_bytes;
243 if (0 == dma_bytes)
244 goto resubmit;
245 fragment_bytes = 4 * ((int)prt->period_size);
246 if (0 == fragment_bytes)
247 goto resubmit;
248/* -------------------------------------------------------------------------*/
249 if (purb->status) {
250 if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) {
251 JOM(16, "urb status -ESHUTDOWN or -ENOENT\n");
252 return;
253 }
254 SAM("ERROR: non-zero urb status: -%s: %d\n",
255 strerror(purb->status), purb->status);
256 goto resubmit;
257 }
258/*---------------------------------------------------------------------------*/
259/*
260 * PROCEED HERE WHEN NO ERROR
261 */
262/*---------------------------------------------------------------------------*/
263
264#ifdef UPSAMPLE
265 oldaudio = peasycap->oldaudio;
266#endif /*UPSAMPLE*/
267
268 for (i = 0; i < purb->number_of_packets; i++) {
269 if (purb->iso_frame_desc[i].status < 0) {
270 SAM("-%s: %d\n",
271 strerror(purb->iso_frame_desc[i].status),
272 purb->iso_frame_desc[i].status);
273 }
274 if (purb->iso_frame_desc[i].status) {
275 JOM(12, "discarding audio samples because "
276 "%i=purb->iso_frame_desc[i].status\n",
277 purb->iso_frame_desc[i].status);
278 continue;
279 }
280 more = purb->iso_frame_desc[i].actual_length;
281 if (more == 0) {
282 peasycap->audio_mt++;
283 continue;
284 }
285 if (0 > more) {
286 SAM("MISTAKE: more is negative\n");
287 return;
288 }
289
290 if (peasycap->audio_mt) {
291 JOM(12, "%4i empty audio urb frames\n",
292 peasycap->audio_mt);
293 peasycap->audio_mt = 0;
294 }
295
296 p1 = (u8 *)(purb->transfer_buffer +
297 purb->iso_frame_desc[i].offset);
298
299 /*
300 * COPY more BYTES FROM ISOC BUFFER
301 * TO THE DMA BUFFER, CONVERTING
302 * 8-BIT MONO TO 16-BIT SIGNED
303 * LITTLE-ENDIAN SAMPLES IF NECESSARY
304 */
305 while (more) {
306 much = dma_bytes - peasycap->dma_fill;
307 if (0 > much) {
308 SAM("MISTAKE: much is negative\n");
309 return;
310 }
311 if (0 == much) {
312 peasycap->dma_fill = 0;
313 peasycap->dma_next = fragment_bytes;
314 JOM(8, "wrapped dma buffer\n");
315 }
316 if (!peasycap->microphone) {
317 if (much > more)
318 much = more;
319 memcpy(prt->dma_area + peasycap->dma_fill,
320 p1, much);
321 p1 += much;
322 more -= much;
323 } else {
324#ifdef UPSAMPLE
325 if (much % 16)
326 JOM(8, "MISTAKE? much"
327 " is not divisible by 16\n");
328 if (much > (16 * more))
329 much = 16 * more;
330 p2 = (u8 *)(prt->dma_area + peasycap->dma_fill);
331
332 for (j = 0; j < (much / 16); j++) {
333 newaudio = ((int) *p1) - 128;
334 newaudio = 128 * newaudio;
335
336 delta = (newaudio - oldaudio) / 4;
337 tmp = oldaudio + delta;
338
339 for (k = 0; k < 4; k++) {
340 *p2 = (0x00FF & tmp);
341 *(p2 + 1) = (0xFF00 & tmp) >> 8;
342 p2 += 2;
343 *p2 = (0x00FF & tmp);
344 *(p2 + 1) = (0xFF00 & tmp) >> 8;
345 p2 += 2;
346 tmp += delta;
347 }
348 p1++;
349 more--;
350 oldaudio = tmp;
351 }
352#else /*!UPSAMPLE*/
353 if (much > (2 * more))
354 much = 2 * more;
355 p2 = (u8 *)(prt->dma_area + peasycap->dma_fill);
356
357 for (j = 0; j < (much / 2); j++) {
358 tmp = ((int) *p1) - 128;
359 tmp = 128 * tmp;
360 *p2 = (0x00FF & tmp);
361 *(p2 + 1) = (0xFF00 & tmp) >> 8;
362 p1++;
363 p2 += 2;
364 more--;
365 }
366#endif /*UPSAMPLE*/
367 }
368 peasycap->dma_fill += much;
369 if (peasycap->dma_fill >= peasycap->dma_next) {
370 isfragment = peasycap->dma_fill / fragment_bytes;
371 if (0 > isfragment) {
372 SAM("MISTAKE: isfragment is negative\n");
373 return;
374 }
375 peasycap->dma_read = (isfragment - 1) * fragment_bytes;
376 peasycap->dma_next = (isfragment + 1) * fragment_bytes;
377 if (dma_bytes < peasycap->dma_next)
378 peasycap->dma_next = fragment_bytes;
379
380 if (0 <= peasycap->dma_read) {
381 JOM(8, "snd_pcm_period_elapsed(), %i="
382 "isfragment\n", isfragment);
383 snd_pcm_period_elapsed(pss);
384 }
385 }
386 }
387
388#ifdef UPSAMPLE
389 peasycap->oldaudio = oldaudio;
390#endif /*UPSAMPLE*/
391
392 }
393/*---------------------------------------------------------------------------*/
394/*
395 * RESUBMIT THIS URB
396 */
397/*---------------------------------------------------------------------------*/
398resubmit:
399 if (peasycap->audio_isoc_streaming == 0)
400 return;
401
402 rc = usb_submit_urb(purb, GFP_ATOMIC);
403 if (rc) {
404 if ((-ENODEV != rc) && (-ENOENT != rc)) {
405 SAM("ERROR: while %i=audio_idle, usb_submit_urb failed "
406 "with rc: -%s :%d\n",
407 peasycap->audio_idle, strerror(rc), rc);
408 }
409 if (0 < peasycap->audio_isoc_streaming)
410 peasycap->audio_isoc_streaming--;
411 }
412 return;
413}
414/*****************************************************************************/
415static int easycap_alsa_open(struct snd_pcm_substream *pss)
416{
417 struct snd_pcm *psnd_pcm;
418 struct snd_card *psnd_card;
419 struct easycap *peasycap;
420
421 JOT(4, "\n");
422 if (!pss) {
423 SAY("ERROR: pss is NULL\n");
424 return -EFAULT;
425 }
426 psnd_pcm = pss->pcm;
427 if (!psnd_pcm) {
428 SAY("ERROR: psnd_pcm is NULL\n");
429 return -EFAULT;
430 }
431 psnd_card = psnd_pcm->card;
432 if (!psnd_card) {
433 SAY("ERROR: psnd_card is NULL\n");
434 return -EFAULT;
435 }
436
437 peasycap = psnd_card->private_data;
438 if (!peasycap) {
439 SAY("ERROR: peasycap is NULL\n");
440 return -EFAULT;
441 }
442 if (peasycap->psnd_card != psnd_card) {
443 SAM("ERROR: bad peasycap->psnd_card\n");
444 return -EFAULT;
445 }
446 if (peasycap->psubstream) {
447 SAM("ERROR: bad peasycap->psubstream\n");
448 return -EFAULT;
449 }
450 pss->private_data = peasycap;
451 peasycap->psubstream = pss;
452 pss->runtime->hw = peasycap->alsa_hardware;
453 pss->runtime->private_data = peasycap;
454 pss->private_data = peasycap;
455
456 if (0 != easycap_sound_setup(peasycap)) {
457 JOM(4, "ending unsuccessfully\n");
458 return -EFAULT;
459 }
460 JOM(4, "ending successfully\n");
461 return 0;
462}
463/*****************************************************************************/
464static int easycap_alsa_close(struct snd_pcm_substream *pss)
465{
466 struct easycap *peasycap;
467
468 JOT(4, "\n");
469 if (!pss) {
470 SAY("ERROR: pss is NULL\n");
471 return -EFAULT;
472 }
473 peasycap = snd_pcm_substream_chip(pss);
474 if (!peasycap) {
475 SAY("ERROR: peasycap is NULL\n");
476 return -EFAULT;
477 }
478 pss->private_data = NULL;
479 peasycap->psubstream = NULL;
480 JOT(4, "ending successfully\n");
481 return 0;
482}
483/*****************************************************************************/
484static int easycap_alsa_vmalloc(struct snd_pcm_substream *pss, size_t sz)
485{
486 struct snd_pcm_runtime *prt;
487 JOT(4, "\n");
488
489 if (!pss) {
490 SAY("ERROR: pss is NULL\n");
491 return -EFAULT;
492 }
493 prt = pss->runtime;
494 if (!prt) {
495 SAY("ERROR: substream.runtime is NULL\n");
496 return -EFAULT;
497 }
498 if (prt->dma_area) {
499 if (prt->dma_bytes > sz)
500 return 0;
501 vfree(prt->dma_area);
502 }
503 prt->dma_area = vmalloc(sz);
504 if (!prt->dma_area)
505 return -ENOMEM;
506 prt->dma_bytes = sz;
507 return 0;
508}
509/*****************************************************************************/
510static int easycap_alsa_hw_params(struct snd_pcm_substream *pss,
511 struct snd_pcm_hw_params *phw)
512{
513 int rc;
514
515 JOT(4, "%i\n", (params_buffer_bytes(phw)));
516 if (!pss) {
517 SAY("ERROR: pss is NULL\n");
518 return -EFAULT;
519 }
520 rc = easycap_alsa_vmalloc(pss, params_buffer_bytes(phw));
521 if (rc)
522 return rc;
523 return 0;
524}
525/*****************************************************************************/
526static int easycap_alsa_hw_free(struct snd_pcm_substream *pss)
527{
528 struct snd_pcm_runtime *prt;
529 JOT(4, "\n");
530
531 if (!pss) {
532 SAY("ERROR: pss is NULL\n");
533 return -EFAULT;
534 }
535 prt = pss->runtime;
536 if (!prt) {
537 SAY("ERROR: substream.runtime is NULL\n");
538 return -EFAULT;
539 }
540 if (prt->dma_area) {
541 JOT(8, "prt->dma_area = %p\n", prt->dma_area);
542 vfree(prt->dma_area);
543 prt->dma_area = NULL;
544 } else
545 JOT(8, "dma_area already freed\n");
546 return 0;
547}
548/*****************************************************************************/
549static int easycap_alsa_prepare(struct snd_pcm_substream *pss)
550{
551 struct easycap *peasycap;
552 struct snd_pcm_runtime *prt;
553
554 JOT(4, "\n");
555 if (!pss) {
556 SAY("ERROR: pss is NULL\n");
557 return -EFAULT;
558 }
559 prt = pss->runtime;
560 peasycap = snd_pcm_substream_chip(pss);
561 if (!peasycap) {
562 SAY("ERROR: peasycap is NULL\n");
563 return -EFAULT;
564 }
565
566 JOM(16, "ALSA decides %8i Hz=rate\n", pss->runtime->rate);
567 JOM(16, "ALSA decides %8ld =period_size\n", pss->runtime->period_size);
568 JOM(16, "ALSA decides %8i =periods\n", pss->runtime->periods);
569 JOM(16, "ALSA decides %8ld =buffer_size\n", pss->runtime->buffer_size);
570 JOM(16, "ALSA decides %8zd =dma_bytes\n", pss->runtime->dma_bytes);
571 JOM(16, "ALSA decides %8ld =boundary\n", pss->runtime->boundary);
572 JOM(16, "ALSA decides %8i =period_step\n", pss->runtime->period_step);
573 JOM(16, "ALSA decides %8i =sample_bits\n", pss->runtime->sample_bits);
574 JOM(16, "ALSA decides %8i =frame_bits\n", pss->runtime->frame_bits);
575 JOM(16, "ALSA decides %8ld =min_align\n", pss->runtime->min_align);
576 JOM(12, "ALSA decides %8ld =hw_ptr_base\n", pss->runtime->hw_ptr_base);
577 JOM(12, "ALSA decides %8ld =hw_ptr_interrupt\n",
578 pss->runtime->hw_ptr_interrupt);
579
580 if (prt->dma_bytes != 4 * ((int)prt->period_size) * ((int)prt->periods)) {
581 SAY("MISTAKE: unexpected ALSA parameters\n");
582 return -ENOENT;
583 }
584 return 0;
585}
586/*****************************************************************************/
587static int easycap_alsa_ack(struct snd_pcm_substream *pss)
588{
589 return 0;
590}
591/*****************************************************************************/
592static int easycap_alsa_trigger(struct snd_pcm_substream *pss, int cmd)
593{
594 struct easycap *peasycap;
595
596 JOT(4, "%i=cmd cf %i=START %i=STOP\n", cmd, SNDRV_PCM_TRIGGER_START,
597 SNDRV_PCM_TRIGGER_STOP);
598 if (!pss) {
599 SAY("ERROR: pss is NULL\n");
600 return -EFAULT;
601 }
602 peasycap = snd_pcm_substream_chip(pss);
603 if (!peasycap) {
604 SAY("ERROR: peasycap is NULL\n");
605 return -EFAULT;
606 }
607 switch (cmd) {
608 case SNDRV_PCM_TRIGGER_START: {
609 peasycap->audio_idle = 0;
610 break;
611 }
612 case SNDRV_PCM_TRIGGER_STOP: {
613 peasycap->audio_idle = 1;
614 break;
615 }
616 default:
617 return -EINVAL;
618 }
619 return 0;
620}
621/*****************************************************************************/
622static snd_pcm_uframes_t easycap_alsa_pointer(struct snd_pcm_substream *pss)
623{
624 struct easycap *peasycap;
625 snd_pcm_uframes_t offset;
626
627 JOT(16, "\n");
628 if (!pss) {
629 SAY("ERROR: pss is NULL\n");
630 return -EFAULT;
631 }
632 peasycap = snd_pcm_substream_chip(pss);
633 if (!peasycap) {
634 SAY("ERROR: peasycap is NULL\n");
635 return -EFAULT;
636 }
637 if ((0 != peasycap->audio_eof) || (0 != peasycap->audio_idle)) {
638 JOM(8, "returning -EIO because "
639 "%i=audio_idle %i=audio_eof\n",
640 peasycap->audio_idle, peasycap->audio_eof);
641 return -EIO;
642 }
643/*---------------------------------------------------------------------------*/
644 if (0 > peasycap->dma_read) {
645 JOM(8, "returning -EBUSY\n");
646 return -EBUSY;
647 }
648 offset = ((snd_pcm_uframes_t)peasycap->dma_read)/4;
649 JOM(8, "ALSA decides %8i =hw_ptr_base\n", (int)pss->runtime->hw_ptr_base);
650 JOM(8, "ALSA decides %8i =hw_ptr_interrupt\n",
651 (int)pss->runtime->hw_ptr_interrupt);
652 JOM(8, "%7i=offset %7i=dma_read %7i=dma_next\n",
653 (int)offset, peasycap->dma_read, peasycap->dma_next);
654 return offset;
655}
656/*****************************************************************************/
657static struct page *
658easycap_alsa_page(struct snd_pcm_substream *pss, unsigned long offset)
659{
660 return vmalloc_to_page(pss->runtime->dma_area + offset);
661}
662/*****************************************************************************/
663
664static struct snd_pcm_ops easycap_alsa_pcm_ops = {
665 .open = easycap_alsa_open,
666 .close = easycap_alsa_close,
667 .ioctl = snd_pcm_lib_ioctl,
668 .hw_params = easycap_alsa_hw_params,
669 .hw_free = easycap_alsa_hw_free,
670 .prepare = easycap_alsa_prepare,
671 .ack = easycap_alsa_ack,
672 .trigger = easycap_alsa_trigger,
673 .pointer = easycap_alsa_pointer,
674 .page = easycap_alsa_page,
675};
676
677/*****************************************************************************/
678/*---------------------------------------------------------------------------*/
679/*
680 * THE FUNCTION snd_card_create() HAS THIS_MODULE AS AN ARGUMENT. THIS
681 * MEANS MODULE easycap. BEWARE.
682*/
683/*---------------------------------------------------------------------------*/
684int easycap_alsa_probe(struct easycap *peasycap)
685{
686 int rc;
687 struct snd_card *psnd_card;
688 struct snd_pcm *psnd_pcm;
689
690 if (!peasycap) {
691 SAY("ERROR: peasycap is NULL\n");
692 return -ENODEV;
693 }
694 if (0 > peasycap->minor) {
695 SAY("ERROR: no minor\n");
696 return -ENODEV;
697 }
698
699 peasycap->alsa_hardware = alsa_hardware;
700 if (peasycap->microphone) {
701 peasycap->alsa_hardware.rates = SNDRV_PCM_RATE_32000;
702 peasycap->alsa_hardware.rate_min = 32000;
703 peasycap->alsa_hardware.rate_max = 32000;
704 } else {
705 peasycap->alsa_hardware.rates = SNDRV_PCM_RATE_48000;
706 peasycap->alsa_hardware.rate_min = 48000;
707 peasycap->alsa_hardware.rate_max = 48000;
708 }
709
710 if (0 != snd_card_create(SNDRV_DEFAULT_IDX1, "easycap_alsa",
711 THIS_MODULE, 0, &psnd_card)) {
712 SAY("ERROR: Cannot do ALSA snd_card_create()\n");
713 return -EFAULT;
714 }
715
716 sprintf(&psnd_card->id[0], "EasyALSA%i", peasycap->minor);
717 strcpy(&psnd_card->driver[0], EASYCAP_DRIVER_DESCRIPTION);
718 strcpy(&psnd_card->shortname[0], "easycap_alsa");
719 sprintf(&psnd_card->longname[0], "%s", &psnd_card->shortname[0]);
720
721 psnd_card->dev = &peasycap->pusb_device->dev;
722 psnd_card->private_data = peasycap;
723 peasycap->psnd_card = psnd_card;
724
725 rc = snd_pcm_new(psnd_card, "easycap_pcm", 0, 0, 1, &psnd_pcm);
726 if (rc) {
727 SAM("ERROR: Cannot do ALSA snd_pcm_new()\n");
728 snd_card_free(psnd_card);
729 return -EFAULT;
730 }
731
732 snd_pcm_set_ops(psnd_pcm, SNDRV_PCM_STREAM_CAPTURE,
733 &easycap_alsa_pcm_ops);
734 psnd_pcm->info_flags = 0;
735 strcpy(&psnd_pcm->name[0], &psnd_card->id[0]);
736 psnd_pcm->private_data = peasycap;
737 peasycap->psnd_pcm = psnd_pcm;
738 peasycap->psubstream = NULL;
739
740 rc = snd_card_register(psnd_card);
741 if (rc) {
742 SAM("ERROR: Cannot do ALSA snd_card_register()\n");
743 snd_card_free(psnd_card);
744 return -EFAULT;
745 }
746
747 SAM("registered %s\n", &psnd_card->id[0]);
748 return 0;
749}
750
diff --git a/drivers/staging/media/easycap/easycap_testcard.c b/drivers/staging/media/easycap/easycap_testcard.c
deleted file mode 100644
index 0f71470ace39..000000000000
--- a/drivers/staging/media/easycap/easycap_testcard.c
+++ /dev/null
@@ -1,155 +0,0 @@
1/******************************************************************************
2* *
3* easycap_testcard.c *
4* *
5******************************************************************************/
6/*
7 *
8 * Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org>
9 *
10 *
11 * This is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The software is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this software; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25*/
26/*****************************************************************************/
27
28#include "easycap.h"
29
30/*****************************************************************************/
31#define TESTCARD_BYTESPERLINE (2 * 720)
32void
33easycap_testcard(struct easycap *peasycap, int field)
34{
35 int total;
36 int y, u, v, r, g, b;
37 unsigned char uyvy[4];
38 int i1, line, k, m, n, more, much, barwidth, barheight;
39 unsigned char bfbar[TESTCARD_BYTESPERLINE / 8], *p1, *p2;
40 struct data_buffer *pfield_buffer;
41
42 if (!peasycap) {
43 SAY("ERROR: peasycap is NULL\n");
44 return;
45 }
46 JOM(8, "%i=field\n", field);
47 switch (peasycap->width) {
48 case 720:
49 case 360: {
50 barwidth = (2 * 720) / 8;
51 break;
52 }
53 case 704:
54 case 352: {
55 barwidth = (2 * 704) / 8;
56 break;
57 }
58 case 640:
59 case 320: {
60 barwidth = (2 * 640) / 8;
61 break;
62 }
63 default: {
64 SAM("ERROR: cannot set barwidth\n");
65 return;
66 }
67 }
68 if (TESTCARD_BYTESPERLINE < barwidth) {
69 SAM("ERROR: barwidth is too large\n");
70 return;
71 }
72 switch (peasycap->height) {
73 case 576:
74 case 288: {
75 barheight = 576;
76 break;
77 }
78 case 480:
79 case 240: {
80 barheight = 480;
81 break;
82 }
83 default: {
84 SAM("ERROR: cannot set barheight\n");
85 return;
86 }
87 }
88 total = 0;
89 k = field;
90 m = 0;
91 n = 0;
92
93 for (line = 0; line < (barheight / 2); line++) {
94 for (i1 = 0; i1 < 8; i1++) {
95 r = (i1 * 256)/8;
96 g = (i1 * 256)/8;
97 b = (i1 * 256)/8;
98
99 y = 299*r/1000 + 587*g/1000 + 114*b/1000 ;
100 u = -147*r/1000 - 289*g/1000 + 436*b/1000 ;
101 u = u + 128;
102 v = 615*r/1000 - 515*g/1000 - 100*b/1000 ;
103 v = v + 128;
104
105 uyvy[0] = 0xFF & u ;
106 uyvy[1] = 0xFF & y ;
107 uyvy[2] = 0xFF & v ;
108 uyvy[3] = 0xFF & y ;
109
110 p1 = &bfbar[0];
111 while (p1 < &bfbar[barwidth]) {
112 *p1++ = uyvy[0] ;
113 *p1++ = uyvy[1] ;
114 *p1++ = uyvy[2] ;
115 *p1++ = uyvy[3] ;
116 total += 4;
117 }
118
119 p1 = &bfbar[0];
120 more = barwidth;
121
122 while (more) {
123 if ((FIELD_BUFFER_SIZE/PAGE_SIZE) <= m) {
124 SAM("ERROR: bad m reached\n");
125 return;
126 }
127 if (PAGE_SIZE < n) {
128 SAM("ERROR: bad n reached\n");
129 return;
130 }
131
132 if (0 > more) {
133 SAM("ERROR: internal fault\n");
134 return;
135 }
136
137 much = PAGE_SIZE - n;
138 if (much > more)
139 much = more;
140 pfield_buffer = &peasycap->field_buffer[k][m];
141 p2 = pfield_buffer->pgo + n;
142 memcpy(p2, p1, much);
143
144 p1 += much;
145 n += much;
146 more -= much;
147 if (PAGE_SIZE == n) {
148 m++;
149 n = 0;
150 }
151 }
152 }
153 }
154 return;
155}
diff --git a/drivers/staging/media/go7007/Makefile b/drivers/staging/media/go7007/Makefile
index 6ee837c56706..3fdbef5306a0 100644
--- a/drivers/staging/media/go7007/Makefile
+++ b/drivers/staging/media/go7007/Makefile
@@ -24,7 +24,7 @@ s2250-y := s2250-board.o
24#ccflags-$(CONFIG_VIDEO_SAA7134:m=y) += -Idrivers/media/video/saa7134 -DSAA7134_MPEG_GO7007=3 24#ccflags-$(CONFIG_VIDEO_SAA7134:m=y) += -Idrivers/media/video/saa7134 -DSAA7134_MPEG_GO7007=3
25 25
26# S2250 needs cypress ezusb loader from dvb-usb 26# S2250 needs cypress ezusb loader from dvb-usb
27ccflags-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD:m=y) += -Idrivers/media/dvb/dvb-usb 27ccflags-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD:m=y) += -Idrivers/media/usb/dvb-usb
28 28
29ccflags-y += -Idrivers/media/dvb/frontends 29ccflags-y += -Idrivers/media/dvb-frontends
30ccflags-y += -Idrivers/media/dvb/dvb-core 30ccflags-y += -Idrivers/media/dvb-core
diff --git a/drivers/staging/media/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c
index c184ad30fbd8..980371b02749 100644
--- a/drivers/staging/media/go7007/go7007-v4l2.c
+++ b/drivers/staging/media/go7007/go7007-v4l2.c
@@ -1372,7 +1372,7 @@ static int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1372 1372
1373/* FIXME: vidioc_s_crop is not really implemented!!! 1373/* FIXME: vidioc_s_crop is not really implemented!!!
1374 */ 1374 */
1375static int vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop) 1375static int vidioc_s_crop(struct file *file, void *priv, const struct v4l2_crop *crop)
1376{ 1376{
1377 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1377 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1378 return -EINVAL; 1378 return -EINVAL;
@@ -1392,7 +1392,7 @@ static int vidioc_g_jpegcomp(struct file *file, void *priv,
1392} 1392}
1393 1393
1394static int vidioc_s_jpegcomp(struct file *file, void *priv, 1394static int vidioc_s_jpegcomp(struct file *file, void *priv,
1395 struct v4l2_jpegcompression *params) 1395 const struct v4l2_jpegcompression *params)
1396{ 1396{
1397 if (params->quality != 50 || 1397 if (params->quality != 50 ||
1398 params->jpeg_markers != (V4L2_JPEG_MARKER_DHT | 1398 params->jpeg_markers != (V4L2_JPEG_MARKER_DHT |
diff --git a/drivers/staging/media/lirc/Kconfig b/drivers/staging/media/lirc/Kconfig
index 526ec0fc2f04..e60a59fc252b 100644
--- a/drivers/staging/media/lirc/Kconfig
+++ b/drivers/staging/media/lirc/Kconfig
@@ -63,12 +63,6 @@ config LIRC_SIR
63 help 63 help
64 Driver for the SIR IrDA port 64 Driver for the SIR IrDA port
65 65
66config LIRC_TTUSBIR
67 tristate "Technotrend USB IR Receiver"
68 depends on LIRC && USB
69 help
70 Driver for the Technotrend USB IR Receiver
71
72config LIRC_ZILOG 66config LIRC_ZILOG
73 tristate "Zilog/Hauppauge IR Transmitter" 67 tristate "Zilog/Hauppauge IR Transmitter"
74 depends on LIRC && I2C 68 depends on LIRC && I2C
diff --git a/drivers/staging/media/lirc/Makefile b/drivers/staging/media/lirc/Makefile
index d76b0fa2af53..b90fcabddab6 100644
--- a/drivers/staging/media/lirc/Makefile
+++ b/drivers/staging/media/lirc/Makefile
@@ -10,5 +10,4 @@ obj-$(CONFIG_LIRC_PARALLEL) += lirc_parallel.o
10obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o 10obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o
11obj-$(CONFIG_LIRC_SERIAL) += lirc_serial.o 11obj-$(CONFIG_LIRC_SERIAL) += lirc_serial.o
12obj-$(CONFIG_LIRC_SIR) += lirc_sir.o 12obj-$(CONFIG_LIRC_SIR) += lirc_sir.o
13obj-$(CONFIG_LIRC_TTUSBIR) += lirc_ttusbir.o
14obj-$(CONFIG_LIRC_ZILOG) += lirc_zilog.o 13obj-$(CONFIG_LIRC_ZILOG) += lirc_zilog.o
diff --git a/drivers/staging/media/lirc/lirc_ene0100.h b/drivers/staging/media/lirc/lirc_ene0100.h
deleted file mode 100644
index 06bebd6acc46..000000000000
--- a/drivers/staging/media/lirc/lirc_ene0100.h
+++ /dev/null
@@ -1,169 +0,0 @@
1/*
2 * driver for ENE KB3926 B/C/D CIR (also known as ENE0100)
3 *
4 * Copyright (C) 2009 Maxim Levitsky <maximlevitsky@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 * USA
20 */
21
22#include <media/lirc.h>
23#include <media/lirc_dev.h>
24
25/* hardware address */
26#define ENE_STATUS 0 /* hardware status - unused */
27#define ENE_ADDR_HI 1 /* hi byte of register address */
28#define ENE_ADDR_LO 2 /* low byte of register address */
29#define ENE_IO 3 /* read/write window */
30#define ENE_MAX_IO 4
31
32/* 8 bytes of samples, divided in 2 halfs*/
33#define ENE_SAMPLE_BUFFER 0xF8F0 /* regular sample buffer */
34#define ENE_SAMPLE_SPC_MASK (1 << 7) /* sample is space */
35#define ENE_SAMPLE_VALUE_MASK 0x7F
36#define ENE_SAMPLE_OVERFLOW 0x7F
37#define ENE_SAMPLES_SIZE 4
38
39/* fan input sample buffer */
40#define ENE_SAMPLE_BUFFER_FAN 0xF8FB /* this buffer holds high byte of */
41 /* each sample of normal buffer */
42
43#define ENE_FAN_SMPL_PULS_MSK 0x8000 /* this bit of combined sample */
44 /* if set, says that sample is pulse */
45#define ENE_FAN_VALUE_MASK 0x0FFF /* mask for valid bits of the value */
46
47/* first firmware register */
48#define ENE_FW1 0xF8F8
49#define ENE_FW1_ENABLE (1 << 0) /* enable fw processing */
50#define ENE_FW1_TXIRQ (1 << 1) /* TX interrupt pending */
51#define ENE_FW1_WAKE (1 << 6) /* enable wake from S3 */
52#define ENE_FW1_IRQ (1 << 7) /* enable interrupt */
53
54/* second firmware register */
55#define ENE_FW2 0xF8F9
56#define ENE_FW2_BUF_HIGH (1 << 0) /* which half of the buffer to read */
57#define ENE_FW2_IRQ_CLR (1 << 2) /* clear this on IRQ */
58#define ENE_FW2_GP40_AS_LEARN (1 << 4) /* normal input is used as */
59 /* learning input */
60#define ENE_FW2_FAN_AS_NRML_IN (1 << 6) /* fan is used as normal input */
61#define ENE_FW2_LEARNING (1 << 7) /* hardware supports learning and TX */
62
63/* fan as input settings - only if learning capable */
64#define ENE_FAN_AS_IN1 0xFE30 /* fan init reg 1 */
65#define ENE_FAN_AS_IN1_EN 0xCD
66#define ENE_FAN_AS_IN2 0xFE31 /* fan init reg 2 */
67#define ENE_FAN_AS_IN2_EN 0x03
68#define ENE_SAMPLE_PERIOD_FAN 61 /* fan input has fixed sample period */
69
70/* IRQ registers block (for revision B) */
71#define ENEB_IRQ 0xFD09 /* IRQ number */
72#define ENEB_IRQ_UNK1 0xFD17 /* unknown setting = 1 */
73#define ENEB_IRQ_STATUS 0xFD80 /* irq status */
74#define ENEB_IRQ_STATUS_IR (1 << 5) /* IR irq */
75
76/* IRQ registers block (for revision C,D) */
77#define ENEC_IRQ 0xFE9B /* new irq settings register */
78#define ENEC_IRQ_MASK 0x0F /* irq number mask */
79#define ENEC_IRQ_UNK_EN (1 << 4) /* always enabled */
80#define ENEC_IRQ_STATUS (1 << 5) /* irq status and ACK */
81
82/* CIR block settings */
83#define ENE_CIR_CONF1 0xFEC0
84#define ENE_CIR_CONF1_ADC_ON 0x7 /* receiver on gpio40 enabled */
85#define ENE_CIR_CONF1_LEARN1 (1 << 3) /* enabled on learning mode */
86#define ENE_CIR_CONF1_TX_ON 0x30 /* enabled on transmit */
87#define ENE_CIR_CONF1_TX_CARR (1 << 7) /* send TX carrier or not */
88
89#define ENE_CIR_CONF2 0xFEC1 /* unknown setting = 0 */
90#define ENE_CIR_CONF2_LEARN2 (1 << 4) /* set on enable learning */
91#define ENE_CIR_CONF2_GPIO40DIS (1 << 5) /* disable normal input via gpio40 */
92
93#define ENE_CIR_SAMPLE_PERIOD 0xFEC8 /* sample period in us */
94#define ENE_CIR_SAMPLE_OVERFLOW (1 << 7) /* interrupt on overflows if set */
95
96
97/* transmitter - not implemented yet */
98/* KB3926C and higher */
99/* transmission is very similar to receiving, a byte is written to */
100/* ENE_TX_INPUT, in same manner as it is read from sample buffer */
101/* sample period is fixed*/
102
103
104/* transmitter ports */
105#define ENE_TX_PORT1 0xFC01 /* this enables one or both */
106#define ENE_TX_PORT1_EN (1 << 5) /* TX ports */
107#define ENE_TX_PORT2 0xFC08
108#define ENE_TX_PORT2_EN (1 << 1)
109
110#define ENE_TX_INPUT 0xFEC9 /* next byte to transmit */
111#define ENE_TX_SPC_MASK (1 << 7) /* Transmitted sample is space */
112#define ENE_TX_UNK1 0xFECB /* set to 0x63 */
113#define ENE_TX_SMPL_PERIOD 50 /* transmit sample period */
114
115
116#define ENE_TX_CARRIER 0xFECE /* TX carrier * 2 (khz) */
117#define ENE_TX_CARRIER_UNKBIT 0x80 /* This bit set on transmit */
118#define ENE_TX_CARRIER_LOW 0xFECF /* TX carrier / 2 */
119
120/* Hardware versions */
121#define ENE_HW_VERSION 0xFF00 /* hardware revision */
122#define ENE_HW_UNK 0xFF1D
123#define ENE_HW_UNK_CLR (1 << 2)
124#define ENE_HW_VER_MAJOR 0xFF1E /* chip version */
125#define ENE_HW_VER_MINOR 0xFF1F
126#define ENE_HW_VER_OLD 0xFD00
127
128#define same_sign(a, b) ((((a) > 0) && (b) > 0) || ((a) < 0 && (b) < 0))
129
130#define ENE_DRIVER_NAME "enecir"
131#define ENE_MAXGAP 250000 /* this is amount of time we wait
132 before turning the sampler, chosen
133 arbitry */
134
135#define space(len) (-(len)) /* add a space */
136
137/* software defines */
138#define ENE_IRQ_RX 1
139#define ENE_IRQ_TX 2
140
141#define ENE_HW_B 1 /* 3926B */
142#define ENE_HW_C 2 /* 3926C */
143#define ENE_HW_D 3 /* 3926D */
144
145#define ene_printk(level, text, ...) \
146 printk(level ENE_DRIVER_NAME ": " text, ## __VA_ARGS__)
147
148struct ene_device {
149 struct pnp_dev *pnp_dev;
150 struct lirc_driver *lirc_driver;
151
152 /* hw settings */
153 unsigned long hw_io;
154 int irq;
155
156 int hw_revision; /* hardware revision */
157 int hw_learning_and_tx_capable; /* learning capable */
158 int hw_gpio40_learning; /* gpio40 is learning */
159 int hw_fan_as_normal_input; /* fan input is used as regular input */
160
161 /* device data */
162 int idle;
163 int fan_input_inuse;
164
165 int sample;
166 int in_use;
167
168 struct timeval gap_start;
169};
diff --git a/drivers/staging/media/lirc/lirc_igorplugusb.c b/drivers/staging/media/lirc/lirc_igorplugusb.c
index 7a2501776679..939a801c23e4 100644
--- a/drivers/staging/media/lirc/lirc_igorplugusb.c
+++ b/drivers/staging/media/lirc/lirc_igorplugusb.c
@@ -325,8 +325,8 @@ static int igorplugusb_remote_poll(void *data, struct lirc_buffer *buf)
325 if (ret < DEVICE_HEADERLEN) 325 if (ret < DEVICE_HEADERLEN)
326 return -ENODATA; 326 return -ENODATA;
327 327
328 dprintk(DRIVER_NAME ": Got %d bytes. Header: %02x %02x %02x\n", 328 dprintk(DRIVER_NAME ": Got %d bytes. Header: %*ph\n",
329 ret, ir->buf_in[0], ir->buf_in[1], ir->buf_in[2]); 329 ret, 3, ir->buf_in);
330 330
331 do_gettimeofday(&now); 331 do_gettimeofday(&now);
332 timediff = now.tv_sec - ir->last_time.tv_sec; 332 timediff = now.tv_sec - ir->last_time.tv_sec;
diff --git a/drivers/staging/media/lirc/lirc_ttusbir.c b/drivers/staging/media/lirc/lirc_ttusbir.c
deleted file mode 100644
index 3bb865c02173..000000000000
--- a/drivers/staging/media/lirc/lirc_ttusbir.c
+++ /dev/null
@@ -1,376 +0,0 @@
1/*
2 * lirc_ttusbir.c
3 *
4 * lirc_ttusbir - LIRC device driver for the TechnoTrend USB IR Receiver
5 *
6 * Copyright (C) 2007 Stefan Macher <st_maker-lirc@yahoo.de>
7 *
8 * This LIRC driver provides access to the TechnoTrend USB IR Receiver.
9 * The receiver delivers the IR signal as raw sampled true/false data in
10 * isochronous USB packets each of size 128 byte.
11 * Currently the driver reduces the sampling rate by factor of 8 as this
12 * is still more than enough to decode RC-5 - others should be analyzed.
13 * But the driver does not rely on RC-5 it should be able to decode every
14 * IR signal that is not too fast.
15 */
16
17/*
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 */
32
33#include <linux/kernel.h>
34#include <linux/init.h>
35#include <linux/module.h>
36#include <linux/errno.h>
37#include <linux/slab.h>
38#include <linux/usb.h>
39
40#include <media/lirc.h>
41#include <media/lirc_dev.h>
42
43MODULE_DESCRIPTION("TechnoTrend USB IR device driver for LIRC");
44MODULE_AUTHOR("Stefan Macher (st_maker-lirc@yahoo.de)");
45MODULE_LICENSE("GPL");
46
47/* #define DEBUG */
48#ifdef DEBUG
49#define DPRINTK printk
50#else
51#define DPRINTK(_x_, a...)
52#endif
53
54/* function declarations */
55static int probe(struct usb_interface *intf, const struct usb_device_id *id);
56static void disconnect(struct usb_interface *intf);
57static void urb_complete(struct urb *urb);
58static int set_use_inc(void *data);
59static void set_use_dec(void *data);
60
61static int num_urbs = 2;
62module_param(num_urbs, int, S_IRUGO);
63MODULE_PARM_DESC(num_urbs,
64 "Number of URBs in queue. Try to increase to 4 in case "
65 "of problems (default: 2; minimum: 2)");
66
67/* table of devices that work with this driver */
68static struct usb_device_id device_id_table[] = {
69 /* TechnoTrend USB IR Receiver */
70 { USB_DEVICE(0x0B48, 0x2003) },
71 /* Terminating entry */
72 { }
73};
74MODULE_DEVICE_TABLE(usb, device_id_table);
75
76/* USB driver definition */
77static struct usb_driver usb_driver = {
78 .name = "TTUSBIR",
79 .id_table = &(device_id_table[0]),
80 .probe = probe,
81 .disconnect = disconnect,
82};
83
84/* USB device definition */
85struct ttusbir_device {
86 struct usb_driver *usb_driver;
87 struct usb_device *udev;
88 struct usb_interface *interf;
89 struct usb_class_driver class_driver;
90 unsigned int ifnum; /* Interface number to use */
91 unsigned int alt_setting; /* alternate setting to use */
92 unsigned int endpoint; /* Endpoint to use */
93 struct urb **urb; /* num_urb URB pointers*/
94 char **buffer; /* 128 byte buffer for each URB */
95 struct lirc_buffer rbuf; /* Buffer towards LIRC */
96 struct lirc_driver driver;
97 int minor;
98 int last_pulse; /* remembers if last received byte was pulse or space */
99 int last_num; /* remembers how many last bytes appeared */
100 int opened;
101};
102
103/*** LIRC specific functions ***/
104static int set_use_inc(void *data)
105{
106 int i, retval;
107 struct ttusbir_device *ttusbir = data;
108
109 DPRINTK("Sending first URBs\n");
110 /* @TODO Do I need to check if I am already opened */
111 ttusbir->opened = 1;
112
113 for (i = 0; i < num_urbs; i++) {
114 retval = usb_submit_urb(ttusbir->urb[i], GFP_KERNEL);
115 if (retval) {
116 dev_err(&ttusbir->interf->dev,
117 "%s: usb_submit_urb failed on urb %d\n",
118 __func__, i);
119 return retval;
120 }
121 }
122 return 0;
123}
124
125static void set_use_dec(void *data)
126{
127 struct ttusbir_device *ttusbir = data;
128
129 DPRINTK("Device closed\n");
130
131 ttusbir->opened = 0;
132}
133
134/*** USB specific functions ***/
135
136/*
137 * This mapping table is used to do a very simple filtering of the
138 * input signal.
139 * For a value with at least 4 bits set it returns 0xFF otherwise
140 * 0x00. For faster IR signals this can not be used. But for RC-5 we
141 * still have about 14 samples per pulse/space, i.e. we sample with 14
142 * times higher frequency than the signal frequency
143 */
144const unsigned char map_table[] = {
145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
152 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
156 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
158 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
159 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
160 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
161 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
162 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
163 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
164 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
165 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
166 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
167 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
168 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
170 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
171 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
172 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
173 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF,
174 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
175 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
176 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
177};
178
179static void urb_complete(struct urb *urb)
180{
181 struct ttusbir_device *ttusbir;
182 unsigned char *buf;
183 int i;
184 int l;
185
186 ttusbir = urb->context;
187
188 if (!ttusbir->opened)
189 return;
190
191 buf = (unsigned char *)urb->transfer_buffer;
192
193 for (i = 0; i < 128; i++) {
194 /* Here we do the filtering and some kind of down sampling */
195 buf[i] = ~map_table[buf[i]];
196 if (ttusbir->last_pulse == buf[i]) {
197 if (ttusbir->last_num < PULSE_MASK/63)
198 ttusbir->last_num++;
199 /*
200 * else we are in a idle period and do not need to
201 * increment any longer
202 */
203 } else {
204 l = ttusbir->last_num * 62; /* about 62 = us/byte */
205 if (ttusbir->last_pulse) /* pulse or space? */
206 l |= PULSE_BIT;
207 if (!lirc_buffer_full(&ttusbir->rbuf)) {
208 lirc_buffer_write(&ttusbir->rbuf, (void *)&l);
209 wake_up_interruptible(&ttusbir->rbuf.wait_poll);
210 }
211 ttusbir->last_num = 0;
212 ttusbir->last_pulse = buf[i];
213 }
214 }
215 usb_submit_urb(urb, GFP_ATOMIC); /* keep data rolling :-) */
216}
217
218/*
219 * Called whenever the USB subsystem thinks we could be the right driver
220 * to handle this device
221 */
222static int probe(struct usb_interface *intf, const struct usb_device_id *id)
223{
224 int alt_set, endp;
225 int found = 0;
226 int i, j;
227 int struct_size;
228 struct usb_host_interface *host_interf;
229 struct usb_interface_descriptor *interf_desc;
230 struct usb_host_endpoint *host_endpoint;
231 struct ttusbir_device *ttusbir;
232
233 DPRINTK("Module ttusbir probe\n");
234
235 /* To reduce memory fragmentation we use only one allocation */
236 struct_size = sizeof(struct ttusbir_device) +
237 (sizeof(struct urb *) * num_urbs) +
238 (sizeof(char *) * num_urbs) +
239 (num_urbs * 128);
240 ttusbir = kzalloc(struct_size, GFP_KERNEL);
241 if (!ttusbir)
242 return -ENOMEM;
243
244 ttusbir->urb = (struct urb **)((char *)ttusbir +
245 sizeof(struct ttusbir_device));
246 ttusbir->buffer = (char **)((char *)ttusbir->urb +
247 (sizeof(struct urb *) * num_urbs));
248 for (i = 0; i < num_urbs; i++)
249 ttusbir->buffer[i] = (char *)ttusbir->buffer +
250 (sizeof(char *)*num_urbs) + (i * 128);
251
252 ttusbir->usb_driver = &usb_driver;
253 ttusbir->alt_setting = -1;
254 /* @TODO check if error can be returned */
255 ttusbir->udev = usb_get_dev(interface_to_usbdev(intf));
256 ttusbir->interf = intf;
257 ttusbir->last_pulse = 0x00;
258 ttusbir->last_num = 0;
259
260 /*
261 * Now look for interface setting we can handle
262 * We are searching for the alt setting where end point
263 * 0x82 has max packet size 16
264 */
265 for (alt_set = 0; alt_set < intf->num_altsetting && !found; alt_set++) {
266 host_interf = &intf->altsetting[alt_set];
267 interf_desc = &host_interf->desc;
268 for (endp = 0; endp < interf_desc->bNumEndpoints; endp++) {
269 host_endpoint = &host_interf->endpoint[endp];
270 if ((host_endpoint->desc.bEndpointAddress == 0x82) &&
271 (host_endpoint->desc.wMaxPacketSize == 0x10)) {
272 ttusbir->alt_setting = alt_set;
273 ttusbir->endpoint = endp;
274 found = 1;
275 break;
276 }
277 }
278 }
279 if (ttusbir->alt_setting != -1)
280 DPRINTK("alt setting: %d\n", ttusbir->alt_setting);
281 else {
282 dev_err(&intf->dev, "Could not find alternate setting\n");
283 kfree(ttusbir);
284 return -EINVAL;
285 }
286
287 /* OK lets setup this interface setting */
288 usb_set_interface(ttusbir->udev, 0, ttusbir->alt_setting);
289
290 /* Store device info in interface structure */
291 usb_set_intfdata(intf, ttusbir);
292
293 /* Register as a LIRC driver */
294 if (lirc_buffer_init(&ttusbir->rbuf, sizeof(int), 256) < 0) {
295 dev_err(&intf->dev, "Could not get memory for LIRC data buffer\n");
296 usb_set_intfdata(intf, NULL);
297 kfree(ttusbir);
298 return -ENOMEM;
299 }
300 strcpy(ttusbir->driver.name, "TTUSBIR");
301 ttusbir->driver.minor = -1;
302 ttusbir->driver.code_length = 1;
303 ttusbir->driver.sample_rate = 0;
304 ttusbir->driver.data = ttusbir;
305 ttusbir->driver.add_to_buf = NULL;
306 ttusbir->driver.rbuf = &ttusbir->rbuf;
307 ttusbir->driver.set_use_inc = set_use_inc;
308 ttusbir->driver.set_use_dec = set_use_dec;
309 ttusbir->driver.dev = &intf->dev;
310 ttusbir->driver.owner = THIS_MODULE;
311 ttusbir->driver.features = LIRC_CAN_REC_MODE2;
312 ttusbir->minor = lirc_register_driver(&ttusbir->driver);
313 if (ttusbir->minor < 0) {
314 dev_err(&intf->dev, "Error registering as LIRC driver\n");
315 usb_set_intfdata(intf, NULL);
316 lirc_buffer_free(&ttusbir->rbuf);
317 kfree(ttusbir);
318 return -EIO;
319 }
320
321 /* Allocate and setup the URB that we will use to talk to the device */
322 for (i = 0; i < num_urbs; i++) {
323 ttusbir->urb[i] = usb_alloc_urb(8, GFP_KERNEL);
324 if (!ttusbir->urb[i]) {
325 dev_err(&intf->dev, "Could not allocate memory for the URB\n");
326 for (j = i - 1; j >= 0; j--)
327 kfree(ttusbir->urb[j]);
328 lirc_buffer_free(&ttusbir->rbuf);
329 lirc_unregister_driver(ttusbir->minor);
330 kfree(ttusbir);
331 usb_set_intfdata(intf, NULL);
332 return -ENOMEM;
333 }
334 ttusbir->urb[i]->dev = ttusbir->udev;
335 ttusbir->urb[i]->context = ttusbir;
336 ttusbir->urb[i]->pipe = usb_rcvisocpipe(ttusbir->udev,
337 ttusbir->endpoint);
338 ttusbir->urb[i]->interval = 1;
339 ttusbir->urb[i]->transfer_flags = URB_ISO_ASAP;
340 ttusbir->urb[i]->transfer_buffer = &ttusbir->buffer[i][0];
341 ttusbir->urb[i]->complete = urb_complete;
342 ttusbir->urb[i]->number_of_packets = 8;
343 ttusbir->urb[i]->transfer_buffer_length = 128;
344 for (j = 0; j < 8; j++) {
345 ttusbir->urb[i]->iso_frame_desc[j].offset = j*16;
346 ttusbir->urb[i]->iso_frame_desc[j].length = 16;
347 }
348 }
349 return 0;
350}
351
352/**
353 * Called when the driver is unloaded or the device is unplugged
354 */
355static void disconnect(struct usb_interface *intf)
356{
357 int i;
358 struct ttusbir_device *ttusbir;
359
360 DPRINTK("Module ttusbir disconnect\n");
361
362 ttusbir = (struct ttusbir_device *) usb_get_intfdata(intf);
363 usb_set_intfdata(intf, NULL);
364 lirc_unregister_driver(ttusbir->minor);
365 DPRINTK("unregistered\n");
366
367 for (i = 0; i < num_urbs; i++) {
368 usb_kill_urb(ttusbir->urb[i]);
369 usb_free_urb(ttusbir->urb[i]);
370 }
371 DPRINTK("URBs killed\n");
372 lirc_buffer_free(&ttusbir->rbuf);
373 kfree(ttusbir);
374}
375
376module_usb_driver(usb_driver);
diff --git a/drivers/staging/media/lirc/lirc_zilog.c b/drivers/staging/media/lirc/lirc_zilog.c
index 76ea4a8f2c75..11d5338b4f2f 100644
--- a/drivers/staging/media/lirc/lirc_zilog.c
+++ b/drivers/staging/media/lirc/lirc_zilog.c
@@ -658,8 +658,7 @@ static int send_data_block(struct IR_tx *tx, unsigned char *data_block)
658 buf[0] = (unsigned char)(i + 1); 658 buf[0] = (unsigned char)(i + 1);
659 for (j = 0; j < tosend; ++j) 659 for (j = 0; j < tosend; ++j)
660 buf[1 + j] = data_block[i + j]; 660 buf[1 + j] = data_block[i + j];
661 dprintk("%02x %02x %02x %02x %02x", 661 dprintk("%*ph", 5, buf);
662 buf[0], buf[1], buf[2], buf[3], buf[4]);
663 ret = i2c_master_send(tx->c, buf, tosend + 1); 662 ret = i2c_master_send(tx->c, buf, tosend + 1);
664 if (ret != tosend + 1) { 663 if (ret != tosend + 1) {
665 zilog_error("i2c_master_send failed with %d\n", ret); 664 zilog_error("i2c_master_send failed with %d\n", ret);