easycap_main.c revision 73019286cddc8bba1773944a7b6b603137fd66ff
1702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/****************************************************************************** 2702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas* * 3702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas* easycap_main.c * 4702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas* * 5702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas* Video driver for EasyCAP USB2.0 Video Capture Device DC60 * 6702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas* * 7702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas* * 8702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas******************************************************************************/ 9702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 10702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 11702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * Copyright (C) 2010 R.M. Thomas <rmthomas@sciolus.org> 12702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 13702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 14702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * This is free software; you can redistribute it and/or modify 15702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * it under the terms of the GNU General Public License as published by 16702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * the Free Software Foundation; either version 2 of the License, or 17702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * (at your option) any later version. 18702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 19702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * The software is distributed in the hope that it will be useful, 20702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * but WITHOUT ANY WARRANTY; without even the implied warranty of 21702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * GNU General Public License for more details. 23702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 24702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * You should have received a copy of the GNU General Public License 25702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * along with this software; if not, write to the Free Software 26702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 27702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 28702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas*/ 29702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 30702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 31702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas#include "easycap.h" 32fc3cc2caa07568de92cc84780b89b5cf9fbf28b7Tomas Winkler#include <linux/usb/audio.h> 33702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 3402149cf7c7fd1ece5ada28f5a95914f4348df44fTomas Winkler 3502149cf7c7fd1ece5ada28f5a95914f4348df44fTomas WinklerMODULE_LICENSE("GPL"); 3602149cf7c7fd1ece5ada28f5a95914f4348df44fTomas WinklerMODULE_AUTHOR("R.M. Thomas <rmthomas@sciolus.org>"); 3702149cf7c7fd1ece5ada28f5a95914f4348df44fTomas WinklerMODULE_DESCRIPTION(EASYCAP_DRIVER_DESCRIPTION); 3802149cf7c7fd1ece5ada28f5a95914f4348df44fTomas WinklerMODULE_VERSION(EASYCAP_DRIVER_VERSION); 3902149cf7c7fd1ece5ada28f5a95914f4348df44fTomas Winkler 4002149cf7c7fd1ece5ada28f5a95914f4348df44fTomas Winkler#ifdef CONFIG_EASYCAP_DEBUG 4118545cfd3623e5cd8960f5155f95e0a9c790a54cMike Thomasint easycap_debug; 4262af33ec6e73d658720ea1190861c8c0609a94b3Randy Dunlapmodule_param_named(debug, easycap_debug, int, S_IRUGO | S_IWUSR); 4302149cf7c7fd1ece5ada28f5a95914f4348df44fTomas WinklerMODULE_PARM_DESC(debug, "Debug level: 0(default),1,2,...,9"); 4402149cf7c7fd1ece5ada28f5a95914f4348df44fTomas Winkler#endif /* CONFIG_EASYCAP_DEBUG */ 4502149cf7c7fd1ece5ada28f5a95914f4348df44fTomas Winkler 462ef0c05e80cf59315f6f0a4e5a950899f169f2d0Tomas Winklerbool easycap_readback; 472ef0c05e80cf59315f6f0a4e5a950899f169f2d0Tomas Winklermodule_param_named(readback, easycap_readback, bool, S_IRUGO | S_IWUSR); 482ef0c05e80cf59315f6f0a4e5a950899f169f2d0Tomas WinklerMODULE_PARM_DESC(readback, "read back written registers: (default false)"); 492ef0c05e80cf59315f6f0a4e5a950899f169f2d0Tomas Winkler 5002149cf7c7fd1ece5ada28f5a95914f4348df44fTomas Winklerstatic int easycap_bars = 1; 5162af33ec6e73d658720ea1190861c8c0609a94b3Randy Dunlapmodule_param_named(bars, easycap_bars, int, S_IRUGO | S_IWUSR); 5202149cf7c7fd1ece5ada28f5a95914f4348df44fTomas WinklerMODULE_PARM_DESC(bars, 5302149cf7c7fd1ece5ada28f5a95914f4348df44fTomas Winkler "Testcard bars on input signal failure: 0=>no, 1=>yes(default)"); 54702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 5502149cf7c7fd1ece5ada28f5a95914f4348df44fTomas Winklerstatic int easycap_gain = 16; 5602149cf7c7fd1ece5ada28f5a95914f4348df44fTomas Winklermodule_param_named(gain, easycap_gain, int, S_IRUGO | S_IWUSR); 5702149cf7c7fd1ece5ada28f5a95914f4348df44fTomas WinklerMODULE_PARM_DESC(gain, "Audio gain: 0,...,16(default),...31"); 58d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler 598d6139547ca349f9acea6536dd6b7f6140d3507fTomas Winklerstatic bool easycap_ntsc; 608d6139547ca349f9acea6536dd6b7f6140d3507fTomas Winklermodule_param_named(ntsc, easycap_ntsc, bool, S_IRUGO | S_IWUSR); 618d6139547ca349f9acea6536dd6b7f6140d3507fTomas WinklerMODULE_PARM_DESC(ntsc, "NTCS default encoding (default PAL)"); 628d6139547ca349f9acea6536dd6b7f6140d3507fTomas Winkler 63d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler 64d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler 65a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomasstruct easycap_dongle easycapdc60_dongle[DONGLE_MANY]; 66a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomasstatic struct mutex mutex_dongle; 67d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic void easycap_complete(struct urb *purb); 68d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic int reset(struct easycap *peasycap); 69e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas 705c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winklerconst char *strerror(int err) 715c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler{ 725c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler#define ERRNOSTR(_e) case _e: return # _e 735c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler switch (err) { 745c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler case 0: return "OK"; 755c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(ENOMEM); 765c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(ENODEV); 775c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(ENXIO); 785c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EINVAL); 795c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EAGAIN); 805c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EFBIG); 815c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EPIPE); 825c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EMSGSIZE); 835c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(ENOSPC); 845c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EINPROGRESS); 855c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(ENOSR); 865c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EOVERFLOW); 875c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EPROTO); 885c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EILSEQ); 895c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(ETIMEDOUT); 905c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EOPNOTSUPP); 915c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EPFNOSUPPORT); 925c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EAFNOSUPPORT); 935c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EADDRINUSE); 945c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EADDRNOTAVAIL); 955c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(ENOBUFS); 965c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EISCONN); 975c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(ENOTCONN); 985c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(ESHUTDOWN); 995c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(ENOENT); 1005c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(ECONNRESET); 1015c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(ETIME); 1025c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(ECOMM); 1035c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EREMOTEIO); 1045c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EXDEV); 1055c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EPERM); 1065c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler default: return "unknown"; 1075c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler } 1085c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler 1095c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler#undef ERRNOSTR 1105c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler} 1115c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler 112e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas/*---------------------------------------------------------------------------*/ 113e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas/* 114702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * PARAMETERS USED WHEN REGISTERING THE VIDEO INTERFACE 115702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 116702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * NOTE: SOME KERNELS IGNORE usb_class_driver.minor_base, AS MENTIONED BY 117702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGE 253. 118702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * THIS IS THE CASE FOR OpenSUSE. 119702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 120702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 121702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ 122702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/****************************************************************************/ 123e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas/*---------------------------------------------------------------------------*/ 124702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 125268dfede46e24eef55a2ef7a10a462617936771eMike Thomas * THIS ROUTINE DOES NOT DETECT DUPLICATE OCCURRENCES OF POINTER peasycap 126e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas*/ 127e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas/*---------------------------------------------------------------------------*/ 128c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winklerint isdongle(struct easycap *peasycap) 129e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas{ 130c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int k; 1316888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) 132c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -2; 133c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (k = 0; k < DONGLE_MANY; k++) { 134c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (easycapdc60_dongle[k].peasycap == peasycap) { 135c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->isdongle = k; 136c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return k; 137c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 138e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas } 139c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -1; 140e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas} 141702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ 142d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic int easycap_open(struct inode *inode, struct file *file) 143702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 144c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct video_device *pvideo_device; 145c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct easycap *peasycap; 146c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int rc; 147702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 148c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOT(4, "\n"); 149c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("==========OPEN=========\n"); 150702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 151c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pvideo_device = video_devdata(file); 1526888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pvideo_device) { 153c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: pvideo_device is NULL.\n"); 154c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 155c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 156c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap = (struct easycap *)video_get_drvdata(pvideo_device); 1576888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 158c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap is NULL\n"); 159c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 160c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1616888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap->pusb_device) { 162c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: peasycap->pusb_device is NULL\n"); 163c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 164c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 165c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(16, "peasycap->pusb_device=%p\n", peasycap->pusb_device); 166c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 167c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler file->private_data = peasycap; 168c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = wakeup_device(peasycap->pusb_device); 169c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 == rc) 170c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "wakeup_device() OK\n"); 171c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else { 172c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: wakeup_device() rc = %i\n", rc); 173c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (-ENODEV == rc) 174c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: wakeup_device() returned -ENODEV\n"); 175c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 176c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: wakeup_device() rc = %i\n", rc); 177c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return rc; 178c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 179c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->input = 0; 180c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = reset(peasycap); 181c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) { 182c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: reset() rc = %i\n", rc); 183c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 184c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 185c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 186f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas} 187d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler 188f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*****************************************************************************/ 189f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*---------------------------------------------------------------------------*/ 190f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/* 191f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * RESET THE HARDWARE TO ITS REFERENCE STATE. 192f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * 193f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * THIS ROUTINE MAY BE CALLED REPEATEDLY IF easycap_complete() DETECTS 194f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * A BAD VIDEO FRAME SIZE. 195f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas*/ 196f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*---------------------------------------------------------------------------*/ 197d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic int reset(struct easycap *peasycap) 198f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas{ 199c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct easycap_standard const *peasycap_standard; 200fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler int fmtidx, input, rate; 201c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bool ntsc, other; 202fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler int rc; 203f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas 2046888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 205c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap is NULL\n"); 206c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 207c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 208c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler input = peasycap->input; 209f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas 210f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*---------------------------------------------------------------------------*/ 211f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/* 212ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * IF THE SAA7113H HAS ALREADY ACQUIRED SYNC, USE ITS HARDWARE-DETECTED 213f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * FIELD FREQUENCY TO DISTINGUISH NTSC FROM PAL. THIS IS ESSENTIAL FOR 214f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * gstreamer AND OTHER USERSPACE PROGRAMS WHICH MAY NOT ATTEMPT TO INITIATE 215f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * A SWITCH BETWEEN PAL AND NTSC. 216f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * 217f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * FUNCTION ready_saa() MAY REQUIRE A SUBSTANTIAL FRACTION OF A SECOND TO 218f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * COMPLETE, SO SHOULD NOT BE INVOKED WITHOUT GOOD REASON. 219f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas*/ 220f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*---------------------------------------------------------------------------*/ 221c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler other = false; 222c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "peasycap->ntsc=%d\n", peasycap->ntsc); 223c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 224c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rate = ready_saa(peasycap->pusb_device); 225fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler if (rate < 0) { 226c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "not ready to capture after %i ms ...\n", PATIENCE); 227fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler ntsc = !peasycap->ntsc; 228fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler JOM(8, "... trying %s ..\n", ntsc ? "NTSC" : "PAL"); 229fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler rc = setup_stk(peasycap->pusb_device, ntsc); 230fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler if (rc) { 231fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler SAM("ERROR: setup_stk() rc = %i\n", rc); 232fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler return -EFAULT; 233fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler } 234fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler rc = setup_saa(peasycap->pusb_device, ntsc); 235fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler if (rc) { 236fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler SAM("ERROR: setup_saa() rc = %i\n", rc); 237fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler return -EFAULT; 238fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler } 239fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler 240fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler rate = ready_saa(peasycap->pusb_device); 241fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler if (rate < 0) { 242fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler JOM(8, "not ready to capture after %i ms\n", PATIENCE); 243fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler JOM(8, "... saa register 0x1F has 0x%02X\n", 244c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler read_saa(peasycap->pusb_device, 0x1F)); 245fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler ntsc = peasycap->ntsc; 246c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 247c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "... success at second try: %i=rate\n", rate); 248c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ntsc = (0 < (rate/2)) ? true : false ; 249c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler other = true; 250c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 251f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } else { 252c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "... success at first try: %i=rate\n", rate); 253c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ntsc = (0 < rate/2) ? true : false ; 254c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 255c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "ntsc=%d\n", ntsc); 256c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler/*---------------------------------------------------------------------------*/ 257c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 258c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = setup_stk(peasycap->pusb_device, ntsc); 259fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler if (rc) { 260c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: setup_stk() rc = %i\n", rc); 261c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 262c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 263c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = setup_saa(peasycap->pusb_device, ntsc); 264fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler if (rc) { 265c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: setup_saa() rc = %i\n", rc); 266c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 267f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 268702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 269fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler memset(peasycap->merit, 0, sizeof(peasycap->merit)); 270c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 271c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_eof = 0; 272c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->audio_eof = 0; 273c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler do_gettimeofday(&peasycap->timeval7); 274f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*---------------------------------------------------------------------------*/ 275f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/* 276f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * RESTORE INPUT AND FORCE REFRESH OF STANDARD, FORMAT, ETC. 277f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * 278f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * WHILE THIS PROCEDURE IS IN PROGRESS, SOME IOCTL COMMANDS WILL RETURN -EBUSY. 279f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas*/ 280f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*---------------------------------------------------------------------------*/ 281c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->input = -8192; 282c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->standard_offset = -8192; 283c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler fmtidx = ntsc ? NTSC_M : PAL_BGHIN; 284c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (other) { 285c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap_standard = &easycap_standard[0]; 286c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (0xFFFF != peasycap_standard->mask) { 287c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (fmtidx == peasycap_standard->v4l2_standard.index) { 2881dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler peasycap->inputset[input].standard_offset = 289c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap_standard - easycap_standard; 290f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas break; 291f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 292c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap_standard++; 293f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 294c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0xFFFF == peasycap_standard->mask) { 295c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: standard not found\n"); 296c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EINVAL; 297c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 298c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=peasycap->inputset[%i].standard_offset\n", 299c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->inputset[input].standard_offset, input); 300f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 301c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->format_offset = -8192; 302c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->brightness = -8192; 303c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->contrast = -8192; 304c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->saturation = -8192; 305c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->hue = -8192; 306f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas 307c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = newinput(peasycap, input); 308702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 309c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) { 310c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: newinput(.,%i) rc = %i\n", rc, input); 311c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 312c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 313f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas JOM(4, "restored input, standard and format\n"); 314c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 315c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "true=peasycap->ntsc %d\n", peasycap->ntsc); 316c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 317c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 > peasycap->input) { 318c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=peasycap->input\n", peasycap->input); 319c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ENOENT; 320c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 321c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 > peasycap->standard_offset) { 322c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=peasycap->standard_offset\n", 323c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->standard_offset); 324c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ENOENT; 325c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 326c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 > peasycap->format_offset) { 327c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=peasycap->format_offset\n", 328c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->format_offset); 329c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ENOENT; 330c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 331c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 > peasycap->brightness) { 332c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=peasycap->brightness\n", 333c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->brightness); 334c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ENOENT; 335c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 336c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 > peasycap->contrast) { 337c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=peasycap->contrast\n", peasycap->contrast); 338c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ENOENT; 339c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 340c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 > peasycap->saturation) { 341c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=peasycap->saturation\n", 342c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->saturation); 343c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ENOENT; 344c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 345c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 > peasycap->hue) { 346c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=peasycap->hue\n", peasycap->hue); 347c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ENOENT; 348c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 349c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 350f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas} 351f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*****************************************************************************/ 352f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*---------------------------------------------------------------------------*/ 353f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/* 354f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * IF THE REQUESTED INPUT IS THE SAME AS THE EXISTING INPUT, DO NOTHING. 355f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * OTHERWISE: 356f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * KILL URBS, CLEAR FIELD AND FRAME BUFFERS AND RESET THEIR 357f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * _read AND _fill POINTERS. 358f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * SELECT THE NEW INPUT. 359f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * ADJUST THE STANDARD, FORMAT, BRIGHTNESS, CONTRAST, SATURATION AND HUE 360f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * ON THE BASIS OF INFORMATION IN STRUCTURE easycap.inputset[input]. 361f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * RESUBMIT THE URBS IF STREAMING WAS ALREADY IN PROGRESS. 362f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * 363f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * NOTE: 364f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * THIS ROUTINE MAY BE CALLED FREQUENTLY BY ZONEMINDER VIA IOCTL, 365f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * SO IT SHOULD WRITE ONLY SPARINGLY TO THE LOGFILE. 366f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas*/ 367f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*---------------------------------------------------------------------------*/ 368f36bc37a48148f31f936557b811431b98dbfe347Mike Thomasint 369f36bc37a48148f31f936557b811431b98dbfe347Mike Thomasnewinput(struct easycap *peasycap, int input) 370f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas{ 371c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int rc, k, m, mood, off; 372c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int inputnow, video_idlenow, audio_idlenow; 373c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bool resubmit; 374f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas 3756888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 376c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap is NULL\n"); 377c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 378c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 379c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=input sought\n", input); 380702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 381c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 > input && INPUT_MANY <= input) 382c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ENOENT; 383c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler inputnow = peasycap->input; 384c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (input == inputnow) 385c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 386702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 387f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/* 388f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * IF STREAMING IS IN PROGRESS THE URBS ARE KILLED AT THIS 389f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * STAGE AND WILL BE RESUBMITTED PRIOR TO EXIT FROM THE ROUTINE. 390f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * IF NO STREAMING IS IN PROGRESS NO URBS WILL BE SUBMITTED BY THE 391f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * ROUTINE. 392f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas*/ 393f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*---------------------------------------------------------------------------*/ 394c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler video_idlenow = peasycap->video_idle; 395c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler audio_idlenow = peasycap->audio_idle; 396f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas 397c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_idle = 1; 398c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->audio_idle = 1; 399c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->video_isoc_streaming) { 400c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler resubmit = true; 401c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler kill_video_urbs(peasycap); 402c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 403c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler resubmit = false; 404c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 405f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*---------------------------------------------------------------------------*/ 4066888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap->pusb_device) { 407c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: peasycap->pusb_device is NULL\n"); 408c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ENODEV; 409c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 410c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = usb_set_interface(peasycap->pusb_device, 411c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_interface, 412c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_altsetting_off); 413c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) { 414c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: usb_set_interface() rc = %i\n", rc); 415c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 416c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 417c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = stop_100(peasycap->pusb_device); 418c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) { 419c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: stop_100() rc = %i\n", rc); 420c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 421c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 422c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (k = 0; k < FIELD_BUFFER_MANY; k++) { 423c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) 424c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler memset(peasycap->field_buffer[k][m].pgo, 0, PAGE_SIZE); 425c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 426c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (k = 0; k < FRAME_BUFFER_MANY; k++) { 427c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) 428c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler memset(peasycap->frame_buffer[k][m].pgo, 0, PAGE_SIZE); 429c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 430c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_page = 0; 431c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_read = 0; 432c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_fill = 0; 433c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 434c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->frame_read = 0; 435c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->frame_fill = 0; 436c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (k = 0; k < peasycap->input; k++) { 437c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap->frame_fill)++; 438c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->frame_buffer_many <= peasycap->frame_fill) 439c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->frame_fill = 0; 440c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 441c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->input = input; 442c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler select_input(peasycap->pusb_device, peasycap->input, 9); 443f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*---------------------------------------------------------------------------*/ 444c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (input == peasycap->inputset[input].input) { 445c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler off = peasycap->inputset[input].standard_offset; 446c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (off != peasycap->standard_offset) { 447c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = adjust_standard(peasycap, 448f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas easycap_standard[off].v4l2_standard.id); 449c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) { 450c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: adjust_standard() rc = %i\n", rc); 451c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 452c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 453c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=peasycap->standard_offset\n", 454c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->standard_offset); 455c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 456c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=peasycap->standard_offset unchanged\n", 457f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas peasycap->standard_offset); 458f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 459c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler off = peasycap->inputset[input].format_offset; 460c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (off != peasycap->format_offset) { 461c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct v4l2_pix_format *pix = 462c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler &easycap_format[off].v4l2_format.fmt.pix; 463c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = adjust_format(peasycap, 464c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pix->width, pix->height, 465c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pix->pixelformat, pix->field, false); 466c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 > rc) { 467c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: adjust_format() rc = %i\n", rc); 468c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 469c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 470c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=peasycap->format_offset\n", 471c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->format_offset); 472c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 473c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=peasycap->format_offset unchanged\n", 474c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->format_offset); 475f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 476c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mood = peasycap->inputset[input].brightness; 477c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (mood != peasycap->brightness) { 478c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = adjust_brightness(peasycap, mood); 479c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) { 480c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: adjust_brightness rc = %i\n", rc); 481c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 482c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 483c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=peasycap->brightness\n", 484c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->brightness); 485f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 486c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mood = peasycap->inputset[input].contrast; 487c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (mood != peasycap->contrast) { 488c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = adjust_contrast(peasycap, mood); 489c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) { 490c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: adjust_contrast rc = %i\n", rc); 491c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 492c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 493c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=peasycap->contrast\n", peasycap->contrast); 494f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 495c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mood = peasycap->inputset[input].saturation; 496c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (mood != peasycap->saturation) { 497c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = adjust_saturation(peasycap, mood); 498c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) { 499c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: adjust_saturation rc = %i\n", rc); 500c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 501c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 502c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=peasycap->saturation\n", 503c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->saturation); 504c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 505c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mood = peasycap->inputset[input].hue; 506c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (mood != peasycap->hue) { 507c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = adjust_hue(peasycap, mood); 508c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) { 509c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: adjust_hue rc = %i\n", rc); 510c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 511c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 512c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=peasycap->hue\n", peasycap->hue); 513f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 514c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 515c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: easycap.inputset[%i] unpopulated\n", input); 516c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ENOENT; 517f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 518702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 5196888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap->pusb_device) { 520c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: peasycap->pusb_device is NULL\n"); 521c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ENODEV; 522c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 523c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = usb_set_interface(peasycap->pusb_device, 524c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_interface, 525c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_altsetting_on); 526c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) { 527c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: usb_set_interface() rc = %i\n", rc); 528c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 529c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 530c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = start_100(peasycap->pusb_device); 531c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) { 532c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: start_100() rc = %i\n", rc); 533c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 534c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 53527d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (resubmit) 536c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler submit_video_urbs(peasycap); 537f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas 538c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_isoc_sequence = VIDEO_ISOC_BUFFER_MANY - 1; 539c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_idle = video_idlenow; 540c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->audio_idle = audio_idlenow; 541c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_junk = 0; 542702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 543c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 544702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 545702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 546d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerint submit_video_urbs(struct easycap *peasycap) 547702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 548c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct data_urb *pdata_urb; 549c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct urb *purb; 550c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct list_head *plist_head; 551c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int j, isbad, nospc, m, rc; 552c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int isbuf; 553e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas 5546888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 555c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap is NULL\n"); 556c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 557c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 558c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 5596888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap->purb_video_head) { 560c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap->urb_video_head uninitialized\n"); 561c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 562c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 5636888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap->pusb_device) { 564c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap->pusb_device is NULL\n"); 565c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ENODEV; 566c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 567c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!peasycap->video_isoc_streaming) { 568c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "submission of all video urbs\n"); 569c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isbad = 0; nospc = 0; m = 0; 570c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler list_for_each(plist_head, (peasycap->purb_video_head)) { 571c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pdata_urb = list_entry(plist_head, 572c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct data_urb, list_head); 573c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (pdata_urb && pdata_urb->purb) { 574c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler purb = pdata_urb->purb; 575702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas isbuf = pdata_urb->isbuf; 576702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas purb->interval = 1; 577702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas purb->dev = peasycap->pusb_device; 5781dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler purb->pipe = 5791dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler usb_rcvisocpipe(peasycap->pusb_device, 580702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas peasycap->video_endpointnumber); 581702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas purb->transfer_flags = URB_ISO_ASAP; 5821dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler purb->transfer_buffer = 583702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas peasycap->video_isoc_buffer[isbuf].pgo; 5841dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler purb->transfer_buffer_length = 585702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas peasycap->video_isoc_buffer_size; 586702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas purb->complete = easycap_complete; 587702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas purb->context = peasycap; 588702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas purb->start_frame = 0; 5891dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler purb->number_of_packets = 590702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas peasycap->video_isoc_framesperdesc; 591702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 592c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (j = 0; j < peasycap->video_isoc_framesperdesc; j++) { 593c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler purb->iso_frame_desc[j]. offset = 594c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler j * peasycap->video_isoc_maxframesize; 595c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler purb->iso_frame_desc[j]. length = 596c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_isoc_maxframesize; 597c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 598702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 599702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas rc = usb_submit_urb(purb, GFP_KERNEL); 6005c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler if (rc) { 601702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas isbad++; 6021dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler SAM("ERROR: usb_submit_urb() failed " 603c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "for urb with rc:-%s\n", 6045c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler strerror(rc)); 6055c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler if (rc == -ENOSPC) 606e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas nospc++; 607702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } else { 608702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas m++; 609702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 610702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } else { 6115c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler isbad++; 612702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 613702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 614c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (nospc) { 615c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc); 616c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("..... possibly inadequate USB bandwidth\n"); 617c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_eof = 1; 618c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 619e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas 620c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (isbad) { 621c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "attempting cleanup instead of submitting\n"); 622c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler list_for_each(plist_head, (peasycap->purb_video_head)) { 623c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pdata_urb = list_entry(plist_head, 624c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct data_urb, list_head); 6256888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (pdata_urb) { 626c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler purb = pdata_urb->purb; 6276888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (purb) 628c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler usb_kill_urb(purb); 629c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 630702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 631c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_isoc_streaming = 0; 632c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 633c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_isoc_streaming = 1; 634c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "submitted %i video urbs\n", m); 635702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 636702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } else { 637c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "already streaming video urbs\n"); 638702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 639c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 640702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 641702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 642c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winklerint kill_video_urbs(struct easycap *peasycap) 643702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 644c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int m; 645c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct list_head *plist_head; 646c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct data_urb *pdata_urb; 647702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 6486888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 649c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap is NULL\n"); 650c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 651c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 652c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!peasycap->video_isoc_streaming) { 653c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=video_isoc_streaming, no video urbs killed\n", 654c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_isoc_streaming); 655c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 656c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 657c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!peasycap->purb_video_head) { 658e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas SAM("ERROR: peasycap->purb_video_head is NULL\n"); 659702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas return -EFAULT; 660702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 661c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 662c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_isoc_streaming = 0; 663c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "killing video urbs\n"); 664c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler m = 0; 665c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler list_for_each(plist_head, (peasycap->purb_video_head)) { 666c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pdata_urb = list_entry(plist_head, struct data_urb, list_head); 667c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (pdata_urb && pdata_urb->purb) { 668c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler usb_kill_urb(pdata_urb->purb); 669c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler m++; 670c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 671c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 672c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "%i video urbs killed\n", m); 673c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 674c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 675702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 676702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/****************************************************************************/ 677702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ 678702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*--------------------------------------------------------------------------*/ 679d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic int easycap_open_noinode(struct file *file) 680d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler{ 681d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler return easycap_open(NULL, file); 682d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler} 683d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler 684d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic int videodev_release(struct video_device *pvideo_device) 685702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 686c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct easycap *peasycap; 687702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 688c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap = video_get_drvdata(pvideo_device); 6896888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 690c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap is NULL\n"); 691c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ending unsuccessfully\n"); 692c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 693c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 694c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 != kill_video_urbs(peasycap)) { 695c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: kill_video_urbs() failed\n"); 696c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 697c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 698c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "ending successfully\n"); 699c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 700702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 701e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ 702e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas/*****************************************************************************/ 703702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*--------------------------------------------------------------------------*/ 704702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 705ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * THIS FUNCTION IS CALLED FROM WITHIN easycap_usb_disconnect() AND IS 706ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * PROTECTED BY SEMAPHORES SET AND CLEARED BY easycap_usb_disconnect(). 707ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * 708ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * BY THIS STAGE THE DEVICE HAS ALREADY BEEN PHYSICALLY UNPLUGGED, SO 709ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * peasycap->pusb_device IS NO LONGER VALID. 710702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 711702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 712d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic void easycap_delete(struct kref *pkref) 713702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 714c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct easycap *peasycap; 715c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct data_urb *pdata_urb; 716c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct list_head *plist_head, *plist_next; 717c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int k, m, gone, kd; 718c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int allocation_video_urb; 719c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int allocation_video_page; 720c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int allocation_video_struct; 721c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int allocation_audio_urb; 722c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int allocation_audio_page; 723c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int allocation_audio_struct; 724c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int registered_video, registered_audio; 725c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 726c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap = container_of(pkref, struct easycap, kref); 7276888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 728c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: peasycap is NULL: cannot perform deletions\n"); 729c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 730c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 731c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler kd = isdongle(peasycap); 732702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 733702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 734702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * FREE VIDEO. 735702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 736702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 7376888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (peasycap->purb_video_head) { 738c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "freeing video urbs\n"); 739c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler m = 0; 740c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler list_for_each(plist_head, (peasycap->purb_video_head)) { 741c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pdata_urb = list_entry(plist_head, 742c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct data_urb, list_head); 7436888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pdata_urb) { 744c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "ERROR: pdata_urb is NULL\n"); 745c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 7466888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (pdata_urb->purb) { 747c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler usb_free_urb(pdata_urb->purb); 748c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pdata_urb->purb = NULL; 749c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->allocation_video_urb -= 1; 750c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler m++; 751c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 752702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 753702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 754702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 755c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "%i video urbs freed\n", m); 756702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 757c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "freeing video data_urb structures.\n"); 758c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler m = 0; 759c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler list_for_each_safe(plist_head, plist_next, 760c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->purb_video_head) { 761c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pdata_urb = list_entry(plist_head, 762c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct data_urb, list_head); 763c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (pdata_urb) { 764c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->allocation_video_struct -= 765702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas sizeof(struct data_urb); 766c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler kfree(pdata_urb); 767c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pdata_urb = NULL; 768c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler m++; 769c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 770702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 771c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "%i video data_urb structures freed\n", m); 772c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "setting peasycap->purb_video_head=NULL\n"); 773c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->purb_video_head = NULL; 774702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 775702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 776c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "freeing video isoc buffers.\n"); 777c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler m = 0; 778c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { 779c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->video_isoc_buffer[k].pgo) { 780c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler free_pages((unsigned long) 781c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_isoc_buffer[k].pgo, 782c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler VIDEO_ISOC_ORDER); 783c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_isoc_buffer[k].pgo = NULL; 784c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->allocation_video_page -= 785c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler BIT(VIDEO_ISOC_ORDER); 786c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler m++; 787c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 788702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 789c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "isoc video buffers freed: %i pages\n", 790c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler m * (0x01 << VIDEO_ISOC_ORDER)); 791c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler/*---------------------------------------------------------------------------*/ 792c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "freeing video field buffers.\n"); 793c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler gone = 0; 794c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (k = 0; k < FIELD_BUFFER_MANY; k++) { 795c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) { 7966888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (peasycap->field_buffer[k][m].pgo) { 797c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler free_page((unsigned long) 798c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_buffer[k][m].pgo); 799c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_buffer[k][m].pgo = NULL; 800c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->allocation_video_page -= 1; 801c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler gone++; 802c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 803702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 804702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 805c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "video field buffers freed: %i pages\n", gone); 806c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler/*---------------------------------------------------------------------------*/ 807c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "freeing video frame buffers.\n"); 808c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler gone = 0; 809c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (k = 0; k < FRAME_BUFFER_MANY; k++) { 810c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) { 8116888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (peasycap->frame_buffer[k][m].pgo) { 812c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler free_page((unsigned long) 813c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->frame_buffer[k][m].pgo); 814c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->frame_buffer[k][m].pgo = NULL; 815c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->allocation_video_page -= 1; 816c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler gone++; 817c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 818702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 819702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 820c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "video frame buffers freed: %i pages\n", gone); 821702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 822702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 823702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * FREE AUDIO. 824702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 825702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 8266888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (peasycap->purb_audio_head) { 827c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "freeing audio urbs\n"); 828c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler m = 0; 829c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler list_for_each(plist_head, (peasycap->purb_audio_head)) { 830c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pdata_urb = list_entry(plist_head, 831c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct data_urb, list_head); 8326888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pdata_urb) 833c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "ERROR: pdata_urb is NULL\n"); 834c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else { 8356888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (pdata_urb->purb) { 836c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler usb_free_urb(pdata_urb->purb); 837c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pdata_urb->purb = NULL; 838c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->allocation_audio_urb -= 1; 839c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler m++; 840c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 841c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 842c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 843c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "%i audio urbs freed\n", m); 844c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler/*---------------------------------------------------------------------------*/ 845c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "freeing audio data_urb structures.\n"); 846c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler m = 0; 847c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler list_for_each_safe(plist_head, plist_next, 848c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->purb_audio_head) { 849c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pdata_urb = list_entry(plist_head, 850c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct data_urb, list_head); 851c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (pdata_urb) { 852c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->allocation_audio_struct -= 853c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler sizeof(struct data_urb); 854c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler kfree(pdata_urb); 855c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pdata_urb = NULL; 856702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas m++; 857702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 858702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 859c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "%i audio data_urb structures freed\n", m); 860c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "setting peasycap->purb_audio_head=NULL\n"); 861c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->purb_audio_head = NULL; 862702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 863702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 864c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "freeing audio isoc buffers.\n"); 865702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas m = 0; 866c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { 8676888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (peasycap->audio_isoc_buffer[k].pgo) { 868c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler free_pages((unsigned long) 869c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap->audio_isoc_buffer[k].pgo), 870c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler AUDIO_ISOC_ORDER); 871c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->audio_isoc_buffer[k].pgo = NULL; 872c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->allocation_audio_page -= 873c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler BIT(AUDIO_ISOC_ORDER); 874702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas m++; 875702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 876702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 877c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "easyoss_delete(): isoc audio buffers freed: %i pages\n", 878702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas m * (0x01 << AUDIO_ISOC_ORDER)); 879702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 880c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "freeing easycap structure.\n"); 881c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler allocation_video_urb = peasycap->allocation_video_urb; 882c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler allocation_video_page = peasycap->allocation_video_page; 883c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler allocation_video_struct = peasycap->allocation_video_struct; 884c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler registered_video = peasycap->registered_video; 885c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler allocation_audio_urb = peasycap->allocation_audio_urb; 886c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler allocation_audio_page = peasycap->allocation_audio_page; 887c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler allocation_audio_struct = peasycap->allocation_audio_struct; 888c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler registered_audio = peasycap->registered_audio; 889c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 890c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 <= kd && DONGLE_MANY > kd) { 891c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (mutex_lock_interruptible(&mutex_dongle)) { 892c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: cannot down mutex_dongle\n"); 893c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 894c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "locked mutex_dongle\n"); 895c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler easycapdc60_dongle[kd].peasycap = NULL; 896c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mutex_unlock(&mutex_dongle); 897c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "unlocked mutex_dongle\n"); 898c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOT(4, " null-->dongle[%i].peasycap\n", kd); 899c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler allocation_video_struct -= sizeof(struct easycap); 900c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 901a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas } else { 902c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: cannot purge dongle[].peasycap"); 903c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 90438d0cffefd3daaad6bc58a6212d16edeaa8ee1f0Dan Carpenter 90538d0cffefd3daaad6bc58a6212d16edeaa8ee1f0Dan Carpenter kfree(peasycap); 90638d0cffefd3daaad6bc58a6212d16edeaa8ee1f0Dan Carpenter 907702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 908c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("%8i=video urbs after all deletions\n", allocation_video_urb); 909c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("%8i=video pages after all deletions\n", allocation_video_page); 910c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("%8i=video structs after all deletions\n", allocation_video_struct); 911c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("%8i=video devices after all deletions\n", registered_video); 912c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("%8i=audio urbs after all deletions\n", allocation_audio_urb); 913c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("%8i=audio pages after all deletions\n", allocation_audio_page); 914c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("%8i=audio structs after all deletions\n", allocation_audio_struct); 915c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("%8i=audio devices after all deletions\n", registered_audio); 916c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 917c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOT(4, "ending.\n"); 918c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 919702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 920702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 921d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic unsigned int easycap_poll(struct file *file, poll_table *wait) 922702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 923c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct easycap *peasycap; 924c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int rc, kd; 925702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 926c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOT(8, "\n"); 927702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 928c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (NULL == ((poll_table *)wait)) 929c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOT(8, "WARNING: poll table pointer is NULL ... continuing\n"); 9306888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!file) { 931c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: file pointer is NULL\n"); 932ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas return -ERESTARTSYS; 933ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas } 934ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas peasycap = file->private_data; 9356888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 936ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas SAY("ERROR: peasycap is NULL\n"); 937c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 938ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas } 9396888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap->pusb_device) { 940c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap->pusb_device is NULL\n"); 941c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 942ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas } 943c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler/*---------------------------------------------------------------------------*/ 944c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler kd = isdongle(peasycap); 945c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 <= kd && DONGLE_MANY > kd) { 946c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) { 947c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: cannot down dongle[%i].mutex_video\n", kd); 948c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ERESTARTSYS; 949c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 950c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "locked dongle[%i].mutex_video\n", kd); 951c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* 952c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER 953c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * peasycap, IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. 954c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * IF NECESSARY, BAIL OUT. 955c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler */ 956c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (kd != isdongle(peasycap)) 957c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ERESTARTSYS; 9586888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!file) { 959c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: file is NULL\n"); 960c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mutex_unlock(&easycapdc60_dongle[kd].mutex_video); 961c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ERESTARTSYS; 962c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 963c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap = file->private_data; 9646888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 965c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap is NULL\n"); 966c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mutex_unlock(&easycapdc60_dongle[kd].mutex_video); 967c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ERESTARTSYS; 968c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 9696888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap->pusb_device) { 970c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: peasycap->pusb_device is NULL\n"); 971c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mutex_unlock(&easycapdc60_dongle[kd].mutex_video); 972c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ERESTARTSYS; 973c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 974c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else 975ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas /* 976ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap 977ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * BEFORE THE ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL 978ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * HAVE FAILED. BAIL OUT. 979ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas */ 980c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ERESTARTSYS; 981c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler/*---------------------------------------------------------------------------*/ 982c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = easycap_dqbuf(peasycap, 0); 983c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->polled = 1; 984c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mutex_unlock(&easycapdc60_dongle[kd].mutex_video); 985c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 == rc) 986c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return POLLIN | POLLRDNORM; 987c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 988c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return POLLERR; 989c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 990702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 991702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 992702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 993702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * IF mode IS NONZERO THIS ROUTINE RETURNS -EAGAIN RATHER THAN BLOCKING. 994702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 995702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 996c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winklerint easycap_dqbuf(struct easycap *peasycap, int mode) 997702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 998c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int input, ifield, miss, rc; 999702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1000702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 10016888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 1002c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap is NULL\n"); 1003c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 1004c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 10056888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap->pusb_device) { 1006c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap->pusb_device is NULL\n"); 1007c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 1008c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1009c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ifield = 0; 1010c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=ifield\n", ifield); 1011702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1012702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 1013849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas * CHECK FOR LOST INPUT SIGNAL. 1014849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas * 1015849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas * FOR THE FOUR-CVBS EasyCAP, THIS DOES NOT WORK AS EXPECTED. 1016ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * IF INPUT 0 IS PRESENT AND SYNC ACQUIRED, UNPLUGGING INPUT 4 DOES NOT 1017ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * RESULT IN SETTING BIT 0x40 ON REGISTER 0x1F, PRESUMABLY BECAUSE THERE 1018ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * IS FLYWHEELING ON INPUT 0. THE UPSHOT IS: 1019849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas * 1020849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas * INPUT 0 PLUGGED, INPUT 4 PLUGGED => SCREEN 0 OK, SCREEN 4 OK 1021849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas * INPUT 0 PLUGGED, INPUT 4 UNPLUGGED => SCREEN 0 OK, SCREEN 4 BLACK 1022849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas * INPUT 0 UNPLUGGED, INPUT 4 PLUGGED => SCREEN 0 BARS, SCREEN 4 OK 1023849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas * INPUT 0 UNPLUGGED, INPUT 4 UNPLUGGED => SCREEN 0 BARS, SCREEN 4 BARS 1024849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas*/ 1025849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas/*---------------------------------------------------------------------------*/ 1026c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler input = peasycap->input; 1027c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 <= input && INPUT_MANY > input) { 1028c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = read_saa(peasycap->pusb_device, 0x1F); 1029c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 <= rc) { 1030c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc & 0x40) 1031c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->lost[input] += 1; 1032c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1033c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->lost[input] -= 2; 1034849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas 1035c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 > peasycap->lost[input]) 1036c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->lost[input] = 0; 1037c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else if ((2 * VIDEO_LOST_TOLERATE) < peasycap->lost[input]) 1038c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->lost[input] = (2 * VIDEO_LOST_TOLERATE); 1039c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1040849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas } 1041849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas/*---------------------------------------------------------------------------*/ 1042849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas/* 104340b8d50ac98f8c8779aea7459f805e5a69fdb726Mike Thomas * WAIT FOR FIELD ifield (0 => TOP, 1 => BOTTOM) 1044702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 1045702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1046c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler miss = 0; 1047c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while ((peasycap->field_read == peasycap->field_fill) || 1048c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (0 != (0xFF00 & peasycap->field_buffer 10491dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler [peasycap->field_read][0].kount)) || 1050c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (ifield != (0x00FF & peasycap->field_buffer 1051702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas [peasycap->field_read][0].kount))) { 1052c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (mode) 1053c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EAGAIN; 1054702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1055a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler JOM(8, "first wait on wq_video, %i=field_read %i=field_fill\n", 1056a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->field_read, peasycap->field_fill); 1057c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 1058c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 != (wait_event_interruptible(peasycap->wq_video, 1059c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap->video_idle || peasycap->video_eof || 1060c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ((peasycap->field_read != peasycap->field_fill) && 1061a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler (0 == (0xFF00 & peasycap->field_buffer[peasycap->field_read][0].kount)) && 1062a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler (ifield == (0x00FF & peasycap->field_buffer[peasycap->field_read][0].kount))))))) { 1063c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("aborted by signal\n"); 1064c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EIO; 1065a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler } 1066c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->video_idle) { 1067c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=peasycap->video_idle returning -EAGAIN\n", 1068c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_idle); 1069f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas return -EAGAIN; 1070f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 1071c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->video_eof) { 1072c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=peasycap->video_eof\n", peasycap->video_eof); 1073c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler #if defined(PERSEVERE) 1074c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (1 == peasycap->status) { 1075c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "persevering ...\n"); 1076c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_eof = 0; 1077c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->audio_eof = 0; 1078c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 != reset(peasycap)) { 1079c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, " ... failed returning -EIO\n"); 1080c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_eof = 1; 1081c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->audio_eof = 1; 1082c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler kill_video_urbs(peasycap); 1083c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EIO; 1084c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1085c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->status = 0; 1086c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, " ... OK returning -EAGAIN\n"); 1087c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EAGAIN; 1088c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1089c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler #endif /*PERSEVERE*/ 1090c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_eof = 1; 1091c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->audio_eof = 1; 1092c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler kill_video_urbs(peasycap); 1093c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "returning -EIO\n"); 1094c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EIO; 1095c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1096a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler miss++; 1097702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1098c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "first awakening on wq_video after %i waits\n", miss); 1099702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1100c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = field2frame(peasycap); 1101c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) 1102c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: field2frame() rc = %i\n", rc); 1103702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1104702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 110540b8d50ac98f8c8779aea7459f805e5a69fdb726Mike Thomas * WAIT FOR THE OTHER FIELD 1106702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 1107702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1108c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (ifield) 1109c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ifield = 0; 1110c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1111c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ifield = 1; 1112c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler miss = 0; 1113c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while ((peasycap->field_read == peasycap->field_fill) || 1114a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler (0 != (0xFF00 & peasycap->field_buffer[peasycap->field_read][0].kount)) || 1115a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler (ifield != (0x00FF & peasycap->field_buffer[peasycap->field_read][0].kount))) { 1116c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (mode) 1117c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EAGAIN; 1118702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1119c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "second wait on wq_video %i=field_read %i=field_fill\n", 1120702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas peasycap->field_read, peasycap->field_fill); 1121c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 != (wait_event_interruptible(peasycap->wq_video, 11221dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler (peasycap->video_idle || peasycap->video_eof || 11231dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler ((peasycap->field_read != peasycap->field_fill) && 1124a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler (0 == (0xFF00 & peasycap->field_buffer[peasycap->field_read][0].kount)) && 1125a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler (ifield == (0x00FF & peasycap->field_buffer[peasycap->field_read][0].kount))))))) { 1126c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("aborted by signal\n"); 1127c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EIO; 1128c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1129c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->video_idle) { 1130c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=peasycap->video_idle returning -EAGAIN\n", 1131f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas peasycap->video_idle); 1132f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas return -EAGAIN; 1133f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 1134c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->video_eof) { 1135c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=peasycap->video_eof\n", peasycap->video_eof); 1136a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler#if defined(PERSEVERE) 1137c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (1 == peasycap->status) { 1138c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "persevering ...\n"); 1139c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_eof = 0; 1140c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->audio_eof = 0; 1141c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 != reset(peasycap)) { 1142c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, " ... failed returning -EIO\n"); 1143c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_eof = 1; 1144c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->audio_eof = 1; 1145c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler kill_video_urbs(peasycap); 1146c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EIO; 1147c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1148c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->status = 0; 1149c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, " ... OK ... returning -EAGAIN\n"); 1150c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EAGAIN; 1151c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1152a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler#endif /*PERSEVERE*/ 1153c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_eof = 1; 1154c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->audio_eof = 1; 1155c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler kill_video_urbs(peasycap); 1156c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "returning -EIO\n"); 1157c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EIO; 1158c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1159a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler miss++; 1160702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1161c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "second awakening on wq_video after %i waits\n", miss); 1162702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1163c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = field2frame(peasycap); 1164c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) 1165c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: field2frame() rc = %i\n", rc); 116640b8d50ac98f8c8779aea7459f805e5a69fdb726Mike Thomas/*---------------------------------------------------------------------------*/ 116740b8d50ac98f8c8779aea7459f805e5a69fdb726Mike Thomas/* 116840b8d50ac98f8c8779aea7459f805e5a69fdb726Mike Thomas * WASTE THIS FRAME 116940b8d50ac98f8c8779aea7459f805e5a69fdb726Mike Thomas*/ 117040b8d50ac98f8c8779aea7459f805e5a69fdb726Mike Thomas/*---------------------------------------------------------------------------*/ 1171a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler if (peasycap->skip) { 1172c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->skipped++; 1173c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->skip != peasycap->skipped) 1174c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return peasycap->skip - peasycap->skipped; 1175a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler else 1176a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->skipped = 0; 1177c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 117840b8d50ac98f8c8779aea7459f805e5a69fdb726Mike Thomas/*---------------------------------------------------------------------------*/ 1179c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->frame_read = peasycap->frame_fill; 1180c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->queued[peasycap->frame_read] = 0; 1181c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->done[peasycap->frame_read] = V4L2_BUF_FLAG_DONE; 1182702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1183c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->frame_fill++; 1184c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->frame_buffer_many <= peasycap->frame_fill) 1185c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->frame_fill = 0; 1186702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1187c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x01 & easycap_standard[peasycap->standard_offset].mask) 1188c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->frame_buffer[peasycap->frame_read][0].kount = 1189702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas V4L2_FIELD_TOP; 1190c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1191c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->frame_buffer[peasycap->frame_read][0].kount = 1192702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas V4L2_FIELD_BOTTOM; 1193702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1194702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1195c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "setting: %i=peasycap->frame_read\n", peasycap->frame_read); 1196c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "bumped to: %i=peasycap->frame_fill\n", peasycap->frame_fill); 1197c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 1198c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 1199702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 1200702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 1201702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1202702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 1203702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * BY DEFINITION, odd IS true FOR THE FIELD OCCUPYING LINES 1,3,5,...,479 1204702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * odd IS false FOR THE FIELD OCCUPYING LINES 0,2,4,...,478 1205702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 1206702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * WHEN BOOLEAN PARAMETER decimatepixel IS true, ONLY THE FIELD FOR WHICH 1207702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * odd==false IS TRANSFERRED TO THE FRAME BUFFER. 1208702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 1209702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * THE BOOLEAN PARAMETER offerfields IS true ONLY WHEN THE USER PROGRAM 121040b8d50ac98f8c8779aea7459f805e5a69fdb726Mike Thomas * CHOOSES THE OPTION V4L2_FIELD_INTERLACED. 1211702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 1212702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1213702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomasint 1214702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomasfield2frame(struct easycap *peasycap) 1215702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 1216c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct timeval timeval; 1217c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler long long int above, below; 1218c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u32 remainder; 1219c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct signed_div_result sdr; 1220c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 1221c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler void *pex, *pad; 1222c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int kex, kad, mex, mad, rex, rad, rad2; 1223c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int c2, c3, w2, w3, cz, wz; 1224c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int rc, bytesperpixel, multiplier; 1225c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int much, more, over, rump, caches, input; 1226c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u8 mask, margin; 1227c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bool odd, isuy, decimatepixel, offerfields, badinput; 1228c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 12296888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 1230c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap is NULL\n"); 1231c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 1232c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1233e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas 1234c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler badinput = false; 1235c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler input = 0x07 & peasycap->field_buffer[peasycap->field_read][0].input; 1236f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas 1237c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "===== parity %i, input 0x%02X, field buffer %i --> " 1238c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "frame buffer %i\n", 12391dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler peasycap->field_buffer[peasycap->field_read][0].kount, 12401dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler peasycap->field_buffer[peasycap->field_read][0].input, 1241702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas peasycap->field_read, peasycap->frame_fill); 1242c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "===== %i=bytesperpixel\n", peasycap->bytesperpixel); 124327d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (peasycap->offerfields) 1244c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "===== offerfields\n"); 1245702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1246702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1247702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 1248702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * REJECT OR CLEAN BAD FIELDS 1249702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 1250702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1251c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->field_read == peasycap->field_fill) { 1252c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: on entry, still filling field buffer %i\n", 1253c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_read); 1254c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 1255c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 12563fc0dae888ee216036ae1898fc9186f1dd04f185Tomas Winkler#ifdef EASYCAP_TESTCARD 1257c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler easycap_testcard(peasycap, peasycap->field_read); 1258702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas#else 1259c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 <= input && INPUT_MANY > input) { 1260c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (easycap_bars && VIDEO_LOST_TOLERATE <= peasycap->lost[input]) 1261c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler easycap_testcard(peasycap, peasycap->field_read); 1262c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1263702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas#endif /*EASYCAP_TESTCARD*/ 1264702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1265702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1266c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler offerfields = peasycap->offerfields; 1267c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bytesperpixel = peasycap->bytesperpixel; 1268c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler decimatepixel = peasycap->decimatepixel; 1269702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1270c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if ((2 != bytesperpixel) && 1271c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (3 != bytesperpixel) && 1272c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (4 != bytesperpixel)) { 1273c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel); 1274c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 1275c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 127627d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (decimatepixel) 1277c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler multiplier = 2; 1278c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1279c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler multiplier = 1; 1280702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1281c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler w2 = 2 * multiplier * (peasycap->width); 1282c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler w3 = bytesperpixel * multiplier * (peasycap->width); 1283c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler wz = multiplier * (peasycap->height) * 1284c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler multiplier * (peasycap->width); 1285c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 1286c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler kex = peasycap->field_read; mex = 0; 1287c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler kad = peasycap->frame_fill; mad = 0; 1288c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 1289c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pex = peasycap->field_buffer[kex][0].pgo; rex = PAGE_SIZE; 1290c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pad = peasycap->frame_buffer[kad][0].pgo; rad = PAGE_SIZE; 1291c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler odd = !!(peasycap->field_buffer[kex][0].kount); 1292c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 1293febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (odd && (!decimatepixel)) { 1294c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "initial skipping %4i bytes p.%4i\n", 1295c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler w3/multiplier, mad); 1296c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pad += (w3 / multiplier); rad -= (w3 / multiplier); 1297c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1298c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = true; 1299c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mask = 0; rump = 0; caches = 0; 1300c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 1301c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler cz = 0; 1302c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (cz < wz) { 1303c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* 1304c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * PROCESS ONE LINE OF FRAME AT FULL RESOLUTION: 1305c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * READ w2 BYTES FROM FIELD BUFFER, 1306c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * WRITE w3 BYTES TO FRAME BUFFER 1307c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler */ 1308febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (!decimatepixel) { 1309c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler over = w2; 1310c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler do { 1311c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler much = over; more = 0; 1312c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler margin = 0; mask = 0x00; 1313c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rex < much) 1314c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler much = rex; 1315c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rump = 0; 1316c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 1317c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (much % 2) { 1318c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: much is odd\n"); 1319c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 1320c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1321702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1322c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler more = (bytesperpixel * 1323c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler much) / 2; 1324702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1325c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (1 < bytesperpixel) { 1326c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rad * 2 < much * bytesperpixel) { 1327c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* 1328c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * INJUDICIOUS ALTERATION OF 1329c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * THIS STATEMENT BLOCK WILL 1330c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * CAUSE BREAKAGE. BEWARE. 1331c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler */ 1332c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rad2 = rad + bytesperpixel - 1; 1333a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler much = ((((2 * rad2)/bytesperpixel)/2) * 2); 1334a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler rump = ((bytesperpixel * much) / 2) - rad; 1335c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler more = rad; 1336a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler } 1337c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mask = (u8)rump; 1338c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler margin = 0; 1339c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (much == rex) { 1340c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mask |= 0x04; 1341a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler if ((mex + 1) < FIELD_BUFFER_SIZE / PAGE_SIZE) 1342a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler margin = *((u8 *)(peasycap->field_buffer[kex][mex + 1].pgo)); 1343a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler else 1344c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mask |= 0x08; 1345702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1346c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 1347c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=bytesperpixel\n", 1348c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bytesperpixel); 1349c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 1350702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1351c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rump) 1352c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler caches++; 135327d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (badinput) { 1354c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "ERROR: 0x%02X=->field_buffer" 1355c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "[%i][%i].input, " 1356c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "0x%02X=(0x08|->input)\n", 1357c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_buffer 1358c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [kex][mex].input, kex, mex, 1359c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (0x08|peasycap->input)); 1360c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1361c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = redaub(peasycap, pad, pex, much, more, 1362c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mask, margin, isuy); 1363c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 > rc) { 1364c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: redaub() failed\n"); 1365c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 1366f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 1367a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler if (much % 4) 1368a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler isuy = !isuy; 1369a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler 1370c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler over -= much; cz += much; 1371c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pex += much; rex -= much; 1372c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!rex) { 1373c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mex++; 1374c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pex = peasycap->field_buffer[kex][mex].pgo; 1375c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rex = PAGE_SIZE; 1376a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler if (peasycap->field_buffer[kex][mex].input != (0x08|peasycap->input)) 1377c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler badinput = true; 1378c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1379c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pad += more; 1380c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rad -= more; 1381c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!rad) { 1382c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mad++; 1383c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pad = peasycap->frame_buffer[kad][mad].pgo; 1384c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rad = PAGE_SIZE; 1385c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rump) { 1386c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pad += rump; 1387c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rad -= rump; 1388c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1389c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1390c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } while (over); 1391702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1392702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 1393702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * SKIP w3 BYTES IN TARGET FRAME BUFFER, 1394702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * UNLESS IT IS THE LAST LINE OF AN ODD FRAME 1395702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 1396702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1397febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (!odd || (cz != wz)) { 1398c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler over = w3; 1399c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler do { 1400c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!rad) { 1401c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mad++; 1402c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pad = peasycap->frame_buffer 1403c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [kad][mad].pgo; 1404c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rad = PAGE_SIZE; 1405c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1406c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler more = over; 1407c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rad < more) 1408c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler more = rad; 1409c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler over -= more; 1410c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pad += more; 1411c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rad -= more; 1412c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } while (over); 1413c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1414702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1415702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 1416702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * PROCESS ONE LINE OF FRAME AT REDUCED RESOLUTION: 1417702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * ONLY IF false==odd, 1418702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * READ w2 BYTES FROM FIELD BUFFER, 1419702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * WRITE w3 / 2 BYTES TO FRAME BUFFER 1420702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 1421702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1422febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler } else if (!odd) { 1423c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler over = w2; 1424c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler do { 1425c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler much = over; more = 0; margin = 0; mask = 0x00; 1426c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rex < much) 1427c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler much = rex; 1428c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rump = 0; 1429702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1430c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (much % 2) { 1431c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: much is odd\n"); 1432c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 1433c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1434702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1435c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler more = (bytesperpixel * much) / 4; 1436702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1437c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (1 < bytesperpixel) { 1438c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rad * 4 < much * bytesperpixel) { 1439c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* 1440c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * INJUDICIOUS ALTERATION OF 1441c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * THIS STATEMENT BLOCK 1442c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * WILL CAUSE BREAKAGE. 1443c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * BEWARE. 1444c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler */ 1445c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rad2 = rad + bytesperpixel - 1; 1446a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler much = ((((2 * rad2) / bytesperpixel) / 2) * 4); 1447a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler rump = ((bytesperpixel * much) / 4) - rad; 1448c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler more = rad; 1449702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1450c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mask = (u8)rump; 1451c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler margin = 0; 1452c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (much == rex) { 1453c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mask |= 0x04; 1454a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler if ((mex + 1) < FIELD_BUFFER_SIZE / PAGE_SIZE) 1455a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler margin = *((u8 *)(peasycap->field_buffer[kex][mex + 1].pgo)); 1456a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler else 1457c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mask |= 0x08; 1458702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1459702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1460702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } else { 14611dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler SAM("MISTAKE: %i=bytesperpixel\n", 1462702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas bytesperpixel); 1463702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas return -EFAULT; 1464702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1465702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1466c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rump) 1467c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler caches++; 1468c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 146927d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (badinput) { 1470c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "ERROR: 0x%02X=->field_buffer" 1471c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "[%i][%i].input, " 1472c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "0x%02X=(0x08|->input)\n", 1473c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_buffer 1474c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [kex][mex].input, kex, mex, 1475c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (0x08|peasycap->input)); 1476c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1477c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = redaub(peasycap, pad, pex, much, more, 1478702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas mask, margin, isuy); 1479c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 > rc) { 1480c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: redaub() failed\n"); 1481c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 1482702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1483c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler over -= much; cz += much; 1484c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pex += much; rex -= much; 1485c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!rex) { 1486c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mex++; 1487c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pex = peasycap->field_buffer[kex][mex].pgo; 1488c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rex = PAGE_SIZE; 1489c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->field_buffer[kex][mex].input != 1490c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (0x08|peasycap->input)) 1491c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler badinput = true; 1492c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1493c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pad += more; 1494c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rad -= more; 1495c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!rad) { 1496c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mad++; 1497c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pad = peasycap->frame_buffer[kad][mad].pgo; 1498c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rad = PAGE_SIZE; 1499c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rump) { 1500c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pad += rump; 1501c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rad -= rump; 1502c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1503c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1504c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } while (over); 1505702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1506702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 1507702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * OTHERWISE JUST 1508702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * READ w2 BYTES FROM FIELD BUFFER AND DISCARD THEM 1509702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 1510702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1511c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 1512c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler over = w2; 1513c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler do { 1514c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!rex) { 1515c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mex++; 1516c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pex = peasycap->field_buffer[kex][mex].pgo; 1517c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rex = PAGE_SIZE; 1518c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->field_buffer[kex][mex].input != 1519c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (0x08|peasycap->input)) { 1520c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "ERROR: 0x%02X=->field_buffer" 1521c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "[%i][%i].input, " 1522c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "0x%02X=(0x08|->input)\n", 1523c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_buffer 1524c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [kex][mex].input, kex, mex, 1525c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (0x08|peasycap->input)); 1526c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler badinput = true; 1527c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1528f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 1529c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler much = over; 1530c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rex < much) 1531c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler much = rex; 1532c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler over -= much; 1533c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler cz += much; 1534c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pex += much; 1535c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rex -= much; 1536c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } while (over); 1537c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1538702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1539702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1540702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 1541702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * SANITY CHECKS 1542702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 1543702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1544c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler c2 = (mex + 1)*PAGE_SIZE - rex; 1545c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (cz != c2) 1546c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: discrepancy %i in bytes read\n", c2 - cz); 1547c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler c3 = (mad + 1)*PAGE_SIZE - rad; 1548c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 1549febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (!decimatepixel) { 1550c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (bytesperpixel * cz != c3) 15511dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler SAM("ERROR: discrepancy %i in bytes written\n", 1552c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler c3 - (bytesperpixel * cz)); 1553c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 1554febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (!odd) { 1555c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (bytesperpixel * 1556c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler cz != (4 * c3)) 1557c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: discrepancy %i in bytes written\n", 1558c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (2*c3)-(bytesperpixel * cz)); 1559c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 1560c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 != c3) 1561c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: discrepancy %i " 1562c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "in bytes written\n", c3); 1563c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1564c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1565c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rump) 1566c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("WORRY: undischarged cache at end of line in frame buffer\n"); 1567702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1568c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "===== field2frame(): %i bytes --> %i bytes (incl skip)\n", c2, c3); 1569c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "===== field2frame(): %i=mad %i=rad\n", mad, rad); 1570702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 157127d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (odd) 1572c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "+++++ field2frame(): frame buffer %i is full\n", kad); 1573702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1574c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->field_read == peasycap->field_fill) 1575c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("WARNING: on exit, filling field buffer %i\n", 1576c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_read); 1577702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1578702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 1579702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * CALCULATE VIDEO STREAMING RATE 1580702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 1581702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1582c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler do_gettimeofday(&timeval); 1583c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->timeval6.tv_sec) { 1584c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler below = ((long long int)(1000000)) * 1585c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ((long long int)(timeval.tv_sec - 1586c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->timeval6.tv_sec)) + 1587c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (long long int)(timeval.tv_usec - peasycap->timeval6.tv_usec); 1588c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler above = (long long int)1000000; 1589702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1590c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler sdr = signed_div(above, below); 1591c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler above = sdr.quotient; 1592c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler remainder = (u32)sdr.remainder; 1593702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1594c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "video streaming at %3lli.%03i fields per second\n", 1595c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler above, (remainder/1000)); 1596c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1597c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->timeval6 = timeval; 1598702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1599c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (caches) 1600c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=caches\n", caches); 1601c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 1602702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 1603702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 1604702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomasstruct signed_div_result 1605702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomassigned_div(long long int above, long long int below) 1606702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 1607c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct signed_div_result sdr; 1608c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 1609c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (((0 <= above) && (0 <= below)) || ((0 > above) && (0 > below))) { 1610c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler sdr.remainder = (unsigned long long int) do_div(above, below); 1611c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler sdr.quotient = (long long int) above; 1612c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 1613c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 > above) 1614c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler above = -above; 1615c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 > below) 1616c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler below = -below; 1617c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler sdr.remainder = (unsigned long long int) do_div(above, below); 1618c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler sdr.quotient = -((long long int) above); 1619c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1620c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return sdr; 1621702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 1622702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 1623702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1624702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 1625702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * DECIMATION AND COLOURSPACE CONVERSION. 1626702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 1627702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * THIS ROUTINE REQUIRES THAT ALL THE DATA TO BE READ RESIDES ON ONE PAGE 1628702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * AND THAT ALL THE DATA TO BE WRITTEN RESIDES ON ONE (DIFFERENT) PAGE. 1629702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * THE CALLING ROUTINE MUST ENSURE THAT THIS REQUIREMENT IS MET, AND MUST 1630702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * ALSO ENSURE THAT much IS EVEN. 1631702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 1632702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * much BYTES ARE READ, AT LEAST (bytesperpixel * much)/2 BYTES ARE WRITTEN 1633702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * IF THERE IS NO DECIMATION, HALF THIS AMOUNT IF THERE IS DECIMATION. 1634702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 1635702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * mask IS ZERO WHEN NO SPECIAL BEHAVIOUR REQUIRED. OTHERWISE IT IS SET THUS: 1636702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 0x03 & mask = number of bytes to be written to cache instead of to 1637702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * frame buffer 1638702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 0x04 & mask => use argument margin to set the chrominance for last pixel 1639702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 0x08 & mask => do not set the chrominance for last pixel 1640702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 1641702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * YUV to RGB CONVERSION IS (OR SHOULD BE) ITU-R BT 601. 1642702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 1643702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * THERE IS A LOT OF CODE REPETITION IN THIS ROUTINE IN ORDER TO AVOID 1644702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * INEFFICIENT SWITCHING INSIDE INNER LOOPS. REARRANGING THE LOGIC TO 1645702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * REDUCE CODE LENGTH WILL GENERALLY IMPAIR RUNTIME PERFORMANCE. BEWARE. 1646702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 1647702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1648702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomasint 16491dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winklerredaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, 1650055e3a3a2cdcb7d39d14857e2fb2175c11168ee7Tomas Winkler u8 mask, u8 margin, bool isuy) 1651702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 1652c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler static s32 ay[256], bu[256], rv[256], gu[256], gv[256]; 1653c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u8 *pcache; 1654c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u8 r, g, b, y, u, v, c, *p2, *p3, *pz, *pr; 1655c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int bytesperpixel; 1656c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bool byteswaporder, decimatepixel, last; 1657c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int j, rump; 1658c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler s32 tmp; 1659c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 1660c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (much % 2) { 1661c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: much is odd\n"); 1662c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 1663c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1664c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bytesperpixel = peasycap->bytesperpixel; 1665c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler byteswaporder = peasycap->byteswaporder; 1666c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler decimatepixel = peasycap->decimatepixel; 1667c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 1668c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler/*---------------------------------------------------------------------------*/ 1669c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!bu[255]) { 1670c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (j = 0; j < 112; j++) { 1671c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = (0xFF00 & (453 * j)) >> 8; 1672c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bu[j + 128] = tmp; bu[127 - j] = -tmp; 1673c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = (0xFF00 & (359 * j)) >> 8; 1674c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rv[j + 128] = tmp; rv[127 - j] = -tmp; 1675c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = (0xFF00 & (88 * j)) >> 8; 1676c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler gu[j + 128] = tmp; gu[127 - j] = -tmp; 1677c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = (0xFF00 & (183 * j)) >> 8; 1678c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler gv[j + 128] = tmp; gv[127 - j] = -tmp; 1679c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1680c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (j = 0; j < 16; j++) { 1681c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bu[j] = bu[16]; rv[j] = rv[16]; 1682c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler gu[j] = gu[16]; gv[j] = gv[16]; 1683c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1684c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (j = 240; j < 256; j++) { 1685c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bu[j] = bu[239]; rv[j] = rv[239]; 1686c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler gu[j] = gu[239]; gv[j] = gv[239]; 1687c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1688c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (j = 16; j < 236; j++) 1689c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ay[j] = j; 1690c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (j = 0; j < 16; j++) 1691c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ay[j] = ay[16]; 1692c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (j = 236; j < 256; j++) 1693c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ay[j] = ay[235]; 1694c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "lookup tables are prepared\n"); 1695c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1696c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pcache = peasycap->pcache; 16976888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pcache) 1698c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pcache = &peasycap->cache[0]; 1699702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1700702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 1701702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * TRANSFER CONTENTS OF CACHE TO THE FRAME BUFFER 1702702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 1703702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1704c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!pcache) { 1705c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: pcache is NULL\n"); 1706c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 1707c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1708702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1709c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (pcache != &peasycap->cache[0]) 1710c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(16, "cache has %i bytes\n", (int)(pcache - &peasycap->cache[0])); 1711c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p2 = &peasycap->cache[0]; 1712c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p3 = (u8 *)pad - (int)(pcache - &peasycap->cache[0]); 1713c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (p2 < pcache) { 1714c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3++ = *p2; p2++; 1715c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1716c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pcache = &peasycap->cache[0]; 1717c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (p3 != pad) { 1718c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: pointer misalignment\n"); 1719c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 1720c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1721702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1722c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rump = (int)(0x03 & mask); 1723c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = 0; v = 0; 1724c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p2 = (u8 *)pex; pz = p2 + much; pr = p3 + more; last = false; 1725c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p2++; 1726702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 172727d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 1728c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = *(p2 - 1); 1729c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1730c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = *(p2 - 1); 1731702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1732c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rump) 1733c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(16, "%4i=much %4i=more %i=rump\n", much, more, rump); 1734702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1735702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1736c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler switch (bytesperpixel) { 1737c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 2: { 1738febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (!decimatepixel) { 1739c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler memcpy(pad, pex, (size_t)much); 1740febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (!byteswaporder) { 1741c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* UYVY */ 1742c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 1743c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 1744c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* YUYV */ 1745c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p3 = (u8 *)pad; pz = p3 + much; 1746c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (pz > p3) { 1747c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler c = *p3; 1748c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = *(p3 + 1); 1749c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 1) = c; 1750c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p3 += 2; 1751702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1752c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 1753702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1754702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } else { 1755febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (!byteswaporder) { 1756c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* UYVY DECIMATED */ 1757c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p2 = (u8 *)pex; p3 = (u8 *)pad; pz = p2 + much; 1758c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (pz > p2) { 1759c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = *p2; 1760c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 1) = *(p2 + 1); 1761c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 2) = *(p2 + 2); 1762c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 3) = *(p2 + 3); 1763c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p3 += 4; p2 += 8; 1764702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1765c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 1766c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 1767c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* YUYV DECIMATED */ 1768c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p2 = (u8 *)pex; p3 = (u8 *)pad; pz = p2 + much; 1769c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (pz > p2) { 1770c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = *(p2 + 1); 1771c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 1) = *p2; 1772c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 2) = *(p2 + 3); 1773c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 3) = *(p2 + 2); 1774c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p3 += 4; p2 += 8; 1775702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1776c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 1777702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1778c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1779c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 1780c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1781c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 3: 1782c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler { 1783febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (!decimatepixel) { 1784febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (!byteswaporder) { 1785c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* RGB */ 1786c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (pz > p2) { 1787c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (pr <= (p3 + bytesperpixel)) 1788c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = true; 1789c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1790c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = false; 1791c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler y = *p2; 179227d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && (0x0C & mask)) { 1793c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x04 & mask) { 179427d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 1795c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = margin; 1796c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1797c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = margin; 1798c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else 1799c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x08 & mask) 1800c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ; 1801c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 180227d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 1803c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = *(p2 + 1); 1804702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas else 1805c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = *(p2 + 1); 1806c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1807702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 180827d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler tmp = ay[(int)y] + rv[(int)v]; 180927d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler r = (255 < tmp) ? 255 : ((0 > tmp) ? 1810055e3a3a2cdcb7d39d14857e2fb2175c11168ee7Tomas Winkler 0 : (u8)tmp); 1811c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; 181227d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler g = (255 < tmp) ? 255 : ((0 > tmp) ? 1813055e3a3a2cdcb7d39d14857e2fb2175c11168ee7Tomas Winkler 0 : (u8)tmp); 181427d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler tmp = ay[(int)y] + bu[(int)u]; 181527d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler b = (255 < tmp) ? 255 : ((0 > tmp) ? 1816055e3a3a2cdcb7d39d14857e2fb2175c11168ee7Tomas Winkler 0 : (u8)tmp); 1817702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 181827d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && rump) { 1819e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas pcache = &peasycap->cache[0]; 1820702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas switch (bytesperpixel - rump) { 1821702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas case 1: { 1822702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = r; 1823702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = g; 1824702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = b; 1825702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas break; 1826702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1827702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas case 2: { 1828702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = r; 1829702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 1) = g; 1830702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = b; 1831702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas break; 1832702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1833702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas default: { 1834c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=rump\n", 1835c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bytesperpixel - rump); 1836702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas return -EFAULT; 1837702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1838702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1839702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } else { 1840702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = r; 1841702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 1) = g; 1842702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 2) = b; 1843702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1844c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p2 += 2; 184527d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 1846c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = false; 1847c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1848c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = true; 1849702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas p3 += bytesperpixel; 1850702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1851c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 1852c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 1853c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* BGR */ 1854c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (pz > p2) { 1855c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (pr <= (p3 + bytesperpixel)) 1856c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = true; 1857c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1858c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = false; 1859c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler y = *p2; 186027d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && (0x0C & mask)) { 1861c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x04 & mask) { 186227d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 1863c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = margin; 1864c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1865c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = margin; 1866c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1867c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1868702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas if (0x08 & mask) 1869702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas ; 1870c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 187127d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 1872c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = *(p2 + 1); 1873c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1874c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = *(p2 + 1); 1875c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1876702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 187727d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler tmp = ay[(int)y] + rv[(int)v]; 187827d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler r = (255 < tmp) ? 255 : ((0 > tmp) ? 1879c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 1880c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; 188127d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler g = (255 < tmp) ? 255 : ((0 > tmp) ? 1882c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 188327d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler tmp = ay[(int)y] + bu[(int)u]; 188427d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler b = (255 < tmp) ? 255 : ((0 > tmp) ? 1885c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 1886702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 188727d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && rump) { 1888e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas pcache = &peasycap->cache[0]; 1889702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas switch (bytesperpixel - rump) { 1890702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas case 1: { 1891702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = b; 1892702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = g; 1893702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = r; 1894702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas break; 1895702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1896702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas case 2: { 1897702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = b; 1898702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 1) = g; 1899702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = r; 1900702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas break; 1901702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1902702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas default: { 1903c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=rump\n", 1904c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bytesperpixel - rump); 1905702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas return -EFAULT; 1906702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1907702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1908702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } else { 1909702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = b; 1910702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 1) = g; 1911702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 2) = r; 1912702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1913c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p2 += 2; 191427d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 1915c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = false; 1916c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1917c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = true; 1918702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas p3 += bytesperpixel; 1919702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1920702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1921702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas return 0; 1922c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 1923febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (!byteswaporder) { 1924c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* RGB DECIMATED */ 1925c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (pz > p2) { 1926c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (pr <= (p3 + bytesperpixel)) 1927c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = true; 1928c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1929c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = false; 1930c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler y = *p2; 193127d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && (0x0C & mask)) { 1932c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x04 & mask) { 193327d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 1934c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = margin; 1935c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1936c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = margin; 1937c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else 1938c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x08 & mask) 1939c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ; 1940c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 194127d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 1942c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = *(p2 + 1); 1943702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas else 1944c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = *(p2 + 1); 1945702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1946c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 194727d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) { 1948c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] + rv[(int)v]; 1949c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler r = (255 < tmp) ? 255 : ((0 > tmp) ? 1950c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 1951c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] - gu[(int)u] - 1952c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler gv[(int)v]; 1953c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler g = (255 < tmp) ? 255 : ((0 > tmp) ? 1954c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 1955c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] + bu[(int)u]; 1956c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler b = (255 < tmp) ? 255 : ((0 > tmp) ? 1957c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 1958c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 195927d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && rump) { 1960c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pcache = &peasycap->cache[0]; 1961c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler switch (bytesperpixel - rump) { 1962c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 1: { 1963c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = r; 1964c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = g; 1965c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = b; 1966c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 1967c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1968c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 2: { 1969c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = r; 1970c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 1) = g; 1971c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = b; 1972c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 1973c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1974c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler default: { 1975c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: " 1976c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "%i=rump\n", 1977c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bytesperpixel - rump); 1978c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 1979c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1980c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1981c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 1982c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = r; 1983c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 1) = g; 1984c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 2) = b; 1985c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1986c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = false; 1987c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p3 += bytesperpixel; 1988c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 1989c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = true; 1990702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1991c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p2 += 2; 1992702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1993c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 1994c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 1995c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* BGR DECIMATED */ 1996c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (pz > p2) { 1997c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (pr <= (p3 + bytesperpixel)) 1998c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = true; 1999c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2000c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = false; 2001c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler y = *p2; 200227d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && (0x0C & mask)) { 2003c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x04 & mask) { 200427d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 2005c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = margin; 2006c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2007c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = margin; 2008c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else 2009c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x08 & mask) 2010c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ; 2011c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 201227d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 2013c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = *(p2 + 1); 2014702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas else 2015c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = *(p2 + 1); 2016702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2017c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 201827d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) { 2019c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 2020c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] + rv[(int)v]; 2021c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler r = (255 < tmp) ? 255 : ((0 > tmp) ? 2022c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 2023c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] - gu[(int)u] - 2024c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler gv[(int)v]; 2025c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler g = (255 < tmp) ? 255 : ((0 > tmp) ? 2026c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 2027c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] + bu[(int)u]; 2028c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler b = (255 < tmp) ? 255 : ((0 > tmp) ? 2029c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 2030c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 203127d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && rump) { 2032c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pcache = &peasycap->cache[0]; 2033c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler switch (bytesperpixel - rump) { 2034c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 1: { 2035c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = b; 2036c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = g; 2037c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = r; 2038c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 2039c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2040c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 2: { 2041c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = b; 2042c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 1) = g; 2043c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = r; 2044c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 2045c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2046c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler default: { 2047c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: " 2048c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "%i=rump\n", 2049c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bytesperpixel - rump); 2050c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 2051c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2052c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2053c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 2054c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = b; 2055c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 1) = g; 2056c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 2) = r; 2057c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2058c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = false; 2059c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p3 += bytesperpixel; 2060c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2061c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2062c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = true; 2063c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p2 += 2; 2064702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2065c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 2066702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2067702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2068c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 2069702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2070c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 4: 2071c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler { 2072febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (!decimatepixel) { 2073febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (!byteswaporder) { 2074c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* RGBA */ 2075c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (pz > p2) { 2076c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (pr <= (p3 + bytesperpixel)) 2077c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = true; 2078c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2079c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = false; 2080c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler y = *p2; 208127d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && (0x0C & mask)) { 2082c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x04 & mask) { 208327d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 2084c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = margin; 2085c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2086c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = margin; 2087c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else 2088c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x08 & mask) 2089c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ; 2090c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 209127d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 2092c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = *(p2 + 1); 2093702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas else 2094c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = *(p2 + 1); 2095c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2096702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 209727d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler tmp = ay[(int)y] + rv[(int)v]; 209827d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler r = (255 < tmp) ? 255 : ((0 > tmp) ? 2099c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 2100c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; 210127d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler g = (255 < tmp) ? 255 : ((0 > tmp) ? 2102c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 210327d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler tmp = ay[(int)y] + bu[(int)u]; 210427d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler b = (255 < tmp) ? 255 : ((0 > tmp) ? 2105c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 2106702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 210727d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && rump) { 2108e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas pcache = &peasycap->cache[0]; 2109702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas switch (bytesperpixel - rump) { 2110702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas case 1: { 2111702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = r; 2112702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = g; 2113702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = b; 2114702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = 0; 2115702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas break; 2116702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2117702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas case 2: { 2118702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = r; 2119702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 1) = g; 2120702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = b; 2121702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = 0; 2122702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas break; 2123702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2124702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas case 3: { 2125702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = r; 2126702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 1) = g; 2127702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 2) = b; 2128702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = 0; 2129702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas break; 2130702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2131702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas default: { 2132c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=rump\n", 2133c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bytesperpixel - rump); 2134702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas return -EFAULT; 2135c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2136702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2137702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } else { 2138702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = r; 2139702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 1) = g; 2140702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 2) = b; 2141702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 3) = 0; 2142c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2143c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p2 += 2; 214427d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 2145c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = false; 2146702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas else 2147c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = true; 2148c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p3 += bytesperpixel; 2149702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2150c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 2151c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 2152c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* 2153c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * BGRA 2154c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler */ 2155c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (pz > p2) { 2156c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (pr <= (p3 + bytesperpixel)) 2157c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = true; 2158c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2159c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = false; 2160c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler y = *p2; 216127d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && (0x0C & mask)) { 2162c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x04 & mask) { 216327d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 2164c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = margin; 2165c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2166c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = margin; 2167c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else 2168c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x08 & mask) 2169c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ; 2170c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 217127d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 2172c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = *(p2 + 1); 2173c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2174c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = *(p2 + 1); 2175c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2176702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 217727d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler tmp = ay[(int)y] + rv[(int)v]; 217827d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler r = (255 < tmp) ? 255 : ((0 > tmp) ? 2179c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 2180c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; 218127d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler g = (255 < tmp) ? 255 : ((0 > tmp) ? 2182c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 218327d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler tmp = ay[(int)y] + bu[(int)u]; 218427d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler b = (255 < tmp) ? 255 : ((0 > tmp) ? 2185c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 2186702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 218727d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && rump) { 2188e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas pcache = &peasycap->cache[0]; 2189702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas switch (bytesperpixel - rump) { 2190702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas case 1: { 2191702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = b; 2192702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = g; 2193702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = r; 2194702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = 0; 2195702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas break; 2196702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2197702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas case 2: { 2198702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = b; 2199702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 1) = g; 2200702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = r; 2201702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = 0; 2202702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas break; 2203702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2204702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas case 3: { 2205702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = b; 2206702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 1) = g; 2207702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 2) = r; 2208702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = 0; 2209702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas break; 2210702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2211c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler default: 2212c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=rump\n", 2213c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bytesperpixel - rump); 2214702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas return -EFAULT; 2215702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2216702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } else { 2217702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = b; 2218702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 1) = g; 2219702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 2) = r; 2220702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 3) = 0; 2221702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2222c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p2 += 2; 222327d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 2224c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = false; 2225c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2226c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = true; 2227702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas p3 += bytesperpixel; 2228c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2229c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2230c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 2231c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 2232febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (!byteswaporder) { 2233c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* 2234c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * RGBA DECIMATED 2235c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler */ 2236c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (pz > p2) { 2237c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (pr <= (p3 + bytesperpixel)) 2238c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = true; 2239c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2240c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = false; 2241c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler y = *p2; 224227d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && (0x0C & mask)) { 2243c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x04 & mask) { 224427d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 2245c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = margin; 2246c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2247c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = margin; 2248c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else 2249c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x08 & mask) 2250c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ; 2251c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 225227d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 2253c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = *(p2 + 1); 2254c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2255c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = *(p2 + 1); 2256c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2257c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 225827d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) { 2259c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 2260c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] + rv[(int)v]; 2261c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler r = (255 < tmp) ? 255 : ((0 > tmp) ? 2262c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 2263c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] - gu[(int)u] - 2264c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler gv[(int)v]; 2265c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler g = (255 < tmp) ? 255 : ((0 > tmp) ? 2266c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 2267c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] + bu[(int)u]; 2268c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler b = (255 < tmp) ? 255 : ((0 > tmp) ? 2269c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 2270c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 227127d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && rump) { 2272c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pcache = &peasycap->cache[0]; 2273c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler switch (bytesperpixel - rump) { 2274c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 1: { 2275c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = r; 2276c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = g; 2277c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = b; 2278c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = 0; 2279c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 2280c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2281c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 2: { 2282c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = r; 2283c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 1) = g; 2284c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = b; 2285c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = 0; 2286c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 2287c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2288c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 3: { 2289c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = r; 2290c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 1) = g; 2291c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 2) = b; 2292c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = 0; 2293c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 2294c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2295c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler default: { 2296c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: " 2297c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "%i=rump\n", 2298c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bytesperpixel - 2299c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rump); 2300c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 2301c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2302c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2303c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 2304c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = r; 2305c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 1) = g; 2306c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 2) = b; 2307c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 3) = 0; 2308c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2309c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = false; 2310c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p3 += bytesperpixel; 2311c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else 2312c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = true; 2313702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas p2 += 2; 2314702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2315c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 2316c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 2317c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* 2318c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * BGRA DECIMATED 2319c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler */ 2320c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (pz > p2) { 2321c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (pr <= (p3 + bytesperpixel)) 2322c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = true; 2323c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2324c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = false; 2325c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler y = *p2; 232627d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && (0x0C & mask)) { 2327c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x04 & mask) { 232827d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 2329c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = margin; 2330c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2331c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = margin; 2332c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else 2333c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x08 & mask) 2334c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ; 2335c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 233627d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 2337c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = *(p2 + 1); 2338c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2339c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = *(p2 + 1); 2340c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2341c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 234227d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) { 2343c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] + rv[(int)v]; 2344c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler r = (255 < tmp) ? 255 : ((0 > tmp) ? 2345c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 2346c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] - gu[(int)u] - 2347c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler gv[(int)v]; 2348c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler g = (255 < tmp) ? 255 : ((0 > tmp) ? 2349c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 2350c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] + bu[(int)u]; 2351c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler b = (255 < tmp) ? 255 : ((0 > tmp) ? 2352c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 2353c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 235427d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && rump) { 2355c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pcache = &peasycap->cache[0]; 2356c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler switch (bytesperpixel - rump) { 2357c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 1: { 2358c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = b; 2359c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = g; 2360c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = r; 2361c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = 0; 2362c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 2363c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2364c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 2: { 2365c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = b; 2366c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 1) = g; 2367c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = r; 2368c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = 0; 2369c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 2370c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2371c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 3: { 2372c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = b; 2373c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 1) = g; 2374c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 2) = r; 2375c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = 0; 2376c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 2377c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2378c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler default: { 2379c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: " 2380c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "%i=rump\n", 2381c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bytesperpixel - rump); 2382c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 2383c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2384c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2385c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 2386c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = b; 2387c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 1) = g; 2388c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 2) = r; 2389c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 3) = 0; 2390c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2391c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = false; 2392c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p3 += bytesperpixel; 2393c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else 2394c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = true; 2395c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p2 += 2; 2396c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2397c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 2398c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2399702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2400c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 2401c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2402c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler default: { 2403c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel); 2404c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 2405702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2406702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2407c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 2408702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 2409702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 2410702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 2411702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * SEE CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGES 430-434 2412702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 2413702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 2414d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic void easycap_vma_open(struct vm_area_struct *pvma) 2415702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 2416c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct easycap *peasycap; 2417702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 2418c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap = pvma->vm_private_data; 24196888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 2420c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap is NULL\n"); 2421c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 2422c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2423c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->vma_many++; 2424c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many); 2425268dfede46e24eef55a2ef7a10a462617936771eMike Thomas return; 2426268dfede46e24eef55a2ef7a10a462617936771eMike Thomas} 2427702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 2428d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic void easycap_vma_close(struct vm_area_struct *pvma) 2429702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 2430c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct easycap *peasycap; 2431702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 2432c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap = pvma->vm_private_data; 24336888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 2434c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap is NULL\n"); 2435c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 2436c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2437c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->vma_many--; 2438c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many); 2439268dfede46e24eef55a2ef7a10a462617936771eMike Thomas return; 2440702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 2441702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 2442d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic int easycap_vma_fault(struct vm_area_struct *pvma, struct vm_fault *pvmf) 2443702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 2444c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int k, m, retcode; 2445c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler void *pbuf; 2446c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct page *page; 2447c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct easycap *peasycap; 2448702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 2449c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler retcode = VM_FAULT_NOPAGE; 2450702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 24516888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pvma) { 2452c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("pvma is NULL\n"); 2453c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return retcode; 2454c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 24556888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pvmf) { 2456c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("pvmf is NULL\n"); 2457c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return retcode; 2458c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2459702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 2460c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler k = (pvmf->pgoff) / (FRAME_BUFFER_SIZE/PAGE_SIZE); 2461c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler m = (pvmf->pgoff) % (FRAME_BUFFER_SIZE/PAGE_SIZE); 2462702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 2463c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!m) 2464c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOT(4, "%4i=k, %4i=m\n", k, m); 2465c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2466c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOT(16, "%4i=k, %4i=m\n", k, m); 2467702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 2468c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if ((0 > k) || (FRAME_BUFFER_MANY <= k)) { 2469c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: buffer index %i out of range\n", k); 2470c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return retcode; 2471c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2472c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if ((0 > m) || (FRAME_BUFFER_SIZE/PAGE_SIZE <= m)) { 2473c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: page number %i out of range\n", m); 2474c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return retcode; 2475c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2476c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap = pvma->vm_private_data; 24776888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 2478c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap is NULL\n"); 2479c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return retcode; 2480c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2481702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 2482c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pbuf = peasycap->frame_buffer[k][m].pgo; 24836888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pbuf) { 2484c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: pbuf is NULL\n"); 2485c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return retcode; 2486c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2487c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler page = virt_to_page(pbuf); 24886888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!page) { 2489c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: page is NULL\n"); 2490c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return retcode; 2491c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2492c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler get_page(page); 2493702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 24946888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!page) { 2495c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: page is NULL after get_page(page)\n"); 2496c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 2497c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pvmf->page = page; 2498c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler retcode = VM_FAULT_MINOR; 2499c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2500c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return retcode; 2501702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 2502d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler 2503d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic const struct vm_operations_struct easycap_vm_ops = { 2504d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .open = easycap_vma_open, 2505d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .close = easycap_vma_close, 2506d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .fault = easycap_vma_fault, 2507d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler}; 2508d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler 2509d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic int easycap_mmap(struct file *file, struct vm_area_struct *pvma) 2510d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler{ 2511d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler JOT(8, "\n"); 2512d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler 2513d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler pvma->vm_ops = &easycap_vm_ops; 2514d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler pvma->vm_flags |= VM_RESERVED; 25156888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (file) 2516d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler pvma->vm_private_data = file->private_data; 2517d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler easycap_vma_open(pvma); 2518d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler return 0; 2519d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler} 2520702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 2521702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 2522702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 2523702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * ON COMPLETION OF A VIDEO URB ITS DATA IS COPIED TO THE FIELD BUFFERS 2524ce36cedab3f865969653bf4360f7e364ab0937e4Mike Thomas * PROVIDED peasycap->video_idle IS ZERO. REGARDLESS OF THIS BEING TRUE, 2525702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * IT IS RESUBMITTED PROVIDED peasycap->video_isoc_streaming IS NOT ZERO. 2526702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 2527702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * THIS FUNCTION IS AN INTERRUPT SERVICE ROUTINE AND MUST NOT SLEEP. 2528702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 2529702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * INFORMATION ABOUT THE VALIDITY OF THE CONTENTS OF THE FIELD BUFFER ARE 2530702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * STORED IN THE TWO-BYTE STATUS PARAMETER 2531702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * peasycap->field_buffer[peasycap->field_fill][0].kount 2532702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * NOTICE THAT THE INFORMATION IS STORED ONLY WITH PAGE 0 OF THE FIELD BUFFER. 2533702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 2534702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * THE LOWER BYTE CONTAINS THE FIELD PARITY BYTE FURNISHED BY THE SAA7113H 2535702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * CHIP. 2536702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 2537702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * THE UPPER BYTE IS ZERO IF NO PROBLEMS, OTHERWISE: 2538702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 0 != (kount & 0x8000) => AT LEAST ONE URB COMPLETED WITH ERRORS 2539702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 0 != (kount & 0x4000) => BUFFER HAS TOO MUCH DATA 2540702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 0 != (kount & 0x2000) => BUFFER HAS NOT ENOUGH DATA 2541f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * 0 != (kount & 0x1000) => BUFFER HAS DATA FROM DISPARATE INPUTS 2542ce36cedab3f865969653bf4360f7e364ab0937e4Mike Thomas * 0 != (kount & 0x0400) => RESERVED 2543702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 0 != (kount & 0x0200) => FIELD BUFFER NOT YET CHECKED 2544702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 0 != (kount & 0x0100) => BUFFER HAS TWO EXTRA BYTES - WHY? 2545702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 2546702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 2547d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic void easycap_complete(struct urb *purb) 2548702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 2549c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct easycap *peasycap; 2550c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct data_buffer *pfield_buffer; 2551c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler char errbuf[16]; 2552c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int i, more, much, leap, rc, last; 2553c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int videofieldamount; 2554c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler unsigned int override, bad; 2555c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int framestatus, framelength, frameactual, frameoffset; 2556c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u8 *pu; 2557c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 25586888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!purb) { 2559c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: easycap_complete(): purb is NULL\n"); 2560c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 2561c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2562c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap = purb->context; 25636888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 2564c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: easycap_complete(): peasycap is NULL\n"); 2565c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 2566c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2567c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->video_eof) 2568c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 2569c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++) 2570c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (purb->transfer_buffer == peasycap->video_isoc_buffer[i].pgo) 2571c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 2572c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(16, "%2i=urb\n", i); 2573c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = peasycap->video_isoc_sequence; 2574c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if ((((VIDEO_ISOC_BUFFER_MANY - 1) == last) && (0 != i)) || 2575c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (((VIDEO_ISOC_BUFFER_MANY - 1) != last) && ((last + 1) != i))) { 2576c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(16, "ERROR: out-of-order urbs %i,%i ... continuing\n", 2577c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last, i); 2578c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2579c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_isoc_sequence = i; 2580702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 2581c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->video_idle) { 2582c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(16, "%i=video_idle %i=video_isoc_streaming\n", 2583c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_idle, peasycap->video_isoc_streaming); 2584c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->video_isoc_streaming) { 2585c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = usb_submit_urb(purb, GFP_ATOMIC); 2586c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) { 2587c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("%s:%d ENOMEM\n", strerror(rc), rc); 2588c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (-ENODEV != rc) 2589c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: while %i=video_idle, " 2590c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "usb_submit_urb() " 2591c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "failed with rc:\n", 2592c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_idle); 2593c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2594702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2595c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 2596702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2597c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler override = 0; 2598702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 2599c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (FIELD_BUFFER_MANY <= peasycap->field_fill) { 2600c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: bad peasycap->field_fill\n"); 2601702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas return; 2602702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2603c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (purb->status) { 2604c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) { 2605c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "urb status -ESHUTDOWN or -ENOENT\n"); 2606c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 2607c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2608702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 2609c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap->field_buffer[peasycap->field_fill][0].kount) |= 0x8000 ; 2610c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: bad urb status -%s: %d\n", 2611c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler strerror(purb->status), purb->status); 2612702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 2613c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 2614c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (i = 0; i < purb->number_of_packets; i++) { 2615c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 != purb->iso_frame_desc[i].status) { 2616c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap->field_buffer 2617c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_fill][0].kount) |= 0x8000 ; 2618c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* FIXME: 1. missing '-' check boundaries */ 2619c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler strcpy(&errbuf[0], 2620c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler strerror(purb->iso_frame_desc[i].status)); 2621702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2622c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler framestatus = purb->iso_frame_desc[i].status; 2623c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler framelength = purb->iso_frame_desc[i].length; 2624c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler frameactual = purb->iso_frame_desc[i].actual_length; 2625c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler frameoffset = purb->iso_frame_desc[i].offset; 2626c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 2627c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(16, "frame[%2i]:" 2628c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "%4i=status " 2629c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "%4i=actual " 2630c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "%4i=length " 2631c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "%5i=offset\n", 2632c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler i, framestatus, frameactual, framelength, frameoffset); 2633c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!purb->iso_frame_desc[i].status) { 2634c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler more = purb->iso_frame_desc[i].actual_length; 2635c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer = &peasycap->field_buffer 2636c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_fill][peasycap->field_page]; 2637c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler videofieldamount = (peasycap->field_page * 2638c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler PAGE_SIZE) + 2639c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (int)(pfield_buffer->pto - pfield_buffer->pgo); 2640c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (4 == more) 2641c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_mt++; 2642c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (4 < more) { 2643c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->video_mt) { 2644c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%4i empty video urb frames\n", 2645c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_mt); 2646c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_mt = 0; 2647c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2648c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (FIELD_BUFFER_MANY <= peasycap->field_fill) { 2649c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: bad peasycap->field_fill\n"); 2650c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 2651c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2652c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (FIELD_BUFFER_SIZE/PAGE_SIZE <= 2653c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_page) { 2654c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: bad peasycap->field_page\n"); 2655c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 2656c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2657c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer = &peasycap->field_buffer 2658c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_fill][peasycap->field_page]; 2659c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pu = (u8 *)(purb->transfer_buffer + 2660c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler purb->iso_frame_desc[i].offset); 2661c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x80 & *pu) 2662c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler leap = 8; 2663c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2664c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler leap = 4; 2665702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*--------------------------------------------------------------------------*/ 2666702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 2667702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * EIGHT-BYTE END-OF-VIDEOFIELD MARKER. 2668702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * NOTE: A SUCCESSION OF URB FRAMES FOLLOWING THIS ARE EMPTY, 2669702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * CORRESPONDING TO THE FIELD FLYBACK (VERTICAL BLANKING) PERIOD. 2670702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 2671702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * PROVIDED THE FIELD BUFFER CONTAINS GOOD DATA AS INDICATED BY A ZERO UPPER 2672702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * BYTE OF 2673702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * peasycap->field_buffer[peasycap->field_fill][0].kount 2674702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * THE CONTENTS OF THE FIELD BUFFER ARE OFFERED TO dqbuf(), field_read IS 2675702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * UPDATED AND field_fill IS BUMPED. IF THE FIELD BUFFER CONTAINS BAD DATA 2676702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * NOTHING IS OFFERED TO dqbuf(). 2677702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 2678702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * THE DECISION ON WHETHER THE PARITY OF THE OFFERED FIELD BUFFER IS RIGHT 2679702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * RESTS WITH dqbuf(). 2680702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 2681702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 2682c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if ((8 == more) || override) { 2683c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (videofieldamount > 2684c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->videofieldamount) { 2685c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (2 == videofieldamount - 2686c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap-> 2687c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler videofieldamount) { 2688c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap->field_buffer 2689c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_fill] 2690c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [0].kount) |= 0x0100; 2691c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_junk += (1 + 2692c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler VIDEO_JUNK_TOLERATE); 2693c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else 2694c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap->field_buffer 2695c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_fill] 2696c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [0].kount) |= 0x4000; 2697c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else if (videofieldamount < 2698c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap-> 2699c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler videofieldamount) { 2700c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap->field_buffer 2701c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_fill] 2702c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [0].kount) |= 0x2000; 2703c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2704c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bad = 0xFF00 & peasycap->field_buffer 2705c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_fill] 2706c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [0].kount; 2707c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!bad) { 2708c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap->video_junk)--; 2709c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (-VIDEO_JUNK_TOLERATE > 2710c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_junk) 2711c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_junk = 2712c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler -VIDEO_JUNK_TOLERATE; 2713c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_read = 2714c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap-> 2715c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler field_fill)++; 2716c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (FIELD_BUFFER_MANY <= 2717c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap-> 2718c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler field_fill) 27191dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler peasycap-> 2720c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler field_fill = 0; 2721c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_page = 0; 2722c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer = &peasycap-> 2723c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler field_buffer 2724c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap-> 2725c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler field_fill] 2726c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap-> 2727c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler field_page]; 2728c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer->pto = 2729c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer->pgo; 2730c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "bumped to: %i=" 2731c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "peasycap->" 2732c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "field_fill %i=" 2733c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "parity\n", 2734c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_fill, 2735c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0x00FF & 2736c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer->kount); 2737c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "field buffer %i has " 2738c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "%i bytes fit to be " 2739c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "read\n", 2740c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_read, 2741c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler videofieldamount); 2742c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "wakeup call to " 2743c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "wq_video, " 2744c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "%i=field_read " 2745c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "%i=field_fill " 2746c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "%i=parity\n", 2747c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_read, 2748c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_fill, 2749c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0x00FF & peasycap-> 2750c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler field_buffer 2751c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap-> 2752c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler field_read][0].kount); 2753c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler wake_up_interruptible 2754c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (&(peasycap-> 2755c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler wq_video)); 2756c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler do_gettimeofday 2757c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (&peasycap->timeval7); 2758c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 2759c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_junk++; 2760c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (bad & 0x0010) 2761c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_junk += 2762c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (1 + VIDEO_JUNK_TOLERATE/2); 2763c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "field buffer %i had %i " 2764c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "bytes, now discarded: " 2765c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "0x%04X\n", 2766c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_fill, 2767c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler videofieldamount, 2768c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (0xFF00 & 2769c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_buffer 2770c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_fill][0]. 2771c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler kount)); 2772c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap->field_fill)++; 2773c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 2774c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (FIELD_BUFFER_MANY <= 2775c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_fill) 2776c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_fill = 0; 2777f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas peasycap->field_page = 0; 2778c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer = 2779c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler &peasycap->field_buffer 2780c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_fill] 2781c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_page]; 27821dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler pfield_buffer->pto = 2783c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer->pgo; 2784c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 2785c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "bumped to: %i=peasycap->" 2786c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "field_fill %i=parity\n", 27871dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler peasycap->field_fill, 2788c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0x00FF & pfield_buffer->kount); 2789c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2790c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (8 == more) { 2791c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "end-of-field: received " 2792c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "parity byte 0x%02X\n", 2793c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (0xFF & *pu)); 2794c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x40 & *pu) 2795c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer->kount = 0x0000; 2796c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2797c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer->kount = 0x0001; 2798c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer->input = 0x08 | 2799c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (0x07 & peasycap->input); 2800c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "end-of-field: 0x%02X=kount\n", 2801c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0xFF & pfield_buffer->kount); 2802c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2803702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2804702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 2805702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 2806702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * COPY more BYTES FROM ISOC BUFFER TO FIELD BUFFER 2807702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 2808702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 2809c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pu += leap; 2810c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler more -= leap; 2811702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 2812c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (FIELD_BUFFER_MANY <= peasycap->field_fill) { 2813c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: bad peasycap->field_fill\n"); 2814702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas return; 2815702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2816c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (FIELD_BUFFER_SIZE/PAGE_SIZE <= peasycap->field_page) { 2817c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: bad peasycap->field_page\n"); 2818c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 2819c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2820c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer = &peasycap->field_buffer 2821c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_fill][peasycap->field_page]; 2822c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (more) { 2823c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer = &peasycap->field_buffer 28241dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler [peasycap->field_fill] 2825702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas [peasycap->field_page]; 2826c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (PAGE_SIZE < (pfield_buffer->pto - 2827c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer->pgo)) { 2828c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: bad pfield_buffer->pto\n"); 2829c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 2830c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2831c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (PAGE_SIZE == (pfield_buffer->pto - 2832c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer->pgo)) { 2833c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap->field_page)++; 2834c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (FIELD_BUFFER_SIZE/PAGE_SIZE <= 2835c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_page) { 2836c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(16, "wrapping peasycap->" 2837c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "field_page\n"); 2838c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_page = 0; 2839c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2840c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer = &peasycap-> 2841c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler field_buffer 2842c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_fill] 2843c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_page]; 2844c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer->pto = pfield_buffer->pgo; 2845c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer->input = 0x08 | 2846c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (0x07 & peasycap->input); 2847c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if ((peasycap->field_buffer[peasycap-> 2848c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler field_fill][0]). 2849c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler input != 2850c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer->input) 2851c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap->field_buffer 2852c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_fill] 2853c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [0]).kount |= 0x1000; 2854c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2855702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 2856c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler much = PAGE_SIZE - 2857c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (int)(pfield_buffer->pto - 2858702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas pfield_buffer->pgo); 2859702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 2860c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (much > more) 2861c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler much = more; 2862c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler memcpy(pfield_buffer->pto, pu, much); 2863c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pu += much; 2864c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (pfield_buffer->pto) += much; 2865c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler more -= much; 2866c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2867702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2868702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2869702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2870702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2871702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 2872702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 2873702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * RESUBMIT THIS URB, UNLESS A SEVERE PERSISTENT ERROR CONDITION EXISTS. 2874702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 2875702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * IF THE WAIT QUEUES ARE NOT CLEARED IN RESPONSE TO AN ERROR CONDITION 2876702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT. BEWARE. 2877702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 2878702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 2879c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (VIDEO_ISOC_BUFFER_MANY <= peasycap->video_junk) { 2880c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("easycap driver shutting down on condition green\n"); 2881c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->status = 1; 2882c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_eof = 1; 2883c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_junk = 0; 2884c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler wake_up_interruptible(&peasycap->wq_video); 2885f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas#if !defined(PERSEVERE) 2886c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->audio_eof = 1; 2887c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler wake_up_interruptible(&peasycap->wq_audio); 2888f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas#endif /*PERSEVERE*/ 2889c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 2890702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2891c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->video_isoc_streaming) { 2892c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = usb_submit_urb(purb, GFP_ATOMIC); 2893c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) { 2894c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("%s: %d\n", strerror(rc), rc); 2895c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (-ENODEV != rc) 2896c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: while %i=video_idle, " 2897c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "usb_submit_urb() " 2898c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "failed with rc:\n", 2899c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_idle); 2900c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2901c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2902c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 2903702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 2904d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic const struct file_operations easycap_fops = { 2905d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .owner = THIS_MODULE, 2906d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .open = easycap_open, 2907f2b3c685b9b1c048cfa8bef98dac037275b9d20dTomas Winkler .unlocked_ioctl = easycap_unlocked_ioctl, 2908d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .poll = easycap_poll, 2909d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .mmap = easycap_mmap, 2910d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .llseek = no_llseek, 2911d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler}; 2912d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic const struct usb_class_driver easycap_class = { 2913d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .name = "usb/easycap%d", 2914d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .fops = &easycap_fops, 2915d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .minor_base = USB_SKEL_MINOR_BASE, 2916d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler}; 2917d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ 2918d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic const struct v4l2_file_operations v4l2_fops = { 2919d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .owner = THIS_MODULE, 2920d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .open = easycap_open_noinode, 2921f2b3c685b9b1c048cfa8bef98dac037275b9d20dTomas Winkler .unlocked_ioctl = easycap_unlocked_ioctl, 2922d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .poll = easycap_poll, 2923d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .mmap = easycap_mmap, 2924d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler}; 2925702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 2926702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 2927702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 2928a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas * WHEN THE EasyCAP IS PHYSICALLY PLUGGED IN, THIS FUNCTION IS CALLED THREE 2929a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas * TIMES, ONCE FOR EACH OF THE THREE INTERFACES. BEWARE. 2930702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 2931702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 293211ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winklerstatic int easycap_usb_probe(struct usb_interface *intf, 293311ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler const struct usb_device_id *id) 2934702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 293511ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler struct usb_device *usbdev; 293611ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler struct usb_host_interface *alt; 293711ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler struct usb_endpoint_descriptor *ep; 293811ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler struct usb_interface_descriptor *interface; 29397dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler struct urb *purb; 29407dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler struct easycap *peasycap; 29417dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler int ndong; 29427dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler struct data_urb *pdata_urb; 29431d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler int i, j, k, m, rc; 29447dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler u8 bInterfaceNumber; 29457dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler u8 bInterfaceClass; 29467dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler u8 bInterfaceSubClass; 29477dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler void *pbuf; 29487dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler int okalt[8], isokalt; 29497dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler int okepn[8]; 29507dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler int okmps[8]; 29517dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler int maxpacketsize; 29527dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler u16 mask; 29537dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler s32 value; 29547dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler struct easycap_format *peasycap_format; 2955b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler int fmtidx; 2956b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler struct inputset *inputset; 2957702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 295811ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler usbdev = interface_to_usbdev(intf); 2959ee99aa4928129d4aad9087988db6b7815ecdc1d5Tomas Winkler 2960702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 296111ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler alt = usb_altnum_to_altsetting(intf, 0); 296211ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler if (!alt) { 296311ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler SAY("ERROR: usb_host_interface not found\n"); 29647dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 29657dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 296611ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler interface = &alt->desc; 296711ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler if (!interface) { 296811ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler SAY("ERROR: intf_descriptor is NULL\n"); 29697dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 29707dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 2971702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 2972702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 2973702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * GET PROPERTIES OF PROBED INTERFACE 2974702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 2975702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 297611ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler bInterfaceNumber = interface->bInterfaceNumber; 297711ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler bInterfaceClass = interface->bInterfaceClass; 297811ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler bInterfaceSubClass = interface->bInterfaceSubClass; 29797dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler 2980e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler JOT(4, "intf[%i]: num_altsetting=%i\n", 298111ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler bInterfaceNumber, intf->num_altsetting); 2982e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler JOT(4, "intf[%i]: cur_altsetting - altsetting=%li\n", 2983e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler bInterfaceNumber, 298411ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler (long int)(intf->cur_altsetting - intf->altsetting)); 2985e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler JOT(4, "intf[%i]: bInterfaceClass=0x%02X bInterfaceSubClass=0x%02X\n", 2986e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler bInterfaceNumber, bInterfaceClass, bInterfaceSubClass); 2987702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 2988702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 2989702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * A NEW struct easycap IS ALWAYS ALLOCATED WHEN INTERFACE 0 IS PROBED. 2990702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * IT IS NOT POSSIBLE HERE TO FREE ANY EXISTING struct easycap. THIS 2991e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas * SHOULD HAVE BEEN DONE BY easycap_delete() WHEN THE EasyCAP WAS 2992e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas * PHYSICALLY UNPLUGGED. 2993e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas * 2994e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas * THE POINTER peasycap TO THE struct easycap IS REMEMBERED WHEN 2995e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas * INTERFACES 1 AND 2 ARE PROBED. 2996e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas*/ 2997702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 29987dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (0 == bInterfaceNumber) { 29997dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap = kzalloc(sizeof(struct easycap), GFP_KERNEL); 30006888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 30017dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAY("ERROR: Could not allocate peasycap\n"); 30027dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOMEM; 30037dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3004702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 3005702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 3006e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas * PERFORM URGENT INTIALIZATIONS ... 3007e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas*/ 3008702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 30097dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->minor = -1; 30107dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler kref_init(&peasycap->kref); 30117dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(8, "intf[%i]: after kref_init(..._video) " 30127dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "%i=peasycap->kref.refcount.counter\n", 30137dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler bInterfaceNumber, peasycap->kref.refcount.counter); 3014702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 30157dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler /* module params */ 30167dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->gain = (s8)clamp(easycap_gain, 0, 31); 30172a9a05c43294d703e351753da49231c47e0aad0dTomas Winkler 30187dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler init_waitqueue_head(&peasycap->wq_video); 30197dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler init_waitqueue_head(&peasycap->wq_audio); 30207dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler init_waitqueue_head(&peasycap->wq_trigger); 3021e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas 30227dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (mutex_lock_interruptible(&mutex_dongle)) { 3023dfcce7bf0913cc81d57a41d8da3175b201ec1664Tomas Winkler SAY("ERROR: cannot down mutex_dongle\n"); 30247dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ERESTARTSYS; 30257dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else { 3026a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas/*---------------------------------------------------------------------------*/ 3027a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas /* 3028a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas * FOR INTERFACES 1 AND 2 THE POINTER peasycap WILL NEED TO 3029a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas * TO BE THE SAME AS THAT ALLOCATED NOW FOR INTERFACE 0. 3030a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas * 3031a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas * NORMALLY ndong WILL NOT HAVE CHANGED SINCE INTERFACE 0 WAS 3032a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas * PROBED, BUT THIS MAY NOT BE THE CASE IF, FOR EXAMPLE, TWO 3033a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas * EASYCAPs ARE PLUGGED IN SIMULTANEOUSLY. 3034a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas */ 3035a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas/*---------------------------------------------------------------------------*/ 30367dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (ndong = 0; ndong < DONGLE_MANY; ndong++) { 30376888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if ((!easycapdc60_dongle[ndong].peasycap) && 30387dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler (!mutex_is_locked(&easycapdc60_dongle 30397dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler [ndong].mutex_video)) && 30407dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler (!mutex_is_locked(&easycapdc60_dongle 30417dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler [ndong].mutex_audio))) { 30427dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler easycapdc60_dongle[ndong].peasycap = peasycap; 30437dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->isdongle = ndong; 30447dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(8, "intf[%i]: peasycap-->easycap" 30457dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "_dongle[%i].peasycap\n", 30467dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler bInterfaceNumber, ndong); 30477dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler break; 30487dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 30497dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 30507dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (DONGLE_MANY <= ndong) { 30517dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: too many dongles\n"); 30527dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler mutex_unlock(&mutex_dongle); 30537dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOMEM; 3054ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas } 3055a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas mutex_unlock(&mutex_dongle); 3056a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas } 30577dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->allocation_video_struct = sizeof(struct easycap); 30587dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->allocation_video_page = 0; 30597dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->allocation_video_urb = 0; 30607dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->allocation_audio_struct = 0; 30617dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->allocation_audio_page = 0; 30627dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->allocation_audio_urb = 0; 3063e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas 3064e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas/*---------------------------------------------------------------------------*/ 3065e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas/* 3066e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas * ... AND FURTHER INITIALIZE THE STRUCTURE 3067e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas*/ 3068e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas/*---------------------------------------------------------------------------*/ 306911ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler peasycap->pusb_device = usbdev; 307011ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler peasycap->pusb_interface = intf; 3071702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 30727dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->ilk = 0; 30737dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->microphone = false; 3074702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 30757dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_interface = -1; 30767dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_altsetting_on = -1; 30777dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_altsetting_off = -1; 30787dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_endpointnumber = -1; 30797dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_maxframesize = -1; 30807dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_buffer_size = -1; 3081702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 30827dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_interface = -1; 30837dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_altsetting_on = -1; 30847dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_altsetting_off = -1; 30857dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_endpointnumber = -1; 30867dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_maxframesize = -1; 30877dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_buffer_size = -1; 3088702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 30897dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->frame_buffer_many = FRAME_BUFFER_MANY; 3090e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas 30917dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (k = 0; k < INPUT_MANY; k++) 30927dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->lost[k] = 0; 30937dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->skip = 0; 30947dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->skipped = 0; 30957dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->offerfields = 0; 3096702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 3097702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 3098f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * DYNAMICALLY FILL IN THE AVAILABLE FORMATS ... 3099702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 3100702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 31017dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler rc = fillin_formats(); 31027dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (0 > rc) { 3103c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: fillin_formats() rc = %i\n", rc); 31047dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 31057dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 31067dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%i formats available\n", rc); 3107f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*---------------------------------------------------------------------------*/ 3108f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/* 3109f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * ... AND POPULATE easycap.inputset[] 3110f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas*/ 3111f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*---------------------------------------------------------------------------*/ 3112b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler /* FIXME: maybe we just use memset 0 */ 3113b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler inputset = peasycap->inputset; 31147dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (k = 0; k < INPUT_MANY; k++) { 3115b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler inputset[k].input_ok = 0; 3116b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler inputset[k].standard_offset_ok = 0; 3117b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler inputset[k].format_offset_ok = 0; 3118b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler inputset[k].brightness_ok = 0; 3119b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler inputset[k].contrast_ok = 0; 3120b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler inputset[k].saturation_ok = 0; 3121b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler inputset[k].hue_ok = 0; 31227dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3123b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler 3124b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler fmtidx = peasycap->ntsc ? NTSC_M : PAL_BGHIN; 3125b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler m = 0; 3126b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler mask = 0; 3127b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler for (i = 0; 0xFFFF != easycap_standard[i].mask; i++) { 3128b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler if (fmtidx == easycap_standard[i].v4l2_standard.index) { 3129b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler m++; 3130b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler for (k = 0; k < INPUT_MANY; k++) 3131b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler inputset[k].standard_offset = i; 3132b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler 31337dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler mask = easycap_standard[i].mask; 3134f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 3135f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 31367dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler 31377dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (1 != m) { 3138b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler SAM("ERROR: " 3139b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler "inputset->standard_offset unpopulated, %i=m\n", m); 31407dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOENT; 31417dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 31427dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler 31437dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap_format = &easycap_format[0]; 3144f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas m = 0; 3145b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler for (i = 0; peasycap_format->v4l2_format.fmt.pix.width; i++) { 3146b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler struct v4l2_pix_format *pix = 3147b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler &peasycap_format->v4l2_format.fmt.pix; 31487dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (((peasycap_format->mask & 0x0F) == (mask & 0x0F)) && 3149b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler pix->field == V4L2_FIELD_NONE && 3150b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler pix->pixelformat == V4L2_PIX_FMT_UYVY && 3151b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler pix->width == 640 && pix->height == 480) { 3152f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas m++; 31537dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (k = 0; k < INPUT_MANY; k++) 3154b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler inputset[k].format_offset = i; 31557dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler break; 3156f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 3157e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler peasycap_format++; 3158f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 31597dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (1 != m) { 3160b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler SAM("ERROR: inputset[]->format_offset unpopulated\n"); 3161e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler return -ENOENT; 3162f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 3163f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas 31647dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler m = 0; 3165b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler for (i = 0; 0xFFFFFFFF != easycap_control[i].id; i++) { 31667dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler value = easycap_control[i].default_value; 31677dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (V4L2_CID_BRIGHTNESS == easycap_control[i].id) { 31687dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler m++; 31697dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (k = 0; k < INPUT_MANY; k++) 3170b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler inputset[k].brightness = value; 31717dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else if (V4L2_CID_CONTRAST == easycap_control[i].id) { 31727dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler m++; 31737dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (k = 0; k < INPUT_MANY; k++) 3174b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler inputset[k].contrast = value; 31757dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else if (V4L2_CID_SATURATION == easycap_control[i].id) { 31767dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler m++; 31777dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (k = 0; k < INPUT_MANY; k++) 3178b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler inputset[k].saturation = value; 31797dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else if (V4L2_CID_HUE == easycap_control[i].id) { 31807dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler m++; 31817dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (k = 0; k < INPUT_MANY; k++) 3182b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler inputset[k].hue = value; 31837dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3184f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 3185e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler 31867dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (4 != m) { 3187b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler SAM("ERROR: inputset[]->brightness underpopulated\n"); 31887dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOENT; 31897dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 31907dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (k = 0; k < INPUT_MANY; k++) 3191b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler inputset[k].input = k; 3192b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler JOM(4, "populated inputset[]\n"); 31937dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "finished initialization\n"); 31947dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else { 3195702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 3196a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas/* 3197a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas * FIXME 3198a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas * 3199a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas * IDENTIFY THE APPROPRIATE POINTER peasycap FOR INTERFACES 1 AND 2. 3200a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas * THE ADDRESS OF peasycap->pusb_device IS RELUCTANTLY USED FOR THIS PURPOSE. 3201a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas */ 3202e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas/*---------------------------------------------------------------------------*/ 32037dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (ndong = 0; ndong < DONGLE_MANY; ndong++) { 320411ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler if (usbdev == easycapdc60_dongle[ndong].peasycap-> 32057dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pusb_device) { 32067dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap = easycapdc60_dongle[ndong].peasycap; 3207c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOT(8, "intf[%i]: dongle[%i].peasycap\n", 3208c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bInterfaceNumber, ndong); 32097dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler break; 32107dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 32117dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 32127dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (DONGLE_MANY <= ndong) { 32137dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAY("ERROR: peasycap is unknown when probing interface %i\n", 32147dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler bInterfaceNumber); 32157dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENODEV; 32167dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 32176888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 32187dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAY("ERROR: peasycap is NULL when probing interface %i\n", 32197dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler bInterfaceNumber); 32207dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENODEV; 3221a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas } 3222dfcce7bf0913cc81d57a41d8da3175b201ec1664Tomas Winkler } 3223702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 32247dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if ((USB_CLASS_VIDEO == bInterfaceClass) || 3225dfcce7bf0913cc81d57a41d8da3175b201ec1664Tomas Winkler (USB_CLASS_VENDOR_SPEC == bInterfaceClass)) { 32267dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->video_interface) { 32277dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_interface = bInterfaceNumber; 32287dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "setting peasycap->video_interface=%i\n", 32297dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_interface); 32307dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else { 32317dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (peasycap->video_interface != bInterfaceNumber) { 32327dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: attempting to reset " 32337dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "peasycap->video_interface\n"); 32347dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("...... continuing with " 32357dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "%i=peasycap->video_interface\n", 3236702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas peasycap->video_interface); 32377dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3238702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 32397dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else if ((USB_CLASS_AUDIO == bInterfaceClass) && 3240fc3cc2caa07568de92cc84780b89b5cf9fbf28b7Tomas Winkler (USB_SUBCLASS_AUDIOSTREAMING == bInterfaceSubClass)) { 32417dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->audio_interface) { 32427dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_interface = bInterfaceNumber; 32437dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "setting peasycap->audio_interface=%i\n", 32447dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_interface); 32457dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else { 32467dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (peasycap->audio_interface != bInterfaceNumber) { 32477dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: attempting to reset " 32487dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "peasycap->audio_interface\n"); 32497dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("...... continuing with " 32507dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "%i=peasycap->audio_interface\n", 32517dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_interface); 32527dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3253702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 3254702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 3255702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 3256702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 3257702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * INVESTIGATE ALL ALTSETTINGS. 3258702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * DONE IN DETAIL BECAUSE USB DEVICE 05e1:0408 HAS DISPARATE INCARNATIONS. 3259702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 3260702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 32617dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler isokalt = 0; 3262702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 326311ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler for (i = 0; i < intf->num_altsetting; i++) { 326411ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler alt = usb_altnum_to_altsetting(intf, i); 326511ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler if (!alt) { 326611ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler SAM("ERROR: alt is NULL\n"); 32677dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 3268702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 326911ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler interface = &alt->desc; 327011ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler if (!interface) { 327111ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler SAM("ERROR: intf_descriptor is NULL\n"); 32727dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 3273702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 32747dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler 327511ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler if (0 == interface->bNumEndpoints) 3276e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler JOM(4, "intf[%i]alt[%i] has no endpoints\n", 3277e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler bInterfaceNumber, i); 32787dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler/*---------------------------------------------------------------------------*/ 327911ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler for (j = 0; j < interface->bNumEndpoints; j++) { 328011ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler ep = &alt->endpoint[j].desc; 328111ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler if (!ep) { 328211ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler SAM("ERROR: ep is NULL.\n"); 32837dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("...... skipping\n"); 32847dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler continue; 32857dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 32861d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler 32871d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler if (!usb_endpoint_is_isoc_in(ep)) { 32881d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler JOM(4, "intf[%i]alt[%i]end[%i] is a %d endpoint\n", 32891d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler bInterfaceNumber, 32901d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler i, j, ep->bmAttributes); 32911d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler if (usb_endpoint_dir_out(ep)) { 32921d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler SAM("ERROR: OUT endpoint unexpected\n"); 32931d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler SAM("...... continuing\n"); 32941d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler } 32951d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler continue; 32967dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 32971d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler switch (bInterfaceClass) { 32981d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler case USB_CLASS_VIDEO: 32991d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler case USB_CLASS_VENDOR_SPEC: { 33001d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler if (ep->wMaxPacketSize) { 33011d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler if (8 > isokalt) { 33021d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler okalt[isokalt] = i; 33031d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler JOM(4, 33041d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "%i=okalt[%i]\n", 33051d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler okalt[isokalt], 33061d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler isokalt); 33071d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler okepn[isokalt] = 33081d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler ep-> 33091d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler bEndpointAddress & 33101d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler 0x0F; 33111d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler JOM(4, 33121d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "%i=okepn[%i]\n", 33131d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler okepn[isokalt], 33141d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler isokalt); 33151d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler okmps[isokalt] = 33161d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler le16_to_cpu(ep-> 33171d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler wMaxPacketSize); 33181d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler JOM(4, 33191d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "%i=okmps[%i]\n", 33201d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler okmps[isokalt], 33211d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler isokalt); 33221d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler isokalt++; 3323702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 33241d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler } else { 33251d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler if (-1 == peasycap-> 33261d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler video_altsetting_off) { 33271d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler peasycap-> 33281d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler video_altsetting_off = 33291d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler i; 33301d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler JOM(4, "%i=video_" 33311d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "altsetting_off " 33321d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "<====\n", 33331d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler peasycap-> 33341d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler video_altsetting_off); 33351d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler } else { 33361d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler SAM("ERROR: peasycap" 33371d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "->video_altsetting_" 33381d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "off already set\n"); 33391d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler SAM("...... " 33401d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "continuing with " 33411d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "%i=peasycap->video_" 33421d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "altsetting_off\n", 33431d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler peasycap-> 33441d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler video_altsetting_off); 33451d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler } 33461d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler } 33471d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler break; 33481d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler } 33491d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler case USB_CLASS_AUDIO: { 33501d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler if (bInterfaceSubClass != 33511d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler USB_SUBCLASS_AUDIOSTREAMING) 3352702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas break; 33531d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler if (!peasycap) { 33541d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler SAM("MISTAKE: " 33551d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "peasycap is NULL\n"); 33561d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler return -EFAULT; 33571d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler } 33581d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler if (ep->wMaxPacketSize) { 33591d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler if (8 > isokalt) { 33601d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler okalt[isokalt] = i ; 33611d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler JOM(4, 33621d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "%i=okalt[%i]\n", 33631d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler okalt[isokalt], 33641d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler isokalt); 33651d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler okepn[isokalt] = 33661d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler ep-> 33671d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler bEndpointAddress & 33681d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler 0x0F; 33691d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler JOM(4, 33701d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "%i=okepn[%i]\n", 33711d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler okepn[isokalt], 33721d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler isokalt); 33731d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler okmps[isokalt] = 33741d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler le16_to_cpu(ep-> 33751d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler wMaxPacketSize); 33761d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler JOM(4, 33771d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "%i=okmps[%i]\n", 33781d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler okmps[isokalt], 33791d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler isokalt); 33801d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler isokalt++; 33817dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 33821d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler } else { 33831d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler if (-1 == peasycap-> 33841d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler audio_altsetting_off) { 33851d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler peasycap-> 33861d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler audio_altsetting_off = 33871d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler i; 33881d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler JOM(4, "%i=audio_" 33891d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "altsetting_off " 33901d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "<====\n", 33911d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler peasycap-> 33921d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler audio_altsetting_off); 33931d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler } else { 33941d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler SAM("ERROR: peasycap" 33951d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "->audio_altsetting_" 33961d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "off already set\n"); 33971d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler SAM("...... " 33981d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "continuing with " 33991d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "%i=peasycap->" 34001d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "audio_altsetting_" 34011d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "off\n", 34021d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler peasycap-> 34031d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler audio_altsetting_off); 34047dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3405702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 34061d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler break; 34071d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler } 34081d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler default: 34091d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler break; 34107dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 341111ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler if (0 == ep->wMaxPacketSize) { 34127dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "intf[%i]alt[%i]end[%i] " 34137dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "has zero packet size\n", 34147dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler bInterfaceNumber, i, j); 3415702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 3416702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 3417702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 3418702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 3419702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 3420702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * PERFORM INITIALIZATION OF THE PROBED INTERFACE 3421702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 3422702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 34237dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "initialization begins for interface %i\n", 342411ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler interface->bInterfaceNumber); 34257dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler switch (bInterfaceNumber) { 3426702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 3427702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 3428702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * INTERFACE 0 IS THE VIDEO INTERFACE 3429702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 3430702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 34317dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler case 0: { 34327dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (!peasycap) { 34337dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: peasycap is NULL\n"); 34347dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 34357dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 34367dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (!isokalt) { 34377dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: no viable video_altsetting_on\n"); 34387dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOENT; 34397dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else { 34407dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_altsetting_on = okalt[isokalt - 1]; 34417dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%i=video_altsetting_on <====\n", 34427dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_altsetting_on); 34437dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3444702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 3445702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 3446702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * DECIDE THE VIDEO STREAMING PARAMETERS 3447702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 3448702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 34497dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_endpointnumber = okepn[isokalt - 1]; 34507dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%i=video_endpointnumber\n", peasycap->video_endpointnumber); 34517dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler maxpacketsize = okmps[isokalt - 1]; 3452e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler 3453e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler peasycap->video_isoc_maxframesize = 3454e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler min(maxpacketsize, USB_2_0_MAXPACKETSIZE); 34557dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (0 >= peasycap->video_isoc_maxframesize) { 34567dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: bad video_isoc_maxframesize\n"); 34577dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM(" possibly because port is USB 1.1\n"); 34587dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOENT; 34597dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3460e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler JOM(4, "%i=video_isoc_maxframesize\n", 3461e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler peasycap->video_isoc_maxframesize); 3462e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler 34637dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_framesperdesc = VIDEO_ISOC_FRAMESPERDESC; 34647dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%i=video_isoc_framesperdesc\n", 34657dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_framesperdesc); 34667dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (0 >= peasycap->video_isoc_framesperdesc) { 34677dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: bad video_isoc_framesperdesc\n"); 34687dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOENT; 34697dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 34707dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_buffer_size = 34717dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_maxframesize * 34727dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_framesperdesc; 34737dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%i=video_isoc_buffer_size\n", 34747dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_buffer_size); 34757dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if ((PAGE_SIZE << VIDEO_ISOC_ORDER) < 34767dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_buffer_size) { 34777dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: peasycap->video_isoc_buffer_size too big\n"); 34787dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 34797dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3480702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 34817dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->video_interface) { 34827dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: video_interface is unset\n"); 34837dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 34847dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 34857dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->video_altsetting_on) { 34867dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: video_altsetting_on is unset\n"); 34877dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 34887dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 34897dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->video_altsetting_off) { 34907dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: video_interface_off is unset\n"); 34917dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 34927dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 34937dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->video_endpointnumber) { 34947dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: video_endpointnumber is unset\n"); 34957dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 34967dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 34977dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->video_isoc_maxframesize) { 34987dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: video_isoc_maxframesize is unset\n"); 34997dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 35007dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 35017dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->video_isoc_buffer_size) { 35027dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: video_isoc_buffer_size is unset\n"); 35037dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 35047dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3505702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 3506702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 3507702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * ALLOCATE MEMORY FOR VIDEO BUFFERS. LISTS MUST BE INITIALIZED FIRST. 3508702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 3509702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 35107dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler INIT_LIST_HEAD(&(peasycap->urb_video_head)); 35117dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->purb_video_head = &(peasycap->urb_video_head); 35127dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler/*---------------------------------------------------------------------------*/ 35137dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "allocating %i frame buffers of size %li\n", 35147dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler FRAME_BUFFER_MANY, (long int)FRAME_BUFFER_SIZE); 35157dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, ".... each scattered over %li pages\n", 35167dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler FRAME_BUFFER_SIZE/PAGE_SIZE); 35177dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler 35187dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (k = 0; k < FRAME_BUFFER_MANY; k++) { 35197dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) { 35206888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (peasycap->frame_buffer[k][m].pgo) 35217dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("attempting to reallocate frame " 35227dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler " buffers\n"); 35237dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler else { 35247dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pbuf = (void *)__get_free_page(GFP_KERNEL); 35256888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pbuf) { 35267dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: Could not allocate frame " 35277dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "buffer %i page %i\n", k, m); 35287dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOMEM; 35297dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else 35307dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->allocation_video_page += 1; 35317dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->frame_buffer[k][m].pgo = pbuf; 35327dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 35337dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->frame_buffer[k][m].pto = 35347dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->frame_buffer[k][m].pgo; 3535702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 3536702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 3537702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 35387dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->frame_fill = 0; 35397dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->frame_read = 0; 35407dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "allocation of frame buffers done: %i pages\n", k * 35417dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler m); 35427dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler/*---------------------------------------------------------------------------*/ 35437dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "allocating %i field buffers of size %li\n", 35447dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler FIELD_BUFFER_MANY, (long int)FIELD_BUFFER_SIZE); 35457dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, ".... each scattered over %li pages\n", 35467dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler FIELD_BUFFER_SIZE/PAGE_SIZE); 35477dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler 35487dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (k = 0; k < FIELD_BUFFER_MANY; k++) { 35497dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) { 35506888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (peasycap->field_buffer[k][m].pgo) { 35517dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: attempting to reallocate " 35527dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "field buffers\n"); 35537dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else { 35547dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pbuf = (void *) __get_free_page(GFP_KERNEL); 35556888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pbuf) { 35567dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: Could not allocate field" 35577dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler " buffer %i page %i\n", k, m); 35587dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOMEM; 35597dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 35607dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler else 35617dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->allocation_video_page += 1; 35627dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->field_buffer[k][m].pgo = pbuf; 3563702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 35647dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->field_buffer[k][m].pto = 35657dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->field_buffer[k][m].pgo; 35667dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 35677dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->field_buffer[k][0].kount = 0x0200; 3568702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 35697dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->field_fill = 0; 35707dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->field_page = 0; 35717dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->field_read = 0; 35727dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "allocation of field buffers done: %i pages\n", k * 35737dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler m); 35747dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler/*---------------------------------------------------------------------------*/ 35757dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "allocating %i isoc video buffers of size %i\n", 35767dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler VIDEO_ISOC_BUFFER_MANY, 35777dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_buffer_size); 35787dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, ".... each occupying contiguous memory pages\n"); 35797dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler 35807dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { 3581a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler pbuf = (void *)__get_free_pages(GFP_KERNEL, 3582a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler VIDEO_ISOC_ORDER); 35836888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pbuf) { 35847dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: Could not allocate isoc video buffer " 35857dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "%i\n", k); 35867dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOMEM; 35877dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else 35887dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->allocation_video_page += 3589a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler BIT(VIDEO_ISOC_ORDER); 3590702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 35917dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_buffer[k].pgo = pbuf; 3592a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->video_isoc_buffer[k].pto = 3593a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler pbuf + peasycap->video_isoc_buffer_size; 35947dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_buffer[k].kount = k; 35957dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 35967dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "allocation of isoc video buffers done: %i pages\n", 35977dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler k * (0x01 << VIDEO_ISOC_ORDER)); 3598702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 3599702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 3600702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * ALLOCATE AND INITIALIZE MULTIPLE struct urb ... 3601702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 3602702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 36037dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY); 36047dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "using %i=peasycap->video_isoc_framesperdesc\n", 36057dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_framesperdesc); 36067dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "using %i=peasycap->video_isoc_maxframesize\n", 36077dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_maxframesize); 36087dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "using %i=peasycap->video_isoc_buffer_sizen", 36097dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_buffer_size); 36107dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler 36117dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { 36127dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb = usb_alloc_urb(peasycap->video_isoc_framesperdesc, 36137dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler GFP_KERNEL); 36146888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!purb) { 36157dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: usb_alloc_urb returned NULL for buffer " 36167dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "%i\n", k); 36177dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOMEM; 36187dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else 36197dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->allocation_video_urb += 1; 3620702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 36217dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL); 36226888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pdata_urb) { 36237dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: Could not allocate struct data_urb.\n"); 36247dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOMEM; 36257dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else 36267dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->allocation_video_struct += 36277dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler sizeof(struct data_urb); 3628702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 36297dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pdata_urb->purb = purb; 36307dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pdata_urb->isbuf = k; 36317dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pdata_urb->length = 0; 36327dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler list_add_tail(&(pdata_urb->list_head), 36337dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->purb_video_head); 3634702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 3635702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 3636702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * ... AND INITIALIZE THEM 3637702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 3638702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 36397dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (!k) { 36407dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "initializing video urbs thus:\n"); 36417dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->interval = 1;\n"); 36427dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->dev = peasycap->pusb_device;\n"); 36437dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->pipe = usb_rcvisocpipe" 36447dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "(peasycap->pusb_device,%i);\n", 36457dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_endpointnumber); 36467dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n"); 36477dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->transfer_buffer = peasycap->" 36487dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "video_isoc_buffer[.].pgo;\n"); 36497dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->transfer_buffer_length = %i;\n", 36507dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_buffer_size); 36517dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->complete = easycap_complete;\n"); 36527dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->context = peasycap;\n"); 36537dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->start_frame = 0;\n"); 36547dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->number_of_packets = %i;\n", 36557dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_framesperdesc); 36567dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " for (j = 0; j < %i; j++)\n", 36577dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_framesperdesc); 36587dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " {\n"); 36597dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n", 36607dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_maxframesize); 36617dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->iso_frame_desc[j].length = %i;\n", 36627dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_maxframesize); 36637dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " }\n"); 36647dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3665702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 36667dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->interval = 1; 36677dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->dev = peasycap->pusb_device; 36687dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, 36697dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_endpointnumber); 36707dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->transfer_flags = URB_ISO_ASAP; 36717dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->transfer_buffer = peasycap->video_isoc_buffer[k].pgo; 36727dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->transfer_buffer_length = 36737dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_buffer_size; 36747dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->complete = easycap_complete; 36757dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->context = peasycap; 36767dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->start_frame = 0; 36777dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->number_of_packets = peasycap->video_isoc_framesperdesc; 36787dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (j = 0; j < peasycap->video_isoc_framesperdesc; j++) { 36797dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->iso_frame_desc[j].offset = j * 36807dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_maxframesize; 36817dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->iso_frame_desc[j].length = 36827dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_maxframesize; 36837dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3684702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 36857dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "allocation of %i struct urb done.\n", k); 3686702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*--------------------------------------------------------------------------*/ 3687702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 3688702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * SAVE POINTER peasycap IN THIS INTERFACE. 3689702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 3690702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*--------------------------------------------------------------------------*/ 369111ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler usb_set_intfdata(intf, peasycap); 3692268dfede46e24eef55a2ef7a10a462617936771eMike Thomas/*---------------------------------------------------------------------------*/ 3693268dfede46e24eef55a2ef7a10a462617936771eMike Thomas/* 3694268dfede46e24eef55a2ef7a10a462617936771eMike Thomas * IT IS ESSENTIAL TO INITIALIZE THE HARDWARE BEFORE, RATHER THAN AFTER, 3695268dfede46e24eef55a2ef7a10a462617936771eMike Thomas * THE DEVICE IS REGISTERED, BECAUSE SOME VERSIONS OF THE videodev MODULE 3696268dfede46e24eef55a2ef7a10a462617936771eMike Thomas * CALL easycap_open() IMMEDIATELY AFTER REGISTRATION, CAUSING A CLASH. 3697268dfede46e24eef55a2ef7a10a462617936771eMike Thomas * BEWARE. 3698268dfede46e24eef55a2ef7a10a462617936771eMike Thomas*/ 3699268dfede46e24eef55a2ef7a10a462617936771eMike Thomas/*---------------------------------------------------------------------------*/ 37008d6139547ca349f9acea6536dd6b7f6140d3507fTomas Winkler peasycap->ntsc = easycap_ntsc; 37018d6139547ca349f9acea6536dd6b7f6140d3507fTomas Winkler JOM(8, "defaulting initially to %s\n", 37028d6139547ca349f9acea6536dd6b7f6140d3507fTomas Winkler easycap_ntsc ? "NTSC" : "PAL"); 37037dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler rc = reset(peasycap); 37047dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (rc) { 3705c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: reset() rc = %i\n", rc); 37067dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 37077dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3708702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*--------------------------------------------------------------------------*/ 3709702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 3710702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * THE VIDEO DEVICE CAN BE REGISTERED NOW, AS IT IS READY. 3711702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 3712702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*--------------------------------------------------------------------------*/ 3713cdaa898b5efcc598ab1004e8f913061dc7005091Tomas Winkler if (v4l2_device_register(&intf->dev, &peasycap->v4l2_device)) { 37147dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("v4l2_device_register() failed\n"); 37157dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENODEV; 37167dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3717cdaa898b5efcc598ab1004e8f913061dc7005091Tomas Winkler JOM(4, "registered device instance: %s\n", 3718cdaa898b5efcc598ab1004e8f913061dc7005091Tomas Winkler peasycap->v4l2_device.name); 3719e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas/*---------------------------------------------------------------------------*/ 3720e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas/* 3721a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas * FIXME 3722ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * 3723ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * 3724e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas * THIS IS BELIEVED TO BE HARMLESS, BUT MAY WELL BE UNNECESSARY OR WRONG: 3725e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas*/ 3726e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas/*---------------------------------------------------------------------------*/ 37277dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_device.v4l2_dev = NULL; 3728e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas/*---------------------------------------------------------------------------*/ 3729702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 3730e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas 37317dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler strcpy(&peasycap->video_device.name[0], "easycapdc60"); 37327dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_device.fops = &v4l2_fops; 37337dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_device.minor = -1; 37347dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_device.release = (void *)(&videodev_release); 3735702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 37367dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler video_set_drvdata(&(peasycap->video_device), (void *)peasycap); 3737702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 37387dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (0 != (video_register_device(&(peasycap->video_device), 37397dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler VFL_TYPE_GRABBER, -1))) { 37407dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler err("Not able to register with videodev"); 37417dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler videodev_release(&(peasycap->video_device)); 37427dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENODEV; 37437dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else { 37447dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler (peasycap->registered_video)++; 37457dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("registered with videodev: %i=minor\n", 37467dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_device.minor); 37477dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->minor = peasycap->video_device.minor; 37487dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3749e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ 3750a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas 37517dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler break; 3752dfcce7bf0913cc81d57a41d8da3175b201ec1664Tomas Winkler } 3753702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*--------------------------------------------------------------------------*/ 3754702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 3755702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * INTERFACE 1 IS THE AUDIO CONTROL INTERFACE 3756702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * INTERFACE 2 IS THE AUDIO STREAMING INTERFACE 3757702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 3758702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*--------------------------------------------------------------------------*/ 37597dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler case 1: { 37607dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (!peasycap) { 37617dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: peasycap is NULL\n"); 37627dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 37637dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3764702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*--------------------------------------------------------------------------*/ 3765702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 3766702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * SAVE POINTER peasycap IN INTERFACE 1 3767702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 3768702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*--------------------------------------------------------------------------*/ 376911ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler usb_set_intfdata(intf, peasycap); 37707dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "no initialization required for interface %i\n", 377111ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler interface->bInterfaceNumber); 37727dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler break; 3773702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 3774c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler/*--------------------------------------------------------------------------*/ 37757dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler case 2: { 37767dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (!peasycap) { 37777dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: peasycap is NULL\n"); 37787dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 37797dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 37807dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (!isokalt) { 37817dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: no viable audio_altsetting_on\n"); 37827dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOENT; 37837dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else { 37847dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_altsetting_on = okalt[isokalt - 1]; 37857dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%i=audio_altsetting_on <====\n", 37867dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_altsetting_on); 37877dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3788e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas 37897dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_endpointnumber = okepn[isokalt - 1]; 37907dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%i=audio_endpointnumber\n", peasycap->audio_endpointnumber); 3791e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas 37927dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_maxframesize = okmps[isokalt - 1]; 37937dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%i=audio_isoc_maxframesize\n", 37947dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_maxframesize); 37957dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (0 >= peasycap->audio_isoc_maxframesize) { 37967dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: bad audio_isoc_maxframesize\n"); 37977dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOENT; 37987dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 37997dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (9 == peasycap->audio_isoc_maxframesize) { 38007dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->ilk |= 0x02; 38017dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("audio hardware is microphone\n"); 38027dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->microphone = true; 3803a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->audio_pages_per_fragment = 3804a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler PAGES_PER_AUDIO_FRAGMENT; 38057dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else if (256 == peasycap->audio_isoc_maxframesize) { 38067dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->ilk &= ~0x02; 38077dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("audio hardware is AC'97\n"); 38087dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->microphone = false; 3809a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->audio_pages_per_fragment = 3810a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler PAGES_PER_AUDIO_FRAGMENT; 38117dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else { 38127dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("hardware is unidentified:\n"); 38137dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("%i=audio_isoc_maxframesize\n", 3814a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->audio_isoc_maxframesize); 38157dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOENT; 38167dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3817702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 38187dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_bytes_per_fragment = 3819a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->audio_pages_per_fragment * PAGE_SIZE; 38207dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_buffer_page_many = (AUDIO_FRAGMENT_MANY * 3821a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->audio_pages_per_fragment); 38227dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler 38237dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%6i=AUDIO_FRAGMENT_MANY\n", AUDIO_FRAGMENT_MANY); 38247dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%6i=audio_pages_per_fragment\n", 38257dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_pages_per_fragment); 38267dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%6i=audio_bytes_per_fragment\n", 38277dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_bytes_per_fragment); 38287dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%6i=audio_buffer_page_many\n", 38297dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_buffer_page_many); 38307dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler 38317dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_framesperdesc = AUDIO_ISOC_FRAMESPERDESC; 38327dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler 38337dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%i=audio_isoc_framesperdesc\n", 38347dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_framesperdesc); 38357dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (0 >= peasycap->audio_isoc_framesperdesc) { 38367dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: bad audio_isoc_framesperdesc\n"); 38377dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOENT; 38387dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3839702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 38407dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_buffer_size = 38417dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_maxframesize * 38427dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_framesperdesc; 38437dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%i=audio_isoc_buffer_size\n", 38447dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_buffer_size); 38457dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (AUDIO_ISOC_BUFFER_SIZE < peasycap->audio_isoc_buffer_size) { 38467dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: audio_isoc_buffer_size bigger " 38477dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "than %li=AUDIO_ISOC_BUFFER_SIZE\n", 38487dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler AUDIO_ISOC_BUFFER_SIZE); 38497dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 38507dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 38517dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->audio_interface) { 38527dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: audio_interface is unset\n"); 38537dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 38547dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 38557dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->audio_altsetting_on) { 38567dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: audio_altsetting_on is unset\n"); 38577dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 38587dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 38597dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->audio_altsetting_off) { 38607dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: audio_interface_off is unset\n"); 38617dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 38627dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 38637dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->audio_endpointnumber) { 38647dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: audio_endpointnumber is unset\n"); 38657dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 38667dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 38677dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->audio_isoc_maxframesize) { 38687dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: audio_isoc_maxframesize is unset\n"); 38697dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 38707dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 38717dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->audio_isoc_buffer_size) { 38727dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: audio_isoc_buffer_size is unset\n"); 38737dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 38747dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3875702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 3876702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 3877702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * ALLOCATE MEMORY FOR AUDIO BUFFERS. LISTS MUST BE INITIALIZED FIRST. 3878702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 3879702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 38807dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler INIT_LIST_HEAD(&(peasycap->urb_audio_head)); 38817dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->purb_audio_head = &(peasycap->urb_audio_head); 3882702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 3883702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 38847dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "allocating %i isoc audio buffers of size %i\n", 3885a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler AUDIO_ISOC_BUFFER_MANY, 3886a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->audio_isoc_buffer_size); 38877dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, ".... each occupying contiguous memory pages\n"); 3888702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 38897dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { 3890a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler pbuf = (void *)__get_free_pages(GFP_KERNEL, 3891a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler AUDIO_ISOC_ORDER); 38926888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pbuf) { 38937dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: Could not allocate isoc audio buffer " 38947dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "%i\n", k); 38957dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOMEM; 38967dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else 38977dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->allocation_audio_page += 3898a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler BIT(AUDIO_ISOC_ORDER); 3899702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 39007dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_buffer[k].pgo = pbuf; 39017dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_buffer[k].pto = pbuf + 39027dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_buffer_size; 39037dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_buffer[k].kount = k; 39047dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 39057dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "allocation of isoc audio buffers done.\n"); 3906702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 3907702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 3908702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * ALLOCATE AND INITIALIZE MULTIPLE struct urb ... 3909702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 3910702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 39117dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY); 39127dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "using %i=peasycap->audio_isoc_framesperdesc\n", 3913a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->audio_isoc_framesperdesc); 39147dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "using %i=peasycap->audio_isoc_maxframesize\n", 3915a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->audio_isoc_maxframesize); 39167dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "using %i=peasycap->audio_isoc_buffer_size\n", 3917a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->audio_isoc_buffer_size); 39187dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler 39197dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { 39207dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb = usb_alloc_urb(peasycap->audio_isoc_framesperdesc, 3921a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler GFP_KERNEL); 39226888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!purb) { 39237dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: usb_alloc_urb returned NULL for buffer " 39247dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "%i\n", k); 39257dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOMEM; 3926e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler } 3927e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler peasycap->allocation_audio_urb += 1 ; 3928702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 39297dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL); 39306888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pdata_urb) { 39317dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: Could not allocate struct data_urb.\n"); 39327dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOMEM; 3933e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler } 3934e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler peasycap->allocation_audio_struct += 3935e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler sizeof(struct data_urb); 3936702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 39377dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pdata_urb->purb = purb; 39387dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pdata_urb->isbuf = k; 39397dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pdata_urb->length = 0; 39407dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler list_add_tail(&(pdata_urb->list_head), 39417dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->purb_audio_head); 3942702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 3943702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 3944702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * ... AND INITIALIZE THEM 3945702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 3946702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 39477dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (!k) { 39487dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "initializing audio urbs thus:\n"); 39497dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->interval = 1;\n"); 39507dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->dev = peasycap->pusb_device;\n"); 39517dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->pipe = usb_rcvisocpipe(peasycap->" 39527dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "pusb_device,%i);\n", 39537dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_endpointnumber); 39547dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n"); 39557dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->transfer_buffer = " 39567dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "peasycap->audio_isoc_buffer[.].pgo;\n"); 39577dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->transfer_buffer_length = %i;\n", 3958a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->audio_isoc_buffer_size); 39597dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->complete = easycap_alsa_complete;\n"); 39607dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->context = peasycap;\n"); 39617dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->start_frame = 0;\n"); 39627dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->number_of_packets = %i;\n", 39637dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_framesperdesc); 39647dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " for (j = 0; j < %i; j++)\n", 39657dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_framesperdesc); 39667dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " {\n"); 39677dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n", 3968a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->audio_isoc_maxframesize); 39697dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->iso_frame_desc[j].length = %i;\n", 3970a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->audio_isoc_maxframesize); 39717dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " }\n"); 3972dfcce7bf0913cc81d57a41d8da3175b201ec1664Tomas Winkler } 3973702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 39747dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->interval = 1; 39757dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->dev = peasycap->pusb_device; 39767dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, 39777dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_endpointnumber); 39787dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->transfer_flags = URB_ISO_ASAP; 39797dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->transfer_buffer = peasycap->audio_isoc_buffer[k].pgo; 39807dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->transfer_buffer_length = 39817dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_buffer_size; 39827dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->complete = easycap_alsa_complete; 39837dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->context = peasycap; 39847dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->start_frame = 0; 39857dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->number_of_packets = peasycap->audio_isoc_framesperdesc; 39867dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (j = 0; j < peasycap->audio_isoc_framesperdesc; j++) { 39877dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->iso_frame_desc[j].offset = j * 39887dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_maxframesize; 39897dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->iso_frame_desc[j].length = 39907dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_maxframesize; 39917dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3992702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 39937dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "allocation of %i struct urb done.\n", k); 3994702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 3995702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 3996702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * SAVE POINTER peasycap IN THIS INTERFACE. 3997702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 3998702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 399911ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler usb_set_intfdata(intf, peasycap); 4000702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 4001702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 4002702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * THE AUDIO DEVICE CAN BE REGISTERED NOW, AS IT IS READY. 4003702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 4004702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 40057dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "initializing ALSA card\n"); 4006a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas 40077dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler rc = easycap_alsa_probe(peasycap); 40087dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (rc) { 4009c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler err("easycap_alsa_probe() rc = %i\n", rc); 40107dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENODEV; 40117dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 4012a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas 4013a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas 4014ad30d7af14c778a63304e42acdcedc365b26e8d8Tomas Winkler JOM(8, "kref_get() with %i=kref.refcount.counter\n", 4015ad30d7af14c778a63304e42acdcedc365b26e8d8Tomas Winkler peasycap->kref.refcount.counter); 4016ad30d7af14c778a63304e42acdcedc365b26e8d8Tomas Winkler kref_get(&peasycap->kref); 4017ad30d7af14c778a63304e42acdcedc365b26e8d8Tomas Winkler peasycap->registered_audio++; 40187dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler break; 4019dfcce7bf0913cc81d57a41d8da3175b201ec1664Tomas Winkler } 4020702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 4021702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 4022702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * INTERFACES OTHER THAN 0, 1 AND 2 ARE UNEXPECTED 4023702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 4024702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 4025dfcce7bf0913cc81d57a41d8da3175b201ec1664Tomas Winkler default: 4026dfcce7bf0913cc81d57a41d8da3175b201ec1664Tomas Winkler JOM(4, "ERROR: unexpected interface %i\n", bInterfaceNumber); 4027dfcce7bf0913cc81d57a41d8da3175b201ec1664Tomas Winkler return -EINVAL; 40287dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 4029e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler SAM("ends successfully for interface %i\n", bInterfaceNumber); 40307dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return 0; 4031702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 4032702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 4033702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 4034702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 4035ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * WHEN THIS FUNCTION IS CALLED THE EasyCAP HAS ALREADY BEEN PHYSICALLY 4036ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * UNPLUGGED. HENCE peasycap->pusb_device IS NO LONGER VALID. 4037a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas * 403873019286cddc8bba1773944a7b6b603137fd66ffTomas Winkler * THIS FUNCTION AFFECTS ALSA. BEWARE. 4039702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 4040702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 4041d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic void easycap_usb_disconnect(struct usb_interface *pusb_interface) 4042702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 40437dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler struct usb_host_interface *pusb_host_interface; 40447dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler struct usb_interface_descriptor *pusb_interface_descriptor; 40457dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler u8 bInterfaceNumber; 40467dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler struct easycap *peasycap; 40477dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler 40487dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler struct list_head *plist_head; 40497dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler struct data_urb *pdata_urb; 40507dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler int minor, m, kd; 4051702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 40527dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOT(4, "\n"); 4053702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 40547dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pusb_host_interface = pusb_interface->cur_altsetting; 40556888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pusb_host_interface) { 40567dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOT(4, "ERROR: pusb_host_interface is NULL\n"); 40577dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return; 40587dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 40597dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pusb_interface_descriptor = &(pusb_host_interface->desc); 40606888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pusb_interface_descriptor) { 40617dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOT(4, "ERROR: pusb_interface_descriptor is NULL\n"); 40627dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return; 40637dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 40647dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler bInterfaceNumber = pusb_interface_descriptor->bInterfaceNumber; 40657dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler minor = pusb_interface->minor; 40667dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOT(4, "intf[%i]: minor=%i\n", bInterfaceNumber, minor); 4067702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 40687dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (1 == bInterfaceNumber) 40697dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return; 4070e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas 40717dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap = usb_get_intfdata(pusb_interface); 40726888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 40737dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAY("ERROR: peasycap is NULL\n"); 40747dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return; 40757dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 4076e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas/*---------------------------------------------------------------------------*/ 4077268dfede46e24eef55a2ef7a10a462617936771eMike Thomas/* 4078e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas * IF THE WAIT QUEUES ARE NOT CLEARED A DEADLOCK IS POSSIBLE. BEWARE. 4079e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas*/ 4080e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas/*---------------------------------------------------------------------------*/ 40817dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_eof = 1; 40827dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_eof = 1; 40837dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler wake_up_interruptible(&(peasycap->wq_video)); 40847dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler wake_up_interruptible(&(peasycap->wq_audio)); 40857dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler/*---------------------------------------------------------------------------*/ 40867dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler switch (bInterfaceNumber) { 40877dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler case 0: { 40886888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (peasycap->purb_video_head) { 40897dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "killing video urbs\n"); 40907dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler m = 0; 4091a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler list_for_each(plist_head, peasycap->purb_video_head) { 40927dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pdata_urb = list_entry(plist_head, 40937dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler struct data_urb, list_head); 40946888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (pdata_urb) { 40956888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (pdata_urb->purb) { 40967dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler usb_kill_urb(pdata_urb->purb); 40977dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler m++; 40987dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 4099702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 4100702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 41017dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%i video urbs killed\n", m); 4102e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas } 41037dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler break; 4104702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 4105702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 41067dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler case 2: { 41076888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (peasycap->purb_audio_head) { 41087dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "killing audio urbs\n"); 41097dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler m = 0; 4110a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler list_for_each(plist_head, peasycap->purb_audio_head) { 41117dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pdata_urb = list_entry(plist_head, 41127dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler struct data_urb, list_head); 41136888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (pdata_urb) { 41146888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (pdata_urb->purb) { 41157dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler usb_kill_urb(pdata_urb->purb); 41167dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler m++; 41177dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 4118702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 4119702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 41207dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%i audio urbs killed\n", m); 4121e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas } 41227dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler break; 4123702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 41247dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler default: 41257dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler break; 4126c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 4127702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*--------------------------------------------------------------------------*/ 4128702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 4129702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * DEREGISTER 4130ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * 4131ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * THIS PROCEDURE WILL BLOCK UNTIL easycap_poll(), VIDEO IOCTL AND AUDIO 4132ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * IOCTL ARE ALL UNLOCKED. IF THIS IS NOT DONE AN Oops CAN OCCUR WHEN 4133ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * AN EasyCAP IS UNPLUGGED WHILE THE URBS ARE RUNNING. BEWARE. 4134702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 4135702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*--------------------------------------------------------------------------*/ 4136c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler kd = isdongle(peasycap); 4137c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler switch (bInterfaceNumber) { 4138c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 0: { 4139c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 <= kd && DONGLE_MANY > kd) { 4140c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler wake_up_interruptible(&peasycap->wq_video); 4141c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "about to lock dongle[%i].mutex_video\n", kd); 4142c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (mutex_lock_interruptible(&easycapdc60_dongle[kd]. 4143ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas mutex_video)) { 4144c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: " 4145c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "cannot lock dongle[%i].mutex_video\n", kd); 4146c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 4147c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 4148c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "locked dongle[%i].mutex_video\n", kd); 4149c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 4150c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd); 4151ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas } 4152ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas/*---------------------------------------------------------------------------*/ 4153c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!peasycap->v4l2_device.name[0]) { 4154c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: peasycap->v4l2_device.name is empty\n"); 4155c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 <= kd && DONGLE_MANY > kd) 4156c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mutex_unlock(&easycapdc60_dongle[kd].mutex_video); 4157c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 4158c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 4159c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v4l2_device_disconnect(&peasycap->v4l2_device); 4160c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "v4l2_device_disconnect() OK\n"); 4161c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v4l2_device_unregister(&peasycap->v4l2_device); 4162c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "v4l2_device_unregister() OK\n"); 4163c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 4164c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler video_unregister_device(&peasycap->video_device); 4165c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "intf[%i]: video_unregister_device() minor=%i\n", 4166c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bInterfaceNumber, minor); 4167c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->registered_video--; 4168268dfede46e24eef55a2ef7a10a462617936771eMike Thomas/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ 4169268dfede46e24eef55a2ef7a10a462617936771eMike Thomas 4170c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 <= kd && DONGLE_MANY > kd) { 4171c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mutex_unlock(&easycapdc60_dongle[kd].mutex_video); 4172c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "unlocked dongle[%i].mutex_video\n", kd); 4173c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 4174c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 4175ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas } 4176c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 2: { 4177c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 <= kd && DONGLE_MANY > kd) { 4178c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler wake_up_interruptible(&peasycap->wq_audio); 4179c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "about to lock dongle[%i].mutex_audio\n", kd); 4180c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (mutex_lock_interruptible(&easycapdc60_dongle[kd]. 4181ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas mutex_audio)) { 4182c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: " 4183c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "cannot lock dongle[%i].mutex_audio\n", kd); 4184c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 4185c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 4186c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "locked dongle[%i].mutex_audio\n", kd); 4187c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else 4188c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd); 4189c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 != snd_card_free(peasycap->psnd_card)) { 4190c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: snd_card_free() failed\n"); 4191c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 4192c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->psnd_card = NULL; 4193c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap->registered_audio)--; 4194c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 4195c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 <= kd && DONGLE_MANY > kd) { 4196c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); 4197c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "unlocked dongle[%i].mutex_audio\n", kd); 4198c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 4199c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 4200c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 4201c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler default: 4202c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 4203ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas } 4204702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 4205702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 4206702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * CALL easycap_delete() IF NO REMAINING REFERENCES TO peasycap 4207a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas * (ALSO WHEN ALSA HAS BEEN IN USE) 4208702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 4209702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 4210c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!peasycap->kref.refcount.counter) { 4211c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: peasycap->kref.refcount.counter is zero " 4212c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "so cannot call kref_put()\n"); 4213ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas SAM("ending unsuccessfully: may cause memory leak\n"); 4214ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas return; 4215ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas } 4216c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 <= kd && DONGLE_MANY > kd) { 4217c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "about to lock dongle[%i].mutex_video\n", kd); 4218c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) { 4219c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: cannot lock dongle[%i].mutex_video\n", kd); 4220c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ending unsuccessfully: may cause memory leak\n"); 4221c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 4222c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 4223c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "locked dongle[%i].mutex_video\n", kd); 4224c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "about to lock dongle[%i].mutex_audio\n", kd); 4225c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_audio)) { 4226c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: cannot lock dongle[%i].mutex_audio\n", kd); 4227c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mutex_unlock(&(easycapdc60_dongle[kd].mutex_video)); 4228c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "unlocked dongle[%i].mutex_video\n", kd); 4229c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ending unsuccessfully: may cause memory leak\n"); 4230c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 4231c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 4232c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "locked dongle[%i].mutex_audio\n", kd); 4233c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 4234c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "intf[%i]: %i=peasycap->kref.refcount.counter\n", 4235c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bInterfaceNumber, (int)peasycap->kref.refcount.counter); 4236c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler kref_put(&peasycap->kref, easycap_delete); 4237c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOT(4, "intf[%i]: kref_put() done.\n", bInterfaceNumber); 4238c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 <= kd && DONGLE_MANY > kd) { 4239c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mutex_unlock(&(easycapdc60_dongle[kd].mutex_audio)); 4240c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOT(4, "unlocked dongle[%i].mutex_audio\n", kd); 4241c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mutex_unlock(&easycapdc60_dongle[kd].mutex_video); 4242c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOT(4, "unlocked dongle[%i].mutex_video\n", kd); 4243c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 4244702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 4245c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "ends\n"); 4246c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 4247702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 4248702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 4249a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas 4250702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 4251702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 4252d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler * PARAMETERS APPLICABLE TO ENTIRE DRIVER, I.E. BOTH VIDEO AND AUDIO 4253702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 4254702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 4255d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic struct usb_device_id easycap_usb_device_id_table[] = { 4256d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler {USB_DEVICE(USB_EASYCAP_VENDOR_ID, USB_EASYCAP_PRODUCT_ID)}, 4257d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler { } 4258d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler}; 4259d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler 4260d090bf57492bde9cb6281246c92963476c40b512Tomas WinklerMODULE_DEVICE_TABLE(usb, easycap_usb_device_id_table); 4261d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstruct usb_driver easycap_usb_driver = { 4262d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .name = "easycap", 4263d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .id_table = easycap_usb_device_id_table, 4264d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .probe = easycap_usb_probe, 4265d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .disconnect = easycap_usb_disconnect, 4266d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler}; 4267702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 4268d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic int __init easycap_module_init(void) 4269d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler{ 4270d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler int k, rc; 4271d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler 4272aff512c8a4582c7f74af57bb09a9979edf92b6d8Tomas Winkler printk(KERN_INFO "Easycap version: "EASYCAP_DRIVER_VERSION "\n"); 4273aff512c8a4582c7f74af57bb09a9979edf92b6d8Tomas Winkler 4274d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler JOT(4, "begins. %i=debug %i=bars %i=gain\n", 4275d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler easycap_debug, easycap_bars, easycap_gain); 4276d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler 4277d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler mutex_init(&mutex_dongle); 4278d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler for (k = 0; k < DONGLE_MANY; k++) { 42793c1fb66ede917d54079a959a95f79777e95920bdTomas Winkler easycapdc60_dongle[k].peasycap = NULL; 4280d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler mutex_init(&easycapdc60_dongle[k].mutex_video); 4281d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler mutex_init(&easycapdc60_dongle[k].mutex_audio); 4282d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler } 4283d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler rc = usb_register(&easycap_usb_driver); 42846911e7e4a6bed8ac7989137387f6a33ef65c2b56Tomas Winkler if (rc) 4285aff512c8a4582c7f74af57bb09a9979edf92b6d8Tomas Winkler printk(KERN_ERR "Easycap: usb_register failed rc=%d\n", rc); 4286d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler 4287d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler return rc; 4288702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 4289702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 4290dbf4805ee6a850e941110b0df1e96049287ecf75Tomas Winklerstatic void __exit easycap_module_exit(void) 4291702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 4292d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler usb_deregister(&easycap_usb_driver); 4293702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 4294702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 4295702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 4296702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomasmodule_init(easycap_module_init); 4297702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomasmodule_exit(easycap_module_exit); 4298702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 4299702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 4300