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); 61aa3e842d2c27acd3e73167eef5a347601639f2cbThomas PetazzoniMODULE_PARM_DESC(ntsc, "NTSC 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); 6998680557f3ce7eadae0ceda4484fd6c7a13ba3beTomas Winklerstatic int field2frame(struct easycap *peasycap); 7098680557f3ce7eadae0ceda4484fd6c7a13ba3beTomas Winklerstatic int redaub(struct easycap *peasycap, 7198680557f3ce7eadae0ceda4484fd6c7a13ba3beTomas Winkler void *pad, void *pex, int much, int more, 7298680557f3ce7eadae0ceda4484fd6c7a13ba3beTomas Winkler u8 mask, u8 margin, bool isuy); 73e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas 745c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winklerconst char *strerror(int err) 755c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler{ 765c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler#define ERRNOSTR(_e) case _e: return # _e 775c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler switch (err) { 785c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler case 0: return "OK"; 795c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(ENOMEM); 805c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(ENODEV); 815c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(ENXIO); 825c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EINVAL); 835c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EAGAIN); 845c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EFBIG); 855c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EPIPE); 865c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EMSGSIZE); 875c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(ENOSPC); 885c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EINPROGRESS); 895c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(ENOSR); 905c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EOVERFLOW); 915c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EPROTO); 925c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EILSEQ); 935c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(ETIMEDOUT); 945c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EOPNOTSUPP); 955c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EPFNOSUPPORT); 965c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EAFNOSUPPORT); 975c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EADDRINUSE); 985c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EADDRNOTAVAIL); 995c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(ENOBUFS); 1005c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EISCONN); 1015c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(ENOTCONN); 1025c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(ESHUTDOWN); 1035c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(ENOENT); 1045c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(ECONNRESET); 1055c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(ETIME); 1065c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(ECOMM); 1075c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EREMOTEIO); 1085c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EXDEV); 1095c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler ERRNOSTR(EPERM); 1105c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler default: return "unknown"; 1115c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler } 1125c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler 1135c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler#undef ERRNOSTR 1145c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler} 1155c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler 116702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/****************************************************************************/ 117e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas/*---------------------------------------------------------------------------*/ 118702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 119268dfede46e24eef55a2ef7a10a462617936771eMike Thomas * THIS ROUTINE DOES NOT DETECT DUPLICATE OCCURRENCES OF POINTER peasycap 120e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas*/ 121e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas/*---------------------------------------------------------------------------*/ 12296bec7dd72511e3c16588d9af52da2cc937f7ea1Tomas Winklerint easycap_isdongle(struct easycap *peasycap) 123e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas{ 124c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int k; 1256888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) 126c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -2; 127c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (k = 0; k < DONGLE_MANY; k++) { 128c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (easycapdc60_dongle[k].peasycap == peasycap) { 129c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->isdongle = k; 130c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return k; 131c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 132e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas } 133c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -1; 134e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas} 135702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ 136d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic int easycap_open(struct inode *inode, struct file *file) 137702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 138c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct video_device *pvideo_device; 139c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct easycap *peasycap; 140c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int rc; 141702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 142c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOT(4, "\n"); 143c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("==========OPEN=========\n"); 144702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 145c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pvideo_device = video_devdata(file); 1466888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pvideo_device) { 147c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: pvideo_device is NULL.\n"); 148c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 149c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 150c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap = (struct easycap *)video_get_drvdata(pvideo_device); 1516888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 152c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap is NULL\n"); 153c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 154c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1556888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap->pusb_device) { 156c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: peasycap->pusb_device is NULL\n"); 157c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 158c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 159101dca425da49edb3093000d72490216fa322911Tomas Winkler 160101dca425da49edb3093000d72490216fa322911Tomas Winkler JOM(16, "peasycap->pusb_device=%p\n", peasycap->pusb_device); 161101dca425da49edb3093000d72490216fa322911Tomas Winkler 162c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler file->private_data = peasycap; 16396bec7dd72511e3c16588d9af52da2cc937f7ea1Tomas Winkler rc = easycap_wakeup_device(peasycap->pusb_device); 164101dca425da49edb3093000d72490216fa322911Tomas Winkler if (rc) { 165c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: wakeup_device() rc = %i\n", rc); 166c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (-ENODEV == rc) 167c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: wakeup_device() returned -ENODEV\n"); 168c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 169c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: wakeup_device() rc = %i\n", rc); 170c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return rc; 171c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 172101dca425da49edb3093000d72490216fa322911Tomas Winkler JOM(8, "wakeup_device() OK\n"); 173c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->input = 0; 174c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = reset(peasycap); 175c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) { 176c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: reset() rc = %i\n", rc); 177c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 178c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 179c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 180f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas} 181d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler 182f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*****************************************************************************/ 183f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*---------------------------------------------------------------------------*/ 184f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/* 185f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * RESET THE HARDWARE TO ITS REFERENCE STATE. 186f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * 187f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * THIS ROUTINE MAY BE CALLED REPEATEDLY IF easycap_complete() DETECTS 188f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * A BAD VIDEO FRAME SIZE. 189f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas*/ 190f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*---------------------------------------------------------------------------*/ 191d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic int reset(struct easycap *peasycap) 192f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas{ 193c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct easycap_standard const *peasycap_standard; 194fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler int fmtidx, input, rate; 195c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bool ntsc, other; 196fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler int rc; 197f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas 1986888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 199c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap is NULL\n"); 200c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 201c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 202c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler input = peasycap->input; 203f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas 204f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*---------------------------------------------------------------------------*/ 205f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/* 206ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * IF THE SAA7113H HAS ALREADY ACQUIRED SYNC, USE ITS HARDWARE-DETECTED 207f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * FIELD FREQUENCY TO DISTINGUISH NTSC FROM PAL. THIS IS ESSENTIAL FOR 208f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * gstreamer AND OTHER USERSPACE PROGRAMS WHICH MAY NOT ATTEMPT TO INITIATE 209f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * A SWITCH BETWEEN PAL AND NTSC. 210f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * 211f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * FUNCTION ready_saa() MAY REQUIRE A SUBSTANTIAL FRACTION OF A SECOND TO 212f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * COMPLETE, SO SHOULD NOT BE INVOKED WITHOUT GOOD REASON. 213f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas*/ 214f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*---------------------------------------------------------------------------*/ 215c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler other = false; 216c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "peasycap->ntsc=%d\n", peasycap->ntsc); 217c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 218c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rate = ready_saa(peasycap->pusb_device); 219fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler if (rate < 0) { 220c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "not ready to capture after %i ms ...\n", PATIENCE); 221fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler ntsc = !peasycap->ntsc; 222fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler JOM(8, "... trying %s ..\n", ntsc ? "NTSC" : "PAL"); 223fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler rc = setup_stk(peasycap->pusb_device, ntsc); 224fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler if (rc) { 225fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler SAM("ERROR: setup_stk() rc = %i\n", rc); 226fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler return -EFAULT; 227fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler } 228fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler rc = setup_saa(peasycap->pusb_device, ntsc); 229fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler if (rc) { 230fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler SAM("ERROR: setup_saa() rc = %i\n", rc); 231fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler return -EFAULT; 232fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler } 233fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler 234fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler rate = ready_saa(peasycap->pusb_device); 235fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler if (rate < 0) { 236fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler JOM(8, "not ready to capture after %i ms\n", PATIENCE); 237fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler JOM(8, "... saa register 0x1F has 0x%02X\n", 238c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler read_saa(peasycap->pusb_device, 0x1F)); 239fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler ntsc = peasycap->ntsc; 240c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 241c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "... success at second try: %i=rate\n", rate); 242c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ntsc = (0 < (rate/2)) ? true : false ; 243c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler other = true; 244c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 245f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } else { 246c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "... success at first try: %i=rate\n", rate); 247c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ntsc = (0 < rate/2) ? true : false ; 248c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 249c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "ntsc=%d\n", ntsc); 250c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler/*---------------------------------------------------------------------------*/ 251c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 252c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = setup_stk(peasycap->pusb_device, ntsc); 253fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler if (rc) { 254c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: setup_stk() rc = %i\n", rc); 255c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 256c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 257c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = setup_saa(peasycap->pusb_device, ntsc); 258fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler if (rc) { 259c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: setup_saa() rc = %i\n", rc); 260c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 261f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 262702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 263fd1b821c31f8a4588cc874721e3d17a47b460380Tomas Winkler memset(peasycap->merit, 0, sizeof(peasycap->merit)); 264c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 265c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_eof = 0; 266c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->audio_eof = 0; 267f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*---------------------------------------------------------------------------*/ 268f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/* 269f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * RESTORE INPUT AND FORCE REFRESH OF STANDARD, FORMAT, ETC. 270f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * 271f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * WHILE THIS PROCEDURE IS IN PROGRESS, SOME IOCTL COMMANDS WILL RETURN -EBUSY. 272f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas*/ 273f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*---------------------------------------------------------------------------*/ 274c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->input = -8192; 275c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->standard_offset = -8192; 276c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler fmtidx = ntsc ? NTSC_M : PAL_BGHIN; 277c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (other) { 278c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap_standard = &easycap_standard[0]; 279c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (0xFFFF != peasycap_standard->mask) { 280c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (fmtidx == peasycap_standard->v4l2_standard.index) { 2811dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler peasycap->inputset[input].standard_offset = 282c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap_standard - easycap_standard; 283f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas break; 284f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 285c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap_standard++; 286f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 287c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0xFFFF == peasycap_standard->mask) { 288c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: standard not found\n"); 289c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EINVAL; 290c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 291c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=peasycap->inputset[%i].standard_offset\n", 292c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->inputset[input].standard_offset, input); 293f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 294c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->format_offset = -8192; 295c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->brightness = -8192; 296c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->contrast = -8192; 297c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->saturation = -8192; 298c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->hue = -8192; 299f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas 30096bec7dd72511e3c16588d9af52da2cc937f7ea1Tomas Winkler rc = easycap_newinput(peasycap, input); 301702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 302c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) { 303c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: newinput(.,%i) rc = %i\n", rc, input); 304c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 305c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 306f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas JOM(4, "restored input, standard and format\n"); 307c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 308c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "true=peasycap->ntsc %d\n", peasycap->ntsc); 309c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 310c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 > peasycap->input) { 311c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=peasycap->input\n", peasycap->input); 312c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ENOENT; 313c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 314c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 > peasycap->standard_offset) { 315c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=peasycap->standard_offset\n", 316c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->standard_offset); 317c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ENOENT; 318c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 319c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 > peasycap->format_offset) { 320c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=peasycap->format_offset\n", 321c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->format_offset); 322c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ENOENT; 323c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 324c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 > peasycap->brightness) { 325c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=peasycap->brightness\n", 326c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->brightness); 327c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ENOENT; 328c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 329c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 > peasycap->contrast) { 330c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=peasycap->contrast\n", peasycap->contrast); 331c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ENOENT; 332c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 333c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 > peasycap->saturation) { 334c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=peasycap->saturation\n", 335c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->saturation); 336c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ENOENT; 337c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 338c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 > peasycap->hue) { 339c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=peasycap->hue\n", peasycap->hue); 340c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ENOENT; 341c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 342c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 343f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas} 344f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*****************************************************************************/ 345f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*---------------------------------------------------------------------------*/ 346f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/* 347f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * IF THE REQUESTED INPUT IS THE SAME AS THE EXISTING INPUT, DO NOTHING. 348f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * OTHERWISE: 349f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * KILL URBS, CLEAR FIELD AND FRAME BUFFERS AND RESET THEIR 350f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * _read AND _fill POINTERS. 351f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * SELECT THE NEW INPUT. 352f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * ADJUST THE STANDARD, FORMAT, BRIGHTNESS, CONTRAST, SATURATION AND HUE 353f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * ON THE BASIS OF INFORMATION IN STRUCTURE easycap.inputset[input]. 354f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * RESUBMIT THE URBS IF STREAMING WAS ALREADY IN PROGRESS. 355f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * 356f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * NOTE: 357f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * THIS ROUTINE MAY BE CALLED FREQUENTLY BY ZONEMINDER VIA IOCTL, 358f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * SO IT SHOULD WRITE ONLY SPARINGLY TO THE LOGFILE. 359f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas*/ 360f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*---------------------------------------------------------------------------*/ 36196bec7dd72511e3c16588d9af52da2cc937f7ea1Tomas Winklerint easycap_newinput(struct easycap *peasycap, int input) 362f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas{ 363c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int rc, k, m, mood, off; 364c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int inputnow, video_idlenow, audio_idlenow; 365c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bool resubmit; 366f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas 3676888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 368c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap is NULL\n"); 369c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 370c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 371c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=input sought\n", input); 372702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 373c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 > input && INPUT_MANY <= input) 374c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ENOENT; 375c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler inputnow = peasycap->input; 376c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (input == inputnow) 377c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 378702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 379f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/* 380f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * IF STREAMING IS IN PROGRESS THE URBS ARE KILLED AT THIS 381f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * STAGE AND WILL BE RESUBMITTED PRIOR TO EXIT FROM THE ROUTINE. 382f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * IF NO STREAMING IS IN PROGRESS NO URBS WILL BE SUBMITTED BY THE 383f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * ROUTINE. 384f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas*/ 385f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*---------------------------------------------------------------------------*/ 386c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler video_idlenow = peasycap->video_idle; 387c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler audio_idlenow = peasycap->audio_idle; 388f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas 389c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_idle = 1; 390c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->audio_idle = 1; 391c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->video_isoc_streaming) { 392c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler resubmit = true; 3938b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler easycap_video_kill_urbs(peasycap); 394c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 395c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler resubmit = false; 396c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 397f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*---------------------------------------------------------------------------*/ 3986888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap->pusb_device) { 399c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: peasycap->pusb_device is NULL\n"); 400c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ENODEV; 401c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 402c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = usb_set_interface(peasycap->pusb_device, 403c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_interface, 404c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_altsetting_off); 405c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) { 406c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: usb_set_interface() rc = %i\n", rc); 407c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 408c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 409c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = stop_100(peasycap->pusb_device); 410c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) { 411c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: stop_100() rc = %i\n", rc); 412c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 413c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 414c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (k = 0; k < FIELD_BUFFER_MANY; k++) { 415c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) 416c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler memset(peasycap->field_buffer[k][m].pgo, 0, PAGE_SIZE); 417c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 418c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (k = 0; k < FRAME_BUFFER_MANY; k++) { 419c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) 420c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler memset(peasycap->frame_buffer[k][m].pgo, 0, PAGE_SIZE); 421c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 422c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_page = 0; 423c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_read = 0; 424c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_fill = 0; 425c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 426c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->frame_read = 0; 427c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->frame_fill = 0; 428c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (k = 0; k < peasycap->input; k++) { 429c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap->frame_fill)++; 430c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->frame_buffer_many <= peasycap->frame_fill) 431c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->frame_fill = 0; 432c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 433c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->input = input; 434c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler select_input(peasycap->pusb_device, peasycap->input, 9); 435f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas/*---------------------------------------------------------------------------*/ 436c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (input == peasycap->inputset[input].input) { 437c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler off = peasycap->inputset[input].standard_offset; 438c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (off != peasycap->standard_offset) { 439c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = adjust_standard(peasycap, 440f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas easycap_standard[off].v4l2_standard.id); 441c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) { 442c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: adjust_standard() rc = %i\n", rc); 443c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 444c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 445c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=peasycap->standard_offset\n", 446c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->standard_offset); 447c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 448c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=peasycap->standard_offset unchanged\n", 449f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas peasycap->standard_offset); 450f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 451c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler off = peasycap->inputset[input].format_offset; 452c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (off != peasycap->format_offset) { 453c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct v4l2_pix_format *pix = 454c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler &easycap_format[off].v4l2_format.fmt.pix; 455c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = adjust_format(peasycap, 456c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pix->width, pix->height, 457c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pix->pixelformat, pix->field, false); 458c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 > rc) { 459c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: adjust_format() rc = %i\n", rc); 460c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 461c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 462c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=peasycap->format_offset\n", 463c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->format_offset); 464c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 465c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=peasycap->format_offset unchanged\n", 466c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->format_offset); 467f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 468c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mood = peasycap->inputset[input].brightness; 469c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (mood != peasycap->brightness) { 470c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = adjust_brightness(peasycap, mood); 471c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) { 472c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: adjust_brightness rc = %i\n", rc); 473c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 474c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 475c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=peasycap->brightness\n", 476c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->brightness); 477f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 478c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mood = peasycap->inputset[input].contrast; 479c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (mood != peasycap->contrast) { 480c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = adjust_contrast(peasycap, mood); 481c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) { 482c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: adjust_contrast rc = %i\n", rc); 483c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 484c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 485c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=peasycap->contrast\n", peasycap->contrast); 486f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 487c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mood = peasycap->inputset[input].saturation; 488c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (mood != peasycap->saturation) { 489c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = adjust_saturation(peasycap, mood); 490c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) { 491c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: adjust_saturation rc = %i\n", rc); 492c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 493c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 494c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=peasycap->saturation\n", 495c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->saturation); 496c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 497c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mood = peasycap->inputset[input].hue; 498c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (mood != peasycap->hue) { 499c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = adjust_hue(peasycap, mood); 500c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) { 501c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: adjust_hue rc = %i\n", rc); 502c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 503c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 504c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=peasycap->hue\n", peasycap->hue); 505f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 506c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 507c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: easycap.inputset[%i] unpopulated\n", input); 508c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ENOENT; 509f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 510702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 5116888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap->pusb_device) { 512c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: peasycap->pusb_device is NULL\n"); 513c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ENODEV; 514c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 515c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = usb_set_interface(peasycap->pusb_device, 516c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_interface, 517c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_altsetting_on); 518c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) { 519c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: usb_set_interface() rc = %i\n", rc); 520c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 521c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 522c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = start_100(peasycap->pusb_device); 523c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) { 524c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: start_100() rc = %i\n", rc); 525c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 526c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 52727d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (resubmit) 52896bec7dd72511e3c16588d9af52da2cc937f7ea1Tomas Winkler easycap_video_submit_urbs(peasycap); 529f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas 530c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_isoc_sequence = VIDEO_ISOC_BUFFER_MANY - 1; 531c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_idle = video_idlenow; 532c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->audio_idle = audio_idlenow; 533c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_junk = 0; 534702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 535c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 536702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 537702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 53896bec7dd72511e3c16588d9af52da2cc937f7ea1Tomas Winklerint easycap_video_submit_urbs(struct easycap *peasycap) 539702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 540c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct data_urb *pdata_urb; 541c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct urb *purb; 542c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct list_head *plist_head; 543c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int j, isbad, nospc, m, rc; 544c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int isbuf; 545e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas 5466888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 547c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap is NULL\n"); 548c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 549c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 550c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 5516888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap->purb_video_head) { 552c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap->urb_video_head uninitialized\n"); 553c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 554c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 5556888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap->pusb_device) { 556c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap->pusb_device is NULL\n"); 557c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ENODEV; 558c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 559c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!peasycap->video_isoc_streaming) { 560c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "submission of all video urbs\n"); 561c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isbad = 0; nospc = 0; m = 0; 562c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler list_for_each(plist_head, (peasycap->purb_video_head)) { 563c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pdata_urb = list_entry(plist_head, 564c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct data_urb, list_head); 565c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (pdata_urb && pdata_urb->purb) { 566c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler purb = pdata_urb->purb; 567702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas isbuf = pdata_urb->isbuf; 568702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas purb->interval = 1; 569702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas purb->dev = peasycap->pusb_device; 5701dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler purb->pipe = 5711dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler usb_rcvisocpipe(peasycap->pusb_device, 572702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas peasycap->video_endpointnumber); 573702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas purb->transfer_flags = URB_ISO_ASAP; 5741dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler purb->transfer_buffer = 575702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas peasycap->video_isoc_buffer[isbuf].pgo; 5761dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler purb->transfer_buffer_length = 577702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas peasycap->video_isoc_buffer_size; 578702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas purb->complete = easycap_complete; 579702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas purb->context = peasycap; 580702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas purb->start_frame = 0; 5811dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler purb->number_of_packets = 582702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas peasycap->video_isoc_framesperdesc; 583702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 584c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (j = 0; j < peasycap->video_isoc_framesperdesc; j++) { 585c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler purb->iso_frame_desc[j]. offset = 586c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler j * peasycap->video_isoc_maxframesize; 587c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler purb->iso_frame_desc[j]. length = 588c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_isoc_maxframesize; 589c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 590702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 591702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas rc = usb_submit_urb(purb, GFP_KERNEL); 5925c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler if (rc) { 593702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas isbad++; 5941dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler SAM("ERROR: usb_submit_urb() failed " 595c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "for urb with rc:-%s\n", 5965c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler strerror(rc)); 5975c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler if (rc == -ENOSPC) 598e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas nospc++; 599702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } else { 600702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas m++; 601702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 602702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } else { 6035c0c6c395ea8ad2f831c0717f67f957ba84550adTomas Winkler isbad++; 604702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 605702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 606c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (nospc) { 607c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc); 608c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("..... possibly inadequate USB bandwidth\n"); 609c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_eof = 1; 610c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 611e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas 6128b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler if (isbad) 6138b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler easycap_video_kill_urbs(peasycap); 6148b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler else 615c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_isoc_streaming = 1; 616702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } else { 617c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "already streaming video urbs\n"); 618702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 619c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 620702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 621702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 6228b1fad2f046fb825046fee3a41885a70123de988Tomas Winklerint easycap_audio_kill_urbs(struct easycap *peasycap) 623702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 624c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int m; 625c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct list_head *plist_head; 626c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct data_urb *pdata_urb; 627702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 6288b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler if (!peasycap->audio_isoc_streaming) 6298b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler return 0; 6308b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler 6318b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler if (!peasycap->purb_audio_head) { 6328b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler SAM("ERROR: peasycap->purb_audio_head is NULL\n"); 633c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 634c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 6358b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler 6368b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler peasycap->audio_isoc_streaming = 0; 6378b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler m = 0; 6388b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler list_for_each(plist_head, peasycap->purb_audio_head) { 6398b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler pdata_urb = list_entry(plist_head, struct data_urb, list_head); 6408b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler if (pdata_urb && pdata_urb->purb) { 6418b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler usb_kill_urb(pdata_urb->purb); 6428b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler m++; 6438b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler } 644c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 6458b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler 6468b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler JOM(4, "%i audio urbs killed\n", m); 6478b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler 6488b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler return 0; 6498b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler} 6508b1fad2f046fb825046fee3a41885a70123de988Tomas Winklerint easycap_video_kill_urbs(struct easycap *peasycap) 6518b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler{ 6528b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler int m; 6538b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler struct list_head *plist_head; 6548b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler struct data_urb *pdata_urb; 6558b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler 6568b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler if (!peasycap->video_isoc_streaming) 6578b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler return 0; 6588b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler 659c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!peasycap->purb_video_head) { 660e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas SAM("ERROR: peasycap->purb_video_head is NULL\n"); 661702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas return -EFAULT; 662702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 663c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 664c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_isoc_streaming = 0; 665c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "killing video urbs\n"); 666c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler m = 0; 667c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler list_for_each(plist_head, (peasycap->purb_video_head)) { 668c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pdata_urb = list_entry(plist_head, struct data_urb, list_head); 669c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (pdata_urb && pdata_urb->purb) { 670c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler usb_kill_urb(pdata_urb->purb); 671c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler m++; 672c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 673c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 674c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "%i video urbs killed\n", m); 675c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 676c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 677702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 678702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/****************************************************************************/ 679702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ 680702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*--------------------------------------------------------------------------*/ 681d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic int easycap_open_noinode(struct file *file) 682d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler{ 683d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler return easycap_open(NULL, file); 684d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler} 685d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler 686d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic int videodev_release(struct video_device *pvideo_device) 687702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 688c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct easycap *peasycap; 689702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 690c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap = video_get_drvdata(pvideo_device); 6916888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 692c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap is NULL\n"); 693c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ending unsuccessfully\n"); 694c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 695c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 6968b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler if (easycap_video_kill_urbs(peasycap)) { 6978b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler SAM("ERROR: easycap_video_kill_urbs() failed\n"); 698c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 699c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 700c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "ending successfully\n"); 701c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 702702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 703e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ 704e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas/*****************************************************************************/ 705702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*--------------------------------------------------------------------------*/ 706702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 707ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * THIS FUNCTION IS CALLED FROM WITHIN easycap_usb_disconnect() AND IS 708ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * PROTECTED BY SEMAPHORES SET AND CLEARED BY easycap_usb_disconnect(). 709ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * 710ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * BY THIS STAGE THE DEVICE HAS ALREADY BEEN PHYSICALLY UNPLUGGED, SO 711ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * peasycap->pusb_device IS NO LONGER VALID. 712702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 713702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 714d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic void easycap_delete(struct kref *pkref) 715702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 716c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct easycap *peasycap; 717c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct data_urb *pdata_urb; 718c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct list_head *plist_head, *plist_next; 719c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int k, m, gone, kd; 720c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int allocation_video_urb; 721c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int allocation_video_page; 722c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int allocation_video_struct; 723c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int allocation_audio_urb; 724c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int allocation_audio_page; 725c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int allocation_audio_struct; 726c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int registered_video, registered_audio; 727c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 728c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap = container_of(pkref, struct easycap, kref); 7296888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 730c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: peasycap is NULL: cannot perform deletions\n"); 731c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 732c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 73396bec7dd72511e3c16588d9af52da2cc937f7ea1Tomas Winkler kd = easycap_isdongle(peasycap); 734702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 735702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 736702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * FREE VIDEO. 737702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 738702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 7396888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (peasycap->purb_video_head) { 740c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler m = 0; 7418b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler list_for_each(plist_head, peasycap->purb_video_head) { 742c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pdata_urb = list_entry(plist_head, 743c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct data_urb, list_head); 7448b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler if (pdata_urb && pdata_urb->purb) { 7458b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler usb_free_urb(pdata_urb->purb); 7468b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler pdata_urb->purb = NULL; 7478b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler peasycap->allocation_video_urb--; 7488b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler m++; 749702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 750702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 751702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 752c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "%i video urbs freed\n", m); 753702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 754c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "freeing video data_urb structures.\n"); 755c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler m = 0; 756c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler list_for_each_safe(plist_head, plist_next, 757c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->purb_video_head) { 758c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pdata_urb = list_entry(plist_head, 759c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct data_urb, list_head); 760c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (pdata_urb) { 761c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->allocation_video_struct -= 762702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas sizeof(struct data_urb); 763c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler kfree(pdata_urb); 764c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler m++; 765c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 766702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 767c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "%i video data_urb structures freed\n", m); 768c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "setting peasycap->purb_video_head=NULL\n"); 769c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->purb_video_head = NULL; 770702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 771702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 772c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "freeing video isoc buffers.\n"); 773c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler m = 0; 774c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { 775c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->video_isoc_buffer[k].pgo) { 776c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler free_pages((unsigned long) 777c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_isoc_buffer[k].pgo, 778c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler VIDEO_ISOC_ORDER); 779c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_isoc_buffer[k].pgo = NULL; 780c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->allocation_video_page -= 781c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler BIT(VIDEO_ISOC_ORDER); 782c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler m++; 783c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 784702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 785c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "isoc video buffers freed: %i pages\n", 786c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler m * (0x01 << VIDEO_ISOC_ORDER)); 787c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler/*---------------------------------------------------------------------------*/ 788c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "freeing video field buffers.\n"); 789c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler gone = 0; 790c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (k = 0; k < FIELD_BUFFER_MANY; k++) { 791c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) { 7926888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (peasycap->field_buffer[k][m].pgo) { 793c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler free_page((unsigned long) 794c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_buffer[k][m].pgo); 795c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_buffer[k][m].pgo = NULL; 796c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->allocation_video_page -= 1; 797c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler gone++; 798c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 799702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 800702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 801c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "video field buffers freed: %i pages\n", gone); 802c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler/*---------------------------------------------------------------------------*/ 803c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "freeing video frame buffers.\n"); 804c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler gone = 0; 805c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (k = 0; k < FRAME_BUFFER_MANY; k++) { 806c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) { 8076888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (peasycap->frame_buffer[k][m].pgo) { 808c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler free_page((unsigned long) 809c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->frame_buffer[k][m].pgo); 810c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->frame_buffer[k][m].pgo = NULL; 811c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->allocation_video_page -= 1; 812c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler gone++; 813c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 814702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 815702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 816c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "video frame buffers freed: %i pages\n", gone); 817702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 818702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 819702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * FREE AUDIO. 820702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 821702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 8226888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (peasycap->purb_audio_head) { 823c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "freeing audio urbs\n"); 824c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler m = 0; 825c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler list_for_each(plist_head, (peasycap->purb_audio_head)) { 826c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pdata_urb = list_entry(plist_head, 827c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct data_urb, list_head); 8288b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler if (pdata_urb && pdata_urb->purb) { 8298b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler usb_free_urb(pdata_urb->purb); 8308b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler pdata_urb->purb = NULL; 8318b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler peasycap->allocation_audio_urb--; 8328b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler m++; 833c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 834c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 835c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "%i audio urbs freed\n", m); 836c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler/*---------------------------------------------------------------------------*/ 837c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "freeing audio data_urb structures.\n"); 838c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler m = 0; 839c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler list_for_each_safe(plist_head, plist_next, 840c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->purb_audio_head) { 841c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pdata_urb = list_entry(plist_head, 842c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct data_urb, list_head); 843c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (pdata_urb) { 844c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->allocation_audio_struct -= 845c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler sizeof(struct data_urb); 846c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler kfree(pdata_urb); 847702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas m++; 848702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 849702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 850c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "%i audio data_urb structures freed\n", m); 851c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "setting peasycap->purb_audio_head=NULL\n"); 852c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->purb_audio_head = NULL; 853702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 854702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 855c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "freeing audio isoc buffers.\n"); 856702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas m = 0; 857c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { 8586888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (peasycap->audio_isoc_buffer[k].pgo) { 859c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler free_pages((unsigned long) 860c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap->audio_isoc_buffer[k].pgo), 861c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler AUDIO_ISOC_ORDER); 862c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->audio_isoc_buffer[k].pgo = NULL; 863c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->allocation_audio_page -= 864c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler BIT(AUDIO_ISOC_ORDER); 865702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas m++; 866702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 867702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 868c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "easyoss_delete(): isoc audio buffers freed: %i pages\n", 869702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas m * (0x01 << AUDIO_ISOC_ORDER)); 870702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 871c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "freeing easycap structure.\n"); 872c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler allocation_video_urb = peasycap->allocation_video_urb; 873c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler allocation_video_page = peasycap->allocation_video_page; 874c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler allocation_video_struct = peasycap->allocation_video_struct; 875c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler registered_video = peasycap->registered_video; 876c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler allocation_audio_urb = peasycap->allocation_audio_urb; 877c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler allocation_audio_page = peasycap->allocation_audio_page; 878c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler allocation_audio_struct = peasycap->allocation_audio_struct; 879c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler registered_audio = peasycap->registered_audio; 880c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 881c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 <= kd && DONGLE_MANY > kd) { 882c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (mutex_lock_interruptible(&mutex_dongle)) { 883c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: cannot down mutex_dongle\n"); 884c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 885c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "locked mutex_dongle\n"); 886c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler easycapdc60_dongle[kd].peasycap = NULL; 887c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mutex_unlock(&mutex_dongle); 888c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "unlocked mutex_dongle\n"); 889c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOT(4, " null-->dongle[%i].peasycap\n", kd); 890c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler allocation_video_struct -= sizeof(struct easycap); 891c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 892a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas } else { 893c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: cannot purge dongle[].peasycap"); 894c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 89538d0cffefd3daaad6bc58a6212d16edeaa8ee1f0Dan Carpenter 89638d0cffefd3daaad6bc58a6212d16edeaa8ee1f0Dan Carpenter kfree(peasycap); 89738d0cffefd3daaad6bc58a6212d16edeaa8ee1f0Dan Carpenter 898702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 899c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("%8i=video urbs after all deletions\n", allocation_video_urb); 900c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("%8i=video pages after all deletions\n", allocation_video_page); 901c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("%8i=video structs after all deletions\n", allocation_video_struct); 902c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("%8i=video devices after all deletions\n", registered_video); 903c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("%8i=audio urbs after all deletions\n", allocation_audio_urb); 904c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("%8i=audio pages after all deletions\n", allocation_audio_page); 905c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("%8i=audio structs after all deletions\n", allocation_audio_struct); 906c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("%8i=audio devices after all deletions\n", registered_audio); 907c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 908c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOT(4, "ending.\n"); 909c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 910702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 911702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 912d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic unsigned int easycap_poll(struct file *file, poll_table *wait) 913702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 914c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct easycap *peasycap; 915c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int rc, kd; 916702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 917c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOT(8, "\n"); 918702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 919c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (NULL == ((poll_table *)wait)) 920c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOT(8, "WARNING: poll table pointer is NULL ... continuing\n"); 9216888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!file) { 922c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: file pointer is NULL\n"); 923ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas return -ERESTARTSYS; 924ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas } 925ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas peasycap = file->private_data; 9266888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 927ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas SAY("ERROR: peasycap is NULL\n"); 928c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 929ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas } 9306888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap->pusb_device) { 931c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap->pusb_device is NULL\n"); 932c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 933ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas } 934c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler/*---------------------------------------------------------------------------*/ 93596bec7dd72511e3c16588d9af52da2cc937f7ea1Tomas Winkler kd = easycap_isdongle(peasycap); 936c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 <= kd && DONGLE_MANY > kd) { 937c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) { 938c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: cannot down dongle[%i].mutex_video\n", kd); 939c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ERESTARTSYS; 940c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 941c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "locked dongle[%i].mutex_video\n", kd); 942c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* 943c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER 944c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * peasycap, IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. 945c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * IF NECESSARY, BAIL OUT. 946c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler */ 94796bec7dd72511e3c16588d9af52da2cc937f7ea1Tomas Winkler if (kd != easycap_isdongle(peasycap)) { 94822f88fcf407933321d08c45520fbeffca70b05d1Alexey Khoroshilov mutex_unlock(&easycapdc60_dongle[kd].mutex_video); 949c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ERESTARTSYS; 95022f88fcf407933321d08c45520fbeffca70b05d1Alexey Khoroshilov } 9516888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!file) { 952c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: file is NULL\n"); 953c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mutex_unlock(&easycapdc60_dongle[kd].mutex_video); 954c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ERESTARTSYS; 955c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 956c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap = file->private_data; 9576888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 958c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap is NULL\n"); 959c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mutex_unlock(&easycapdc60_dongle[kd].mutex_video); 960c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ERESTARTSYS; 961c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 9626888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap->pusb_device) { 963c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: peasycap->pusb_device is NULL\n"); 964c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mutex_unlock(&easycapdc60_dongle[kd].mutex_video); 965c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ERESTARTSYS; 966c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 967c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else 968ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas /* 969ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap 970ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * BEFORE THE ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL 971ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * HAVE FAILED. BAIL OUT. 972ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas */ 973c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -ERESTARTSYS; 974c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler/*---------------------------------------------------------------------------*/ 97596bec7dd72511e3c16588d9af52da2cc937f7ea1Tomas Winkler rc = easycap_video_dqbuf(peasycap, 0); 976c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->polled = 1; 977c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mutex_unlock(&easycapdc60_dongle[kd].mutex_video); 978101dca425da49edb3093000d72490216fa322911Tomas Winkler if (rc) 979c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return POLLERR; 980101dca425da49edb3093000d72490216fa322911Tomas Winkler 981101dca425da49edb3093000d72490216fa322911Tomas Winkler return POLLIN | POLLRDNORM; 982101dca425da49edb3093000d72490216fa322911Tomas Winkler} 983702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 984702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 985702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 986702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * IF mode IS NONZERO THIS ROUTINE RETURNS -EAGAIN RATHER THAN BLOCKING. 987702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 988702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 98996bec7dd72511e3c16588d9af52da2cc937f7ea1Tomas Winklerint easycap_video_dqbuf(struct easycap *peasycap, int mode) 990702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 991c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int input, ifield, miss, rc; 992702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 993702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 9946888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 995c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap is NULL\n"); 996c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 997c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 9986888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap->pusb_device) { 999c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap->pusb_device is NULL\n"); 1000c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 1001c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1002c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ifield = 0; 1003c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=ifield\n", ifield); 1004702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1005702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 1006849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas * CHECK FOR LOST INPUT SIGNAL. 1007849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas * 1008849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas * FOR THE FOUR-CVBS EasyCAP, THIS DOES NOT WORK AS EXPECTED. 1009ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * IF INPUT 0 IS PRESENT AND SYNC ACQUIRED, UNPLUGGING INPUT 4 DOES NOT 1010ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * RESULT IN SETTING BIT 0x40 ON REGISTER 0x1F, PRESUMABLY BECAUSE THERE 1011ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * IS FLYWHEELING ON INPUT 0. THE UPSHOT IS: 1012849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas * 1013849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas * INPUT 0 PLUGGED, INPUT 4 PLUGGED => SCREEN 0 OK, SCREEN 4 OK 1014849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas * INPUT 0 PLUGGED, INPUT 4 UNPLUGGED => SCREEN 0 OK, SCREEN 4 BLACK 1015849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas * INPUT 0 UNPLUGGED, INPUT 4 PLUGGED => SCREEN 0 BARS, SCREEN 4 OK 1016849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas * INPUT 0 UNPLUGGED, INPUT 4 UNPLUGGED => SCREEN 0 BARS, SCREEN 4 BARS 1017849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas*/ 1018849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas/*---------------------------------------------------------------------------*/ 1019c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler input = peasycap->input; 1020c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 <= input && INPUT_MANY > input) { 1021c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = read_saa(peasycap->pusb_device, 0x1F); 1022c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 <= rc) { 1023c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc & 0x40) 1024c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->lost[input] += 1; 1025c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1026c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->lost[input] -= 2; 1027849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas 1028c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 > peasycap->lost[input]) 1029c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->lost[input] = 0; 1030c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else if ((2 * VIDEO_LOST_TOLERATE) < peasycap->lost[input]) 1031c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->lost[input] = (2 * VIDEO_LOST_TOLERATE); 1032c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1033849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas } 1034849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas/*---------------------------------------------------------------------------*/ 1035849322a0f114e52d05e16fe8349843c980cff2c6Mike Thomas/* 103640b8d50ac98f8c8779aea7459f805e5a69fdb726Mike Thomas * WAIT FOR FIELD ifield (0 => TOP, 1 => BOTTOM) 1037702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 1038702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1039c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler miss = 0; 1040c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while ((peasycap->field_read == peasycap->field_fill) || 1041c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (0 != (0xFF00 & peasycap->field_buffer 10421dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler [peasycap->field_read][0].kount)) || 1043c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (ifield != (0x00FF & peasycap->field_buffer 1044702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas [peasycap->field_read][0].kount))) { 1045c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (mode) 1046c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EAGAIN; 1047702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1048a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler JOM(8, "first wait on wq_video, %i=field_read %i=field_fill\n", 1049a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->field_read, peasycap->field_fill); 1050c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 1051c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 != (wait_event_interruptible(peasycap->wq_video, 1052c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap->video_idle || peasycap->video_eof || 1053c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ((peasycap->field_read != peasycap->field_fill) && 1054a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler (0 == (0xFF00 & peasycap->field_buffer[peasycap->field_read][0].kount)) && 1055a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler (ifield == (0x00FF & peasycap->field_buffer[peasycap->field_read][0].kount))))))) { 1056c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("aborted by signal\n"); 1057c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EIO; 1058a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler } 1059c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->video_idle) { 1060c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=peasycap->video_idle returning -EAGAIN\n", 1061c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_idle); 1062f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas return -EAGAIN; 1063f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 1064c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->video_eof) { 1065c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=peasycap->video_eof\n", peasycap->video_eof); 1066c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler #if defined(PERSEVERE) 1067c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (1 == peasycap->status) { 1068c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "persevering ...\n"); 1069c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_eof = 0; 1070c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->audio_eof = 0; 1071c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 != reset(peasycap)) { 1072c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, " ... failed returning -EIO\n"); 1073c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_eof = 1; 1074c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->audio_eof = 1; 10758b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler easycap_video_kill_urbs(peasycap); 1076c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EIO; 1077c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1078c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->status = 0; 1079c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, " ... OK returning -EAGAIN\n"); 1080c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EAGAIN; 1081c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1082c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler #endif /*PERSEVERE*/ 1083c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_eof = 1; 1084c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->audio_eof = 1; 10858b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler easycap_video_kill_urbs(peasycap); 1086c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "returning -EIO\n"); 1087c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EIO; 1088c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1089a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler miss++; 1090702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1091c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "first awakening on wq_video after %i waits\n", miss); 1092702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1093c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = field2frame(peasycap); 1094c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) 1095c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: field2frame() rc = %i\n", rc); 1096702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1097702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 109840b8d50ac98f8c8779aea7459f805e5a69fdb726Mike Thomas * WAIT FOR THE OTHER FIELD 1099702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 1100702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1101c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (ifield) 1102c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ifield = 0; 1103c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1104c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ifield = 1; 1105c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler miss = 0; 1106c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while ((peasycap->field_read == peasycap->field_fill) || 1107a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler (0 != (0xFF00 & peasycap->field_buffer[peasycap->field_read][0].kount)) || 1108a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler (ifield != (0x00FF & peasycap->field_buffer[peasycap->field_read][0].kount))) { 1109c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (mode) 1110c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EAGAIN; 1111702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1112c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "second wait on wq_video %i=field_read %i=field_fill\n", 1113702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas peasycap->field_read, peasycap->field_fill); 1114c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 != (wait_event_interruptible(peasycap->wq_video, 11151dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler (peasycap->video_idle || peasycap->video_eof || 11161dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler ((peasycap->field_read != peasycap->field_fill) && 1117a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler (0 == (0xFF00 & peasycap->field_buffer[peasycap->field_read][0].kount)) && 1118a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler (ifield == (0x00FF & peasycap->field_buffer[peasycap->field_read][0].kount))))))) { 1119c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("aborted by signal\n"); 1120c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EIO; 1121c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1122c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->video_idle) { 1123c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=peasycap->video_idle returning -EAGAIN\n", 1124f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas peasycap->video_idle); 1125f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas return -EAGAIN; 1126f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 1127c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->video_eof) { 1128c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=peasycap->video_eof\n", peasycap->video_eof); 1129a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler#if defined(PERSEVERE) 1130c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (1 == peasycap->status) { 1131c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "persevering ...\n"); 1132c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_eof = 0; 1133c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->audio_eof = 0; 1134c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 != reset(peasycap)) { 1135c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, " ... failed returning -EIO\n"); 1136c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_eof = 1; 1137c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->audio_eof = 1; 11388b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler easycap_video_kill_urbs(peasycap); 1139c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EIO; 1140c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1141c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->status = 0; 1142c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, " ... OK ... returning -EAGAIN\n"); 1143c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EAGAIN; 1144c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1145a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler#endif /*PERSEVERE*/ 1146c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_eof = 1; 1147c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->audio_eof = 1; 11488b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler easycap_video_kill_urbs(peasycap); 1149c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "returning -EIO\n"); 1150c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EIO; 1151c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1152a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler miss++; 1153702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1154c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "second awakening on wq_video after %i waits\n", miss); 1155702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1156c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = field2frame(peasycap); 1157c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) 1158c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: field2frame() rc = %i\n", rc); 115940b8d50ac98f8c8779aea7459f805e5a69fdb726Mike Thomas/*---------------------------------------------------------------------------*/ 116040b8d50ac98f8c8779aea7459f805e5a69fdb726Mike Thomas/* 116140b8d50ac98f8c8779aea7459f805e5a69fdb726Mike Thomas * WASTE THIS FRAME 116240b8d50ac98f8c8779aea7459f805e5a69fdb726Mike Thomas*/ 116340b8d50ac98f8c8779aea7459f805e5a69fdb726Mike Thomas/*---------------------------------------------------------------------------*/ 1164a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler if (peasycap->skip) { 1165c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->skipped++; 1166c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->skip != peasycap->skipped) 1167c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return peasycap->skip - peasycap->skipped; 1168a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler else 1169a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->skipped = 0; 1170c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 117140b8d50ac98f8c8779aea7459f805e5a69fdb726Mike Thomas/*---------------------------------------------------------------------------*/ 1172c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->frame_read = peasycap->frame_fill; 1173c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->queued[peasycap->frame_read] = 0; 1174c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->done[peasycap->frame_read] = V4L2_BUF_FLAG_DONE; 1175702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1176c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->frame_fill++; 1177c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->frame_buffer_many <= peasycap->frame_fill) 1178c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->frame_fill = 0; 1179702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1180c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x01 & easycap_standard[peasycap->standard_offset].mask) 1181c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->frame_buffer[peasycap->frame_read][0].kount = 1182702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas V4L2_FIELD_TOP; 1183c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1184c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->frame_buffer[peasycap->frame_read][0].kount = 1185702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas V4L2_FIELD_BOTTOM; 1186702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1187702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1188c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "setting: %i=peasycap->frame_read\n", peasycap->frame_read); 1189c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "bumped to: %i=peasycap->frame_fill\n", peasycap->frame_fill); 1190c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 1191c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 1192702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 1193702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 1194702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1195702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 1196702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * BY DEFINITION, odd IS true FOR THE FIELD OCCUPYING LINES 1,3,5,...,479 1197702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * odd IS false FOR THE FIELD OCCUPYING LINES 0,2,4,...,478 1198702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 1199702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * WHEN BOOLEAN PARAMETER decimatepixel IS true, ONLY THE FIELD FOR WHICH 1200702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * odd==false IS TRANSFERRED TO THE FRAME BUFFER. 1201702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 1202702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 1203702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 120498680557f3ce7eadae0ceda4484fd6c7a13ba3beTomas Winklerstatic int field2frame(struct easycap *peasycap) 1205702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 1206c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 1207c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler void *pex, *pad; 1208c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int kex, kad, mex, mad, rex, rad, rad2; 1209c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int c2, c3, w2, w3, cz, wz; 1210c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int rc, bytesperpixel, multiplier; 1211c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int much, more, over, rump, caches, input; 1212c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u8 mask, margin; 1213a6ff0a06d8634a07db52dbc006fd9ce4c438c1e3Tomas Winkler bool odd, isuy, decimatepixel, badinput; 1214c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 12156888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 1216c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap is NULL\n"); 1217c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 1218c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1219e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas 1220c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler badinput = false; 1221c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler input = 0x07 & peasycap->field_buffer[peasycap->field_read][0].input; 1222f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas 1223c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "===== parity %i, input 0x%02X, field buffer %i --> " 1224c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "frame buffer %i\n", 12251dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler peasycap->field_buffer[peasycap->field_read][0].kount, 12261dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler peasycap->field_buffer[peasycap->field_read][0].input, 1227702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas peasycap->field_read, peasycap->frame_fill); 1228c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "===== %i=bytesperpixel\n", peasycap->bytesperpixel); 1229702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1230702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1231702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 1232702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * REJECT OR CLEAN BAD FIELDS 1233702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 1234702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1235c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->field_read == peasycap->field_fill) { 1236c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: on entry, still filling field buffer %i\n", 1237c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_read); 1238c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 1239c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 12403fc0dae888ee216036ae1898fc9186f1dd04f185Tomas Winkler#ifdef EASYCAP_TESTCARD 1241c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler easycap_testcard(peasycap, peasycap->field_read); 1242702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas#else 1243c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 <= input && INPUT_MANY > input) { 1244c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (easycap_bars && VIDEO_LOST_TOLERATE <= peasycap->lost[input]) 1245c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler easycap_testcard(peasycap, peasycap->field_read); 1246c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1247702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas#endif /*EASYCAP_TESTCARD*/ 1248702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1249702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1250c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bytesperpixel = peasycap->bytesperpixel; 1251c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler decimatepixel = peasycap->decimatepixel; 1252702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1253c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if ((2 != bytesperpixel) && 1254c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (3 != bytesperpixel) && 1255c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (4 != bytesperpixel)) { 1256c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel); 1257c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 1258c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 125927d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (decimatepixel) 1260c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler multiplier = 2; 1261c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1262c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler multiplier = 1; 1263702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1264c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler w2 = 2 * multiplier * (peasycap->width); 1265c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler w3 = bytesperpixel * multiplier * (peasycap->width); 1266c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler wz = multiplier * (peasycap->height) * 1267c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler multiplier * (peasycap->width); 1268c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 1269c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler kex = peasycap->field_read; mex = 0; 1270c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler kad = peasycap->frame_fill; mad = 0; 1271c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 1272c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pex = peasycap->field_buffer[kex][0].pgo; rex = PAGE_SIZE; 1273c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pad = peasycap->frame_buffer[kad][0].pgo; rad = PAGE_SIZE; 1274c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler odd = !!(peasycap->field_buffer[kex][0].kount); 1275c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 1276febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (odd && (!decimatepixel)) { 1277c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "initial skipping %4i bytes p.%4i\n", 1278c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler w3/multiplier, mad); 1279c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pad += (w3 / multiplier); rad -= (w3 / multiplier); 1280c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1281c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = true; 1282c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mask = 0; rump = 0; caches = 0; 1283c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 1284c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler cz = 0; 1285c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (cz < wz) { 1286c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* 1287c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * PROCESS ONE LINE OF FRAME AT FULL RESOLUTION: 1288c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * READ w2 BYTES FROM FIELD BUFFER, 1289c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * WRITE w3 BYTES TO FRAME BUFFER 1290c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler */ 1291febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (!decimatepixel) { 1292c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler over = w2; 1293c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler do { 1294c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler much = over; more = 0; 1295c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler margin = 0; mask = 0x00; 1296c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rex < much) 1297c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler much = rex; 1298c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rump = 0; 1299c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 1300c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (much % 2) { 1301c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: much is odd\n"); 1302c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 1303c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1304702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1305c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler more = (bytesperpixel * 1306c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler much) / 2; 1307702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1308c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (1 < bytesperpixel) { 1309c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rad * 2 < much * bytesperpixel) { 1310c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* 1311c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * INJUDICIOUS ALTERATION OF 1312c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * THIS STATEMENT BLOCK WILL 1313c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * CAUSE BREAKAGE. BEWARE. 1314c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler */ 1315c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rad2 = rad + bytesperpixel - 1; 1316a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler much = ((((2 * rad2)/bytesperpixel)/2) * 2); 1317a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler rump = ((bytesperpixel * much) / 2) - rad; 1318c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler more = rad; 1319a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler } 1320c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mask = (u8)rump; 1321c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler margin = 0; 1322c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (much == rex) { 1323c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mask |= 0x04; 1324a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler if ((mex + 1) < FIELD_BUFFER_SIZE / PAGE_SIZE) 1325a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler margin = *((u8 *)(peasycap->field_buffer[kex][mex + 1].pgo)); 1326a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler else 1327c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mask |= 0x08; 1328702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1329c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 1330c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=bytesperpixel\n", 1331c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bytesperpixel); 1332c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 1333702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1334c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rump) 1335c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler caches++; 133627d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (badinput) { 1337c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "ERROR: 0x%02X=->field_buffer" 1338c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "[%i][%i].input, " 1339c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "0x%02X=(0x08|->input)\n", 1340c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_buffer 1341c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [kex][mex].input, kex, mex, 1342c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (0x08|peasycap->input)); 1343c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1344c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = redaub(peasycap, pad, pex, much, more, 1345c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mask, margin, isuy); 1346c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 > rc) { 1347c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: redaub() failed\n"); 1348c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 1349f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 1350a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler if (much % 4) 1351a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler isuy = !isuy; 1352a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler 1353c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler over -= much; cz += much; 1354c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pex += much; rex -= much; 1355c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!rex) { 1356c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mex++; 1357c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pex = peasycap->field_buffer[kex][mex].pgo; 1358c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rex = PAGE_SIZE; 1359a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler if (peasycap->field_buffer[kex][mex].input != (0x08|peasycap->input)) 1360c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler badinput = true; 1361c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1362c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pad += more; 1363c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rad -= more; 1364c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!rad) { 1365c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mad++; 1366c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pad = peasycap->frame_buffer[kad][mad].pgo; 1367c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rad = PAGE_SIZE; 1368c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rump) { 1369c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pad += rump; 1370c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rad -= rump; 1371c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1372c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1373c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } while (over); 1374702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1375702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 1376702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * SKIP w3 BYTES IN TARGET FRAME BUFFER, 1377702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * UNLESS IT IS THE LAST LINE OF AN ODD FRAME 1378702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 1379702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1380febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (!odd || (cz != wz)) { 1381c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler over = w3; 1382c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler do { 1383c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!rad) { 1384c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mad++; 1385c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pad = peasycap->frame_buffer 1386c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [kad][mad].pgo; 1387c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rad = PAGE_SIZE; 1388c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1389c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler more = over; 1390c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rad < more) 1391c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler more = rad; 1392c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler over -= more; 1393c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pad += more; 1394c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rad -= more; 1395c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } while (over); 1396c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1397702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1398702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 1399702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * PROCESS ONE LINE OF FRAME AT REDUCED RESOLUTION: 1400702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * ONLY IF false==odd, 1401702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * READ w2 BYTES FROM FIELD BUFFER, 1402702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * WRITE w3 / 2 BYTES TO FRAME BUFFER 1403702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 1404702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1405febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler } else if (!odd) { 1406c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler over = w2; 1407c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler do { 1408c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler much = over; more = 0; margin = 0; mask = 0x00; 1409c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rex < much) 1410c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler much = rex; 1411c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rump = 0; 1412702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1413c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (much % 2) { 1414c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: much is odd\n"); 1415c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 1416c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1417702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1418c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler more = (bytesperpixel * much) / 4; 1419702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1420c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (1 < bytesperpixel) { 1421c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rad * 4 < much * bytesperpixel) { 1422c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* 1423c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * INJUDICIOUS ALTERATION OF 1424c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * THIS STATEMENT BLOCK 1425c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * WILL CAUSE BREAKAGE. 1426c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * BEWARE. 1427c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler */ 1428c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rad2 = rad + bytesperpixel - 1; 1429a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler much = ((((2 * rad2) / bytesperpixel) / 2) * 4); 1430a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler rump = ((bytesperpixel * much) / 4) - rad; 1431c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler more = rad; 1432702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1433c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mask = (u8)rump; 1434c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler margin = 0; 1435c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (much == rex) { 1436c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mask |= 0x04; 1437a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler if ((mex + 1) < FIELD_BUFFER_SIZE / PAGE_SIZE) 1438a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler margin = *((u8 *)(peasycap->field_buffer[kex][mex + 1].pgo)); 1439a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler else 1440c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mask |= 0x08; 1441702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1442702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1443702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } else { 14441dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler SAM("MISTAKE: %i=bytesperpixel\n", 1445702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas bytesperpixel); 1446702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas return -EFAULT; 1447702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1448702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1449c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rump) 1450c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler caches++; 1451c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 145227d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (badinput) { 1453c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "ERROR: 0x%02X=->field_buffer" 1454c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "[%i][%i].input, " 1455c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "0x%02X=(0x08|->input)\n", 1456c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_buffer 1457c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [kex][mex].input, kex, mex, 1458c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (0x08|peasycap->input)); 1459c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1460c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = redaub(peasycap, pad, pex, much, more, 1461702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas mask, margin, isuy); 1462c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 > rc) { 1463c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: redaub() failed\n"); 1464c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 1465702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1466c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler over -= much; cz += much; 1467c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pex += much; rex -= much; 1468c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!rex) { 1469c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mex++; 1470c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pex = peasycap->field_buffer[kex][mex].pgo; 1471c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rex = PAGE_SIZE; 1472c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->field_buffer[kex][mex].input != 1473c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (0x08|peasycap->input)) 1474c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler badinput = true; 1475c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1476c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pad += more; 1477c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rad -= more; 1478c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!rad) { 1479c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mad++; 1480c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pad = peasycap->frame_buffer[kad][mad].pgo; 1481c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rad = PAGE_SIZE; 1482c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rump) { 1483c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pad += rump; 1484c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rad -= rump; 1485c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1486c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1487c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } while (over); 1488702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1489702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 1490702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * OTHERWISE JUST 1491702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * READ w2 BYTES FROM FIELD BUFFER AND DISCARD THEM 1492702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 1493702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1494c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 1495c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler over = w2; 1496c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler do { 1497c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!rex) { 1498c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mex++; 1499c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pex = peasycap->field_buffer[kex][mex].pgo; 1500c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rex = PAGE_SIZE; 1501c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->field_buffer[kex][mex].input != 1502c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (0x08|peasycap->input)) { 1503c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "ERROR: 0x%02X=->field_buffer" 1504c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "[%i][%i].input, " 1505c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "0x%02X=(0x08|->input)\n", 1506c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_buffer 1507c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [kex][mex].input, kex, mex, 1508c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (0x08|peasycap->input)); 1509c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler badinput = true; 1510c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1511f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 1512c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler much = over; 1513c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rex < much) 1514c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler much = rex; 1515c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler over -= much; 1516c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler cz += much; 1517c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pex += much; 1518c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rex -= much; 1519c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } while (over); 1520c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1521702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1522702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1523702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 1524702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * SANITY CHECKS 1525702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 1526702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1527c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler c2 = (mex + 1)*PAGE_SIZE - rex; 1528c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (cz != c2) 1529c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: discrepancy %i in bytes read\n", c2 - cz); 1530c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler c3 = (mad + 1)*PAGE_SIZE - rad; 1531c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 1532febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (!decimatepixel) { 1533c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (bytesperpixel * cz != c3) 15341dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler SAM("ERROR: discrepancy %i in bytes written\n", 1535c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler c3 - (bytesperpixel * cz)); 1536c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 1537febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (!odd) { 1538c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (bytesperpixel * 1539c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler cz != (4 * c3)) 1540c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: discrepancy %i in bytes written\n", 1541c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (2*c3)-(bytesperpixel * cz)); 1542c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 1543c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 != c3) 1544c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: discrepancy %i " 1545c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "in bytes written\n", c3); 1546c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1547c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1548c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rump) 1549c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("WORRY: undischarged cache at end of line in frame buffer\n"); 1550702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1551c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "===== field2frame(): %i bytes --> %i bytes (incl skip)\n", c2, c3); 1552c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "===== field2frame(): %i=mad %i=rad\n", mad, rad); 1553702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 155427d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (odd) 1555c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "+++++ field2frame(): frame buffer %i is full\n", kad); 1556702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1557c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->field_read == peasycap->field_fill) 1558c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("WARNING: on exit, filling field buffer %i\n", 1559c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_read); 1560702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1561c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (caches) 1562c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%i=caches\n", caches); 1563c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 1564702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 1565702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1566702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 1567702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * DECIMATION AND COLOURSPACE CONVERSION. 1568702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 1569702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * THIS ROUTINE REQUIRES THAT ALL THE DATA TO BE READ RESIDES ON ONE PAGE 1570702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * AND THAT ALL THE DATA TO BE WRITTEN RESIDES ON ONE (DIFFERENT) PAGE. 1571702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * THE CALLING ROUTINE MUST ENSURE THAT THIS REQUIREMENT IS MET, AND MUST 1572702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * ALSO ENSURE THAT much IS EVEN. 1573702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 1574702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * much BYTES ARE READ, AT LEAST (bytesperpixel * much)/2 BYTES ARE WRITTEN 1575702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * IF THERE IS NO DECIMATION, HALF THIS AMOUNT IF THERE IS DECIMATION. 1576702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 1577702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * mask IS ZERO WHEN NO SPECIAL BEHAVIOUR REQUIRED. OTHERWISE IT IS SET THUS: 1578702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 0x03 & mask = number of bytes to be written to cache instead of to 1579702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * frame buffer 1580702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 0x04 & mask => use argument margin to set the chrominance for last pixel 1581702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 0x08 & mask => do not set the chrominance for last pixel 1582702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 1583702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * YUV to RGB CONVERSION IS (OR SHOULD BE) ITU-R BT 601. 1584702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 1585702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * THERE IS A LOT OF CODE REPETITION IN THIS ROUTINE IN ORDER TO AVOID 1586702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * INEFFICIENT SWITCHING INSIDE INNER LOOPS. REARRANGING THE LOGIC TO 1587702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * REDUCE CODE LENGTH WILL GENERALLY IMPAIR RUNTIME PERFORMANCE. BEWARE. 1588702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 1589702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 159098680557f3ce7eadae0ceda4484fd6c7a13ba3beTomas Winklerstatic int redaub(struct easycap *peasycap, 159198680557f3ce7eadae0ceda4484fd6c7a13ba3beTomas Winkler void *pad, void *pex, int much, int more, 159298680557f3ce7eadae0ceda4484fd6c7a13ba3beTomas Winkler u8 mask, u8 margin, bool isuy) 1593702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 1594c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler static s32 ay[256], bu[256], rv[256], gu[256], gv[256]; 1595c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u8 *pcache; 1596c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u8 r, g, b, y, u, v, c, *p2, *p3, *pz, *pr; 1597c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int bytesperpixel; 1598c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bool byteswaporder, decimatepixel, last; 1599c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int j, rump; 1600c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler s32 tmp; 1601c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 1602c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (much % 2) { 1603c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: much is odd\n"); 1604c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 1605c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1606c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bytesperpixel = peasycap->bytesperpixel; 1607c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler byteswaporder = peasycap->byteswaporder; 1608c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler decimatepixel = peasycap->decimatepixel; 1609c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 1610c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler/*---------------------------------------------------------------------------*/ 1611c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!bu[255]) { 1612c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (j = 0; j < 112; j++) { 1613c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = (0xFF00 & (453 * j)) >> 8; 1614c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bu[j + 128] = tmp; bu[127 - j] = -tmp; 1615c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = (0xFF00 & (359 * j)) >> 8; 1616c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rv[j + 128] = tmp; rv[127 - j] = -tmp; 1617c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = (0xFF00 & (88 * j)) >> 8; 1618c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler gu[j + 128] = tmp; gu[127 - j] = -tmp; 1619c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = (0xFF00 & (183 * j)) >> 8; 1620c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler gv[j + 128] = tmp; gv[127 - j] = -tmp; 1621c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1622c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (j = 0; j < 16; j++) { 1623c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bu[j] = bu[16]; rv[j] = rv[16]; 1624c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler gu[j] = gu[16]; gv[j] = gv[16]; 1625c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1626c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (j = 240; j < 256; j++) { 1627c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bu[j] = bu[239]; rv[j] = rv[239]; 1628c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler gu[j] = gu[239]; gv[j] = gv[239]; 1629c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1630c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (j = 16; j < 236; j++) 1631c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ay[j] = j; 1632c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (j = 0; j < 16; j++) 1633c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ay[j] = ay[16]; 1634c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (j = 236; j < 256; j++) 1635c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ay[j] = ay[235]; 1636c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "lookup tables are prepared\n"); 1637c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1638c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pcache = peasycap->pcache; 16396888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pcache) 1640c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pcache = &peasycap->cache[0]; 1641702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1642702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 1643702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * TRANSFER CONTENTS OF CACHE TO THE FRAME BUFFER 1644702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 1645702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1646c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!pcache) { 1647c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: pcache is NULL\n"); 1648c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 1649c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1650702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1651c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (pcache != &peasycap->cache[0]) 1652c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(16, "cache has %i bytes\n", (int)(pcache - &peasycap->cache[0])); 1653c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p2 = &peasycap->cache[0]; 1654c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p3 = (u8 *)pad - (int)(pcache - &peasycap->cache[0]); 1655c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (p2 < pcache) { 1656c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3++ = *p2; p2++; 1657c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1658c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pcache = &peasycap->cache[0]; 1659c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (p3 != pad) { 1660c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: pointer misalignment\n"); 1661c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 1662c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1663702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1664c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rump = (int)(0x03 & mask); 1665c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = 0; v = 0; 1666c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p2 = (u8 *)pex; pz = p2 + much; pr = p3 + more; last = false; 1667c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p2++; 1668702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 166927d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 1670c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = *(p2 - 1); 1671c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1672c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = *(p2 - 1); 1673702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1674c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rump) 1675c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(16, "%4i=much %4i=more %i=rump\n", much, more, rump); 1676702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 1677702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 1678c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler switch (bytesperpixel) { 1679c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 2: { 1680febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (!decimatepixel) { 1681c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler memcpy(pad, pex, (size_t)much); 1682febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (!byteswaporder) { 1683c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* UYVY */ 1684c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 1685c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 1686c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* YUYV */ 1687c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p3 = (u8 *)pad; pz = p3 + much; 1688c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (pz > p3) { 1689c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler c = *p3; 1690c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = *(p3 + 1); 1691c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 1) = c; 1692c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p3 += 2; 1693702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1694c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 1695702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1696702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } else { 1697febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (!byteswaporder) { 1698c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* UYVY DECIMATED */ 1699c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p2 = (u8 *)pex; p3 = (u8 *)pad; pz = p2 + much; 1700c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (pz > p2) { 1701c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = *p2; 1702c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 1) = *(p2 + 1); 1703c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 2) = *(p2 + 2); 1704c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 3) = *(p2 + 3); 1705c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p3 += 4; p2 += 8; 1706702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1707c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 1708c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 1709c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* YUYV DECIMATED */ 1710c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p2 = (u8 *)pex; p3 = (u8 *)pad; pz = p2 + much; 1711c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (pz > p2) { 1712c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = *(p2 + 1); 1713c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 1) = *p2; 1714c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 2) = *(p2 + 3); 1715c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 3) = *(p2 + 2); 1716c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p3 += 4; p2 += 8; 1717702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1718c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 1719702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1720c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1721c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 1722c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1723c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 3: 1724c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler { 1725febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (!decimatepixel) { 1726febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (!byteswaporder) { 1727c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* RGB */ 1728c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (pz > p2) { 1729c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (pr <= (p3 + bytesperpixel)) 1730c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = true; 1731c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1732c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = false; 1733c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler y = *p2; 173427d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && (0x0C & mask)) { 1735c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x04 & mask) { 173627d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 1737c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = margin; 1738c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1739c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = margin; 1740c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else 1741c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x08 & mask) 1742c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ; 1743c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 174427d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 1745c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = *(p2 + 1); 1746702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas else 1747c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = *(p2 + 1); 1748c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1749702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 175027d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler tmp = ay[(int)y] + rv[(int)v]; 175127d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler r = (255 < tmp) ? 255 : ((0 > tmp) ? 1752055e3a3a2cdcb7d39d14857e2fb2175c11168ee7Tomas Winkler 0 : (u8)tmp); 1753c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; 175427d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler g = (255 < tmp) ? 255 : ((0 > tmp) ? 1755055e3a3a2cdcb7d39d14857e2fb2175c11168ee7Tomas Winkler 0 : (u8)tmp); 175627d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler tmp = ay[(int)y] + bu[(int)u]; 175727d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler b = (255 < tmp) ? 255 : ((0 > tmp) ? 1758055e3a3a2cdcb7d39d14857e2fb2175c11168ee7Tomas Winkler 0 : (u8)tmp); 1759702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 176027d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && rump) { 1761e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas pcache = &peasycap->cache[0]; 1762702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas switch (bytesperpixel - rump) { 1763702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas case 1: { 1764702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = r; 1765702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = g; 1766702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = b; 1767702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas break; 1768702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1769702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas case 2: { 1770702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = r; 1771702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 1) = g; 1772702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = b; 1773702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas break; 1774702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1775702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas default: { 1776c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=rump\n", 1777c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bytesperpixel - rump); 1778702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas return -EFAULT; 1779702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1780702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1781702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } else { 1782702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = r; 1783702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 1) = g; 1784702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 2) = b; 1785702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1786c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p2 += 2; 178727d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 1788c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = false; 1789c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1790c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = true; 1791702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas p3 += bytesperpixel; 1792702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1793c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 1794c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 1795c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* BGR */ 1796c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (pz > p2) { 1797c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (pr <= (p3 + bytesperpixel)) 1798c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = true; 1799c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1800c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = false; 1801c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler y = *p2; 180227d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && (0x0C & mask)) { 1803c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x04 & mask) { 180427d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 1805c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = margin; 1806c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1807c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = margin; 1808c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1809c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1810702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas if (0x08 & mask) 1811702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas ; 1812c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 181327d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 1814c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = *(p2 + 1); 1815c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1816c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = *(p2 + 1); 1817c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1818702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 181927d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler tmp = ay[(int)y] + rv[(int)v]; 182027d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler r = (255 < tmp) ? 255 : ((0 > tmp) ? 1821c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 1822c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; 182327d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler g = (255 < tmp) ? 255 : ((0 > tmp) ? 1824c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 182527d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler tmp = ay[(int)y] + bu[(int)u]; 182627d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler b = (255 < tmp) ? 255 : ((0 > tmp) ? 1827c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 1828702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 182927d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && rump) { 1830e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas pcache = &peasycap->cache[0]; 1831702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas switch (bytesperpixel - rump) { 1832702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas case 1: { 1833702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = b; 1834702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = g; 1835702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = r; 1836702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas break; 1837702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1838702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas case 2: { 1839702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = b; 1840702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 1) = g; 1841702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = r; 1842702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas break; 1843702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1844702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas default: { 1845c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=rump\n", 1846c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bytesperpixel - rump); 1847702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas return -EFAULT; 1848702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1849702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1850702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } else { 1851702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = b; 1852702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 1) = g; 1853702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 2) = r; 1854702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1855c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p2 += 2; 185627d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 1857c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = false; 1858c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1859c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = true; 1860702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas p3 += bytesperpixel; 1861702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1862702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1863702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas return 0; 1864c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 1865febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (!byteswaporder) { 1866c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* RGB DECIMATED */ 1867c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (pz > p2) { 1868c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (pr <= (p3 + bytesperpixel)) 1869c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = true; 1870c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1871c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = false; 1872c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler y = *p2; 187327d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && (0x0C & mask)) { 1874c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x04 & mask) { 187527d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 1876c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = margin; 1877c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1878c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = margin; 1879c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else 1880c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x08 & mask) 1881c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ; 1882c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 188327d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 1884c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = *(p2 + 1); 1885702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas else 1886c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = *(p2 + 1); 1887702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1888c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 188927d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) { 1890c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] + rv[(int)v]; 1891c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler r = (255 < tmp) ? 255 : ((0 > tmp) ? 1892c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 1893c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] - gu[(int)u] - 1894c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler gv[(int)v]; 1895c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler g = (255 < tmp) ? 255 : ((0 > tmp) ? 1896c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 1897c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] + bu[(int)u]; 1898c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler b = (255 < tmp) ? 255 : ((0 > tmp) ? 1899c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 1900c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 190127d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && rump) { 1902c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pcache = &peasycap->cache[0]; 1903c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler switch (bytesperpixel - rump) { 1904c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 1: { 1905c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = r; 1906c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = g; 1907c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = b; 1908c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 1909c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1910c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 2: { 1911c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = r; 1912c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 1) = g; 1913c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = b; 1914c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 1915c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1916c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler default: { 1917c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: " 1918c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "%i=rump\n", 1919c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bytesperpixel - rump); 1920c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 1921c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1922c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1923c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 1924c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = r; 1925c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 1) = g; 1926c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 2) = b; 1927c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1928c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = false; 1929c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p3 += bytesperpixel; 1930c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 1931c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = true; 1932702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1933c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p2 += 2; 1934702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1935c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 1936c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 1937c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* BGR DECIMATED */ 1938c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (pz > p2) { 1939c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (pr <= (p3 + bytesperpixel)) 1940c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = true; 1941c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1942c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = false; 1943c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler y = *p2; 194427d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && (0x0C & mask)) { 1945c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x04 & mask) { 194627d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 1947c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = margin; 1948c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 1949c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = margin; 1950c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else 1951c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x08 & mask) 1952c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ; 1953c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 195427d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 1955c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = *(p2 + 1); 1956702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas else 1957c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = *(p2 + 1); 1958702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 1959c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 196027d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) { 1961c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 1962c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] + rv[(int)v]; 1963c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler r = (255 < tmp) ? 255 : ((0 > tmp) ? 1964c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 1965c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] - gu[(int)u] - 1966c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler gv[(int)v]; 1967c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler g = (255 < tmp) ? 255 : ((0 > tmp) ? 1968c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 1969c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] + bu[(int)u]; 1970c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler b = (255 < tmp) ? 255 : ((0 > tmp) ? 1971c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 1972c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 197327d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && rump) { 1974c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pcache = &peasycap->cache[0]; 1975c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler switch (bytesperpixel - rump) { 1976c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 1: { 1977c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = b; 1978c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = g; 1979c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = r; 1980c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 1981c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1982c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 2: { 1983c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = b; 1984c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 1) = g; 1985c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = r; 1986c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 1987c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1988c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler default: { 1989c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: " 1990c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "%i=rump\n", 1991c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bytesperpixel - rump); 1992c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 1993c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1994c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 1995c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 1996c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = b; 1997c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 1) = g; 1998c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 2) = r; 1999c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2000c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = false; 2001c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p3 += bytesperpixel; 2002c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2003c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2004c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = true; 2005c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p2 += 2; 2006702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2007c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 2008702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2009702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2010c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 2011702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2012c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 4: 2013c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler { 2014febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (!decimatepixel) { 2015febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (!byteswaporder) { 2016c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* RGBA */ 2017c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (pz > p2) { 2018c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (pr <= (p3 + bytesperpixel)) 2019c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = true; 2020c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2021c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = false; 2022c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler y = *p2; 202327d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && (0x0C & mask)) { 2024c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x04 & mask) { 202527d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 2026c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = margin; 2027c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2028c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = margin; 2029c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else 2030c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x08 & mask) 2031c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ; 2032c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 203327d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 2034c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = *(p2 + 1); 2035702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas else 2036c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = *(p2 + 1); 2037c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2038702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 203927d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler tmp = ay[(int)y] + rv[(int)v]; 204027d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler r = (255 < tmp) ? 255 : ((0 > tmp) ? 2041c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 2042c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; 204327d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler g = (255 < tmp) ? 255 : ((0 > tmp) ? 2044c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 204527d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler tmp = ay[(int)y] + bu[(int)u]; 204627d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler b = (255 < tmp) ? 255 : ((0 > tmp) ? 2047c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 2048702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 204927d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && rump) { 2050e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas pcache = &peasycap->cache[0]; 2051702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas switch (bytesperpixel - rump) { 2052702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas case 1: { 2053702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = r; 2054702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = g; 2055702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = b; 2056702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = 0; 2057702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas break; 2058702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2059702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas case 2: { 2060702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = r; 2061702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 1) = g; 2062702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = b; 2063702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = 0; 2064702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas break; 2065702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2066702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas case 3: { 2067702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = r; 2068702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 1) = g; 2069702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 2) = b; 2070702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = 0; 2071702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas break; 2072702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2073702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas default: { 2074c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=rump\n", 2075c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bytesperpixel - rump); 2076702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas return -EFAULT; 2077c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2078702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2079702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } else { 2080702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = r; 2081702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 1) = g; 2082702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 2) = b; 2083702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 3) = 0; 2084c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2085c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p2 += 2; 208627d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 2087c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = false; 2088702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas else 2089c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = true; 2090c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p3 += bytesperpixel; 2091702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2092c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 2093c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 2094c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* 2095c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * BGRA 2096c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler */ 2097c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (pz > p2) { 2098c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (pr <= (p3 + bytesperpixel)) 2099c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = true; 2100c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2101c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = false; 2102c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler y = *p2; 210327d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && (0x0C & mask)) { 2104c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x04 & mask) { 210527d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 2106c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = margin; 2107c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2108c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = margin; 2109c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else 2110c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x08 & mask) 2111c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ; 2112c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 211327d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 2114c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = *(p2 + 1); 2115c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2116c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = *(p2 + 1); 2117c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2118702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 211927d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler tmp = ay[(int)y] + rv[(int)v]; 212027d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler r = (255 < tmp) ? 255 : ((0 > tmp) ? 2121c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 2122c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] - gu[(int)u] - gv[(int)v]; 212327d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler g = (255 < tmp) ? 255 : ((0 > tmp) ? 2124c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 212527d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler tmp = ay[(int)y] + bu[(int)u]; 212627d1766927372bf1410a44e8a22132757b0948b0Tomas Winkler b = (255 < tmp) ? 255 : ((0 > tmp) ? 2127c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 2128702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 212927d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && rump) { 2130e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas pcache = &peasycap->cache[0]; 2131702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas switch (bytesperpixel - rump) { 2132702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas case 1: { 2133702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = b; 2134702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = g; 2135702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = r; 2136702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = 0; 2137702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas break; 2138702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2139702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas case 2: { 2140702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = b; 2141702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 1) = g; 2142702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = r; 2143702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = 0; 2144702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas break; 2145702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2146702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas case 3: { 2147702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = b; 2148702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 1) = g; 2149702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 2) = r; 2150702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *pcache++ = 0; 2151702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas break; 2152702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2153c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler default: 2154c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=rump\n", 2155c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bytesperpixel - rump); 2156702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas return -EFAULT; 2157702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2158702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } else { 2159702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *p3 = b; 2160702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 1) = g; 2161702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 2) = r; 2162702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas *(p3 + 3) = 0; 2163702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2164c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p2 += 2; 216527d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 2166c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = false; 2167c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2168c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = true; 2169702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas p3 += bytesperpixel; 2170c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2171c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2172c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 2173c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 2174febd32bcfd09aeb543b229fd2896814a26d74d20Tomas Winkler if (!byteswaporder) { 2175c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* 2176c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * RGBA DECIMATED 2177c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler */ 2178c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (pz > p2) { 2179c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (pr <= (p3 + bytesperpixel)) 2180c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = true; 2181c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2182c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = false; 2183c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler y = *p2; 218427d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && (0x0C & mask)) { 2185c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x04 & mask) { 218627d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 2187c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = margin; 2188c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2189c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = margin; 2190c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else 2191c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x08 & mask) 2192c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ; 2193c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 219427d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 2195c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = *(p2 + 1); 2196c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2197c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = *(p2 + 1); 2198c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2199c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 220027d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) { 2201c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 2202c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] + rv[(int)v]; 2203c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler r = (255 < tmp) ? 255 : ((0 > tmp) ? 2204c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 2205c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] - gu[(int)u] - 2206c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler gv[(int)v]; 2207c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler g = (255 < tmp) ? 255 : ((0 > tmp) ? 2208c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 2209c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] + bu[(int)u]; 2210c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler b = (255 < tmp) ? 255 : ((0 > tmp) ? 2211c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 2212c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 221327d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && rump) { 2214c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pcache = &peasycap->cache[0]; 2215c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler switch (bytesperpixel - rump) { 2216c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 1: { 2217c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = r; 2218c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = g; 2219c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = b; 2220c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = 0; 2221c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 2222c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2223c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 2: { 2224c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = r; 2225c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 1) = g; 2226c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = b; 2227c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = 0; 2228c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 2229c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2230c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 3: { 2231c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = r; 2232c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 1) = g; 2233c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 2) = b; 2234c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = 0; 2235c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 2236c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2237c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler default: { 2238c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: " 2239c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "%i=rump\n", 2240c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bytesperpixel - 2241c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rump); 2242c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 2243c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2244c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2245c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 2246c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = r; 2247c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 1) = g; 2248c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 2) = b; 2249c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 3) = 0; 2250c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2251c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = false; 2252c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p3 += bytesperpixel; 2253c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else 2254c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = true; 2255702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas p2 += 2; 2256702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2257c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 2258c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 2259c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* 2260c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler * BGRA DECIMATED 2261c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler */ 2262c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (pz > p2) { 2263c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (pr <= (p3 + bytesperpixel)) 2264c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = true; 2265c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2266c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = false; 2267c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler y = *p2; 226827d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && (0x0C & mask)) { 2269c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x04 & mask) { 227027d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 2271c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = margin; 2272c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2273c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = margin; 2274c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else 2275c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x08 & mask) 2276c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler ; 2277c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 227827d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) 2279c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v = *(p2 + 1); 2280c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2281c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u = *(p2 + 1); 2282c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2283c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 228427d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (isuy) { 2285c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] + rv[(int)v]; 2286c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler r = (255 < tmp) ? 255 : ((0 > tmp) ? 2287c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 2288c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] - gu[(int)u] - 2289c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler gv[(int)v]; 2290c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler g = (255 < tmp) ? 255 : ((0 > tmp) ? 2291c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 2292c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler tmp = ay[(int)y] + bu[(int)u]; 2293c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler b = (255 < tmp) ? 255 : ((0 > tmp) ? 2294c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0 : (u8)tmp); 2295c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 229627d683ab79a408a6a48cb01a200af9abf82cca5aTomas Winkler if (last && rump) { 2297c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pcache = &peasycap->cache[0]; 2298c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler switch (bytesperpixel - rump) { 2299c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 1: { 2300c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = b; 2301c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = g; 2302c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = r; 2303c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = 0; 2304c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 2305c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2306c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 2: { 2307c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = b; 2308c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 1) = g; 2309c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = r; 2310c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = 0; 2311c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 2312c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2313c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 3: { 2314c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = b; 2315c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 1) = g; 2316c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 2) = r; 2317c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *pcache++ = 0; 2318c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 2319c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2320c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler default: { 2321c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: " 2322c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "%i=rump\n", 2323c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bytesperpixel - rump); 2324c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 2325c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2326c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2327c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 2328c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *p3 = b; 2329c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 1) = g; 2330c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 2) = r; 2331c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler *(p3 + 3) = 0; 2332c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2333c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = false; 2334c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p3 += bytesperpixel; 2335c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else 2336c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler isuy = true; 2337c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler p2 += 2; 2338c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2339c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 2340c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2341702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2342c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 2343c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2344c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler default: { 2345c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel); 2346c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return -EFAULT; 2347702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2348702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2349c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return 0; 2350702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 2351702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 2352702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 2353702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * SEE CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGES 430-434 2354702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 2355702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 2356d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic void easycap_vma_open(struct vm_area_struct *pvma) 2357702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 2358c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct easycap *peasycap; 2359702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 2360c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap = pvma->vm_private_data; 23616888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 2362c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap is NULL\n"); 2363c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 2364c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2365c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->vma_many++; 2366c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many); 2367268dfede46e24eef55a2ef7a10a462617936771eMike Thomas return; 2368268dfede46e24eef55a2ef7a10a462617936771eMike Thomas} 2369702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 2370d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic void easycap_vma_close(struct vm_area_struct *pvma) 2371702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 2372c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct easycap *peasycap; 2373702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 2374c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap = pvma->vm_private_data; 23756888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 2376c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap is NULL\n"); 2377c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 2378c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2379c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->vma_many--; 2380c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many); 2381268dfede46e24eef55a2ef7a10a462617936771eMike Thomas return; 2382702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 2383702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 2384d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic int easycap_vma_fault(struct vm_area_struct *pvma, struct vm_fault *pvmf) 2385702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 2386c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int k, m, retcode; 2387c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler void *pbuf; 2388c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct page *page; 2389c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct easycap *peasycap; 2390702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 2391c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler retcode = VM_FAULT_NOPAGE; 2392702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 23936888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pvma) { 2394c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("pvma is NULL\n"); 2395c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return retcode; 2396c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 23976888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pvmf) { 2398c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("pvmf is NULL\n"); 2399c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return retcode; 2400c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2401702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 2402c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler k = (pvmf->pgoff) / (FRAME_BUFFER_SIZE/PAGE_SIZE); 2403c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler m = (pvmf->pgoff) % (FRAME_BUFFER_SIZE/PAGE_SIZE); 2404702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 2405c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!m) 2406c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOT(4, "%4i=k, %4i=m\n", k, m); 2407c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2408c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOT(16, "%4i=k, %4i=m\n", k, m); 2409702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 2410c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if ((0 > k) || (FRAME_BUFFER_MANY <= k)) { 2411c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: buffer index %i out of range\n", k); 2412c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return retcode; 2413c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2414c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if ((0 > m) || (FRAME_BUFFER_SIZE/PAGE_SIZE <= m)) { 2415c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: page number %i out of range\n", m); 2416c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return retcode; 2417c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2418c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap = pvma->vm_private_data; 24196888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 2420c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: peasycap is NULL\n"); 2421c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return retcode; 2422c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2423702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 2424c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pbuf = peasycap->frame_buffer[k][m].pgo; 24256888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pbuf) { 2426c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: pbuf is NULL\n"); 2427c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return retcode; 2428c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2429c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler page = virt_to_page(pbuf); 24306888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!page) { 2431c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: page is NULL\n"); 2432c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return retcode; 2433c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2434c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler get_page(page); 2435702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 24366888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!page) { 2437c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: page is NULL after get_page(page)\n"); 2438c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 2439c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pvmf->page = page; 2440c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler retcode = VM_FAULT_MINOR; 2441c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2442c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return retcode; 2443702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 2444d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler 2445d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic const struct vm_operations_struct easycap_vm_ops = { 2446d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .open = easycap_vma_open, 2447d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .close = easycap_vma_close, 2448d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .fault = easycap_vma_fault, 2449d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler}; 2450d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler 2451d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic int easycap_mmap(struct file *file, struct vm_area_struct *pvma) 2452d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler{ 2453d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler JOT(8, "\n"); 2454d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler 2455d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler pvma->vm_ops = &easycap_vm_ops; 2456d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler pvma->vm_flags |= VM_RESERVED; 24576888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (file) 2458d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler pvma->vm_private_data = file->private_data; 2459d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler easycap_vma_open(pvma); 2460d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler return 0; 2461d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler} 2462702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 2463702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 2464702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 2465702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * ON COMPLETION OF A VIDEO URB ITS DATA IS COPIED TO THE FIELD BUFFERS 2466ce36cedab3f865969653bf4360f7e364ab0937e4Mike Thomas * PROVIDED peasycap->video_idle IS ZERO. REGARDLESS OF THIS BEING TRUE, 2467702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * IT IS RESUBMITTED PROVIDED peasycap->video_isoc_streaming IS NOT ZERO. 2468702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 2469702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * THIS FUNCTION IS AN INTERRUPT SERVICE ROUTINE AND MUST NOT SLEEP. 2470702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 2471702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * INFORMATION ABOUT THE VALIDITY OF THE CONTENTS OF THE FIELD BUFFER ARE 2472702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * STORED IN THE TWO-BYTE STATUS PARAMETER 2473702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * peasycap->field_buffer[peasycap->field_fill][0].kount 2474702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * NOTICE THAT THE INFORMATION IS STORED ONLY WITH PAGE 0 OF THE FIELD BUFFER. 2475702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 2476702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * THE LOWER BYTE CONTAINS THE FIELD PARITY BYTE FURNISHED BY THE SAA7113H 2477702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * CHIP. 2478702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 2479702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * THE UPPER BYTE IS ZERO IF NO PROBLEMS, OTHERWISE: 2480702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 0 != (kount & 0x8000) => AT LEAST ONE URB COMPLETED WITH ERRORS 2481702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 0 != (kount & 0x4000) => BUFFER HAS TOO MUCH DATA 2482702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 0 != (kount & 0x2000) => BUFFER HAS NOT ENOUGH DATA 2483f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas * 0 != (kount & 0x1000) => BUFFER HAS DATA FROM DISPARATE INPUTS 2484ce36cedab3f865969653bf4360f7e364ab0937e4Mike Thomas * 0 != (kount & 0x0400) => RESERVED 2485702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 0 != (kount & 0x0200) => FIELD BUFFER NOT YET CHECKED 2486702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 0 != (kount & 0x0100) => BUFFER HAS TWO EXTRA BYTES - WHY? 2487702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 2488702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 2489d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic void easycap_complete(struct urb *purb) 2490702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 2491c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct easycap *peasycap; 2492c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler struct data_buffer *pfield_buffer; 2493c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler char errbuf[16]; 2494c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int i, more, much, leap, rc, last; 2495c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int videofieldamount; 2496c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler unsigned int override, bad; 2497c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler int framestatus, framelength, frameactual, frameoffset; 2498c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler u8 *pu; 2499c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 25006888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!purb) { 2501c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: easycap_complete(): purb is NULL\n"); 2502c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 2503c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2504c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap = purb->context; 25056888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 2506c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: easycap_complete(): peasycap is NULL\n"); 2507c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 2508c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2509c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->video_eof) 2510c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 2511c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++) 2512c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (purb->transfer_buffer == peasycap->video_isoc_buffer[i].pgo) 2513c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 2514c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(16, "%2i=urb\n", i); 2515c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last = peasycap->video_isoc_sequence; 2516c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if ((((VIDEO_ISOC_BUFFER_MANY - 1) == last) && (0 != i)) || 2517c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (((VIDEO_ISOC_BUFFER_MANY - 1) != last) && ((last + 1) != i))) { 2518c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(16, "ERROR: out-of-order urbs %i,%i ... continuing\n", 2519c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler last, i); 2520c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2521c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_isoc_sequence = i; 2522702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 2523c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->video_idle) { 2524c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(16, "%i=video_idle %i=video_isoc_streaming\n", 2525c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_idle, peasycap->video_isoc_streaming); 2526c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->video_isoc_streaming) { 2527c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = usb_submit_urb(purb, GFP_ATOMIC); 2528c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) { 2529c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("%s:%d ENOMEM\n", strerror(rc), rc); 2530c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (-ENODEV != rc) 2531c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: while %i=video_idle, " 2532c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "usb_submit_urb() " 2533c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "failed with rc:\n", 2534c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_idle); 2535c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2536702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2537c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 2538702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2539c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler override = 0; 2540702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 2541c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (FIELD_BUFFER_MANY <= peasycap->field_fill) { 2542c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: bad peasycap->field_fill\n"); 2543702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas return; 2544702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2545c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (purb->status) { 2546c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) { 2547c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "urb status -ESHUTDOWN or -ENOENT\n"); 2548c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 2549c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2550702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 2551c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap->field_buffer[peasycap->field_fill][0].kount) |= 0x8000 ; 2552c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: bad urb status -%s: %d\n", 2553c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler strerror(purb->status), purb->status); 2554702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 2555c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 2556c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler for (i = 0; i < purb->number_of_packets; i++) { 2557c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 != purb->iso_frame_desc[i].status) { 2558c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap->field_buffer 2559c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_fill][0].kount) |= 0x8000 ; 2560c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler /* FIXME: 1. missing '-' check boundaries */ 2561c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler strcpy(&errbuf[0], 2562c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler strerror(purb->iso_frame_desc[i].status)); 2563702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2564c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler framestatus = purb->iso_frame_desc[i].status; 2565c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler framelength = purb->iso_frame_desc[i].length; 2566c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler frameactual = purb->iso_frame_desc[i].actual_length; 2567c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler frameoffset = purb->iso_frame_desc[i].offset; 2568c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 2569c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(16, "frame[%2i]:" 2570c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "%4i=status " 2571c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "%4i=actual " 2572c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "%4i=length " 2573c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "%5i=offset\n", 2574c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler i, framestatus, frameactual, framelength, frameoffset); 2575c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!purb->iso_frame_desc[i].status) { 2576c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler more = purb->iso_frame_desc[i].actual_length; 2577c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer = &peasycap->field_buffer 2578c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_fill][peasycap->field_page]; 2579c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler videofieldamount = (peasycap->field_page * 2580c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler PAGE_SIZE) + 2581c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (int)(pfield_buffer->pto - pfield_buffer->pgo); 2582c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (4 == more) 2583c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_mt++; 2584c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (4 < more) { 2585c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->video_mt) { 2586c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "%4i empty video urb frames\n", 2587c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_mt); 2588c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_mt = 0; 2589c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2590c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (FIELD_BUFFER_MANY <= peasycap->field_fill) { 2591c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: bad peasycap->field_fill\n"); 2592c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 2593c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2594c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (FIELD_BUFFER_SIZE/PAGE_SIZE <= 2595c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_page) { 2596c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: bad peasycap->field_page\n"); 2597c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 2598c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2599c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer = &peasycap->field_buffer 2600c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_fill][peasycap->field_page]; 2601c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pu = (u8 *)(purb->transfer_buffer + 2602c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler purb->iso_frame_desc[i].offset); 2603c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x80 & *pu) 2604c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler leap = 8; 2605c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2606c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler leap = 4; 2607702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*--------------------------------------------------------------------------*/ 2608702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 2609702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * EIGHT-BYTE END-OF-VIDEOFIELD MARKER. 2610702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * NOTE: A SUCCESSION OF URB FRAMES FOLLOWING THIS ARE EMPTY, 2611702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * CORRESPONDING TO THE FIELD FLYBACK (VERTICAL BLANKING) PERIOD. 2612702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 2613702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * PROVIDED THE FIELD BUFFER CONTAINS GOOD DATA AS INDICATED BY A ZERO UPPER 2614702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * BYTE OF 2615702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * peasycap->field_buffer[peasycap->field_fill][0].kount 2616702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * THE CONTENTS OF THE FIELD BUFFER ARE OFFERED TO dqbuf(), field_read IS 2617702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * UPDATED AND field_fill IS BUMPED. IF THE FIELD BUFFER CONTAINS BAD DATA 2618702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * NOTHING IS OFFERED TO dqbuf(). 2619702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 2620702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * THE DECISION ON WHETHER THE PARITY OF THE OFFERED FIELD BUFFER IS RIGHT 2621702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * RESTS WITH dqbuf(). 2622702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 2623702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 2624c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if ((8 == more) || override) { 2625c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (videofieldamount > 2626c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->videofieldamount) { 2627c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (2 == videofieldamount - 2628c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap-> 2629c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler videofieldamount) { 2630c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap->field_buffer 2631c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_fill] 2632c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [0].kount) |= 0x0100; 2633c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_junk += (1 + 2634c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler VIDEO_JUNK_TOLERATE); 2635c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else 2636c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap->field_buffer 2637c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_fill] 2638c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [0].kount) |= 0x4000; 2639c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else if (videofieldamount < 2640c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap-> 2641c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler videofieldamount) { 2642c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap->field_buffer 2643c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_fill] 2644c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [0].kount) |= 0x2000; 2645c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2646c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bad = 0xFF00 & peasycap->field_buffer 2647c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_fill] 2648c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [0].kount; 2649c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!bad) { 2650c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap->video_junk)--; 2651c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (-VIDEO_JUNK_TOLERATE > 2652c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_junk) 2653c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_junk = 2654c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler -VIDEO_JUNK_TOLERATE; 2655c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_read = 2656c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap-> 2657c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler field_fill)++; 2658c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (FIELD_BUFFER_MANY <= 2659c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap-> 2660c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler field_fill) 26611dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler peasycap-> 2662c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler field_fill = 0; 2663c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_page = 0; 2664c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer = &peasycap-> 2665c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler field_buffer 2666c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap-> 2667c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler field_fill] 2668c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap-> 2669c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler field_page]; 2670c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer->pto = 2671c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer->pgo; 2672c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "bumped to: %i=" 2673c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "peasycap->" 2674c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "field_fill %i=" 2675c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "parity\n", 2676c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_fill, 2677c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0x00FF & 2678c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer->kount); 2679c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "field buffer %i has " 2680c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "%i bytes fit to be " 2681c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "read\n", 2682c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_read, 2683c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler videofieldamount); 2684c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "wakeup call to " 2685c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "wq_video, " 2686c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "%i=field_read " 2687c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "%i=field_fill " 2688c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "%i=parity\n", 2689c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_read, 2690c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_fill, 2691c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0x00FF & peasycap-> 2692c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler field_buffer 2693c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap-> 2694c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler field_read][0].kount); 2695c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler wake_up_interruptible 2696c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (&(peasycap-> 2697c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler wq_video)); 2698c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 2699c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_junk++; 2700c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (bad & 0x0010) 2701c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_junk += 2702c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (1 + VIDEO_JUNK_TOLERATE/2); 2703c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "field buffer %i had %i " 2704c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "bytes, now discarded: " 2705c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "0x%04X\n", 2706c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_fill, 2707c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler videofieldamount, 2708c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (0xFF00 & 2709c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_buffer 2710c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_fill][0]. 2711c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler kount)); 2712c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap->field_fill)++; 2713c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 2714c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (FIELD_BUFFER_MANY <= 2715c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_fill) 2716c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_fill = 0; 2717f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas peasycap->field_page = 0; 2718c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer = 2719c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler &peasycap->field_buffer 2720c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_fill] 2721c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_page]; 27221dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler pfield_buffer->pto = 2723c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer->pgo; 2724c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 2725c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "bumped to: %i=peasycap->" 2726c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "field_fill %i=parity\n", 27271dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler peasycap->field_fill, 2728c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0x00FF & pfield_buffer->kount); 2729c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2730c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (8 == more) { 2731c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "end-of-field: received " 2732c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "parity byte 0x%02X\n", 2733c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (0xFF & *pu)); 2734c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0x40 & *pu) 2735c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer->kount = 0x0000; 2736c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler else 2737c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer->kount = 0x0001; 2738c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer->input = 0x08 | 2739c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (0x07 & peasycap->input); 2740c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(8, "end-of-field: 0x%02X=kount\n", 2741c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 0xFF & pfield_buffer->kount); 2742c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2743702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2744702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 2745702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 2746702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * COPY more BYTES FROM ISOC BUFFER TO FIELD BUFFER 2747702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 2748702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 2749c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pu += leap; 2750c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler more -= leap; 2751702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 2752c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (FIELD_BUFFER_MANY <= peasycap->field_fill) { 2753c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: bad peasycap->field_fill\n"); 2754702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas return; 2755702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2756c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (FIELD_BUFFER_SIZE/PAGE_SIZE <= peasycap->field_page) { 2757c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: bad peasycap->field_page\n"); 2758c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 2759c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2760c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer = &peasycap->field_buffer 2761c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_fill][peasycap->field_page]; 2762c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler while (more) { 2763c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer = &peasycap->field_buffer 27641dc6e41825aa270cfc0166beb54afb1c235dc803Tomas Winkler [peasycap->field_fill] 2765702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas [peasycap->field_page]; 2766c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (PAGE_SIZE < (pfield_buffer->pto - 2767c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer->pgo)) { 2768c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: bad pfield_buffer->pto\n"); 2769c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 2770c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2771c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (PAGE_SIZE == (pfield_buffer->pto - 2772c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer->pgo)) { 2773c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap->field_page)++; 2774c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (FIELD_BUFFER_SIZE/PAGE_SIZE <= 2775c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_page) { 2776c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(16, "wrapping peasycap->" 2777c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "field_page\n"); 2778c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->field_page = 0; 2779c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2780c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer = &peasycap-> 2781c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler field_buffer 2782c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_fill] 2783c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_page]; 2784c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer->pto = pfield_buffer->pgo; 2785c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer->input = 0x08 | 2786c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (0x07 & peasycap->input); 2787c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if ((peasycap->field_buffer[peasycap-> 2788c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler field_fill][0]). 2789c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler input != 2790c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pfield_buffer->input) 2791c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap->field_buffer 2792c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [peasycap->field_fill] 2793c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler [0]).kount |= 0x1000; 2794c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2795702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 2796c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler much = PAGE_SIZE - 2797c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (int)(pfield_buffer->pto - 2798702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas pfield_buffer->pgo); 2799702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 2800c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (much > more) 2801c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler much = more; 2802c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler memcpy(pfield_buffer->pto, pu, much); 2803c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler pu += much; 2804c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (pfield_buffer->pto) += much; 2805c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler more -= much; 2806c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2807702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2808702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2809702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2810702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2811702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 2812702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 2813702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * RESUBMIT THIS URB, UNLESS A SEVERE PERSISTENT ERROR CONDITION EXISTS. 2814702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * 2815702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * IF THE WAIT QUEUES ARE NOT CLEARED IN RESPONSE TO AN ERROR CONDITION 2816702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT. BEWARE. 2817702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 2818702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 2819c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (VIDEO_ISOC_BUFFER_MANY <= peasycap->video_junk) { 2820c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("easycap driver shutting down on condition green\n"); 2821c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->status = 1; 2822c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_eof = 1; 2823c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_junk = 0; 2824c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler wake_up_interruptible(&peasycap->wq_video); 2825f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas#if !defined(PERSEVERE) 2826c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->audio_eof = 1; 2827c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler wake_up_interruptible(&peasycap->wq_audio); 2828f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas#endif /*PERSEVERE*/ 2829c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 2830702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 2831c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (peasycap->video_isoc_streaming) { 2832c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler rc = usb_submit_urb(purb, GFP_ATOMIC); 2833c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (rc) { 2834c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("%s: %d\n", strerror(rc), rc); 2835c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (-ENODEV != rc) 2836c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: while %i=video_idle, " 2837c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "usb_submit_urb() " 2838c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "failed with rc:\n", 2839c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->video_idle); 2840c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2841c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 2842c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 2843702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 28440b217d2125acc039d2f3a94f01821472fbbb75b6Tomas Winkler 2845d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic const struct v4l2_file_operations v4l2_fops = { 2846d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .owner = THIS_MODULE, 2847d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .open = easycap_open_noinode, 2848f2b3c685b9b1c048cfa8bef98dac037275b9d20dTomas Winkler .unlocked_ioctl = easycap_unlocked_ioctl, 2849d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .poll = easycap_poll, 2850d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .mmap = easycap_mmap, 2851d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler}; 28522bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa 2853702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 28542bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa * When the device is plugged, this function is called three times, 28552bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa * one for each interface. 2856702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 285711ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winklerstatic int easycap_usb_probe(struct usb_interface *intf, 285811ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler const struct usb_device_id *id) 2859702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 286011ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler struct usb_device *usbdev; 286111ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler struct usb_host_interface *alt; 286211ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler struct usb_endpoint_descriptor *ep; 286311ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler struct usb_interface_descriptor *interface; 28647dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler struct urb *purb; 28657dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler struct easycap *peasycap; 28667dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler int ndong; 28677dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler struct data_urb *pdata_urb; 28681d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler int i, j, k, m, rc; 28697dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler u8 bInterfaceNumber; 28707dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler u8 bInterfaceClass; 28717dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler u8 bInterfaceSubClass; 28727dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler void *pbuf; 28737dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler int okalt[8], isokalt; 28747dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler int okepn[8]; 28757dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler int okmps[8]; 28767dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler int maxpacketsize; 28777dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler u16 mask; 28787dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler s32 value; 28797dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler struct easycap_format *peasycap_format; 2880b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler int fmtidx; 2881b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler struct inputset *inputset; 2882702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 288311ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler usbdev = interface_to_usbdev(intf); 2884ee99aa4928129d4aad9087988db6b7815ecdc1d5Tomas Winkler 288511ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler alt = usb_altnum_to_altsetting(intf, 0); 288611ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler if (!alt) { 288711ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler SAY("ERROR: usb_host_interface not found\n"); 28887dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 28897dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 2890101dca425da49edb3093000d72490216fa322911Tomas Winkler 289111ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler interface = &alt->desc; 289211ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler if (!interface) { 289311ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler SAY("ERROR: intf_descriptor is NULL\n"); 28947dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 28957dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 28962bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa 28972bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa /* Get properties of probed interface */ 289811ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler bInterfaceNumber = interface->bInterfaceNumber; 289911ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler bInterfaceClass = interface->bInterfaceClass; 290011ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler bInterfaceSubClass = interface->bInterfaceSubClass; 29017dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler 2902e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler JOT(4, "intf[%i]: num_altsetting=%i\n", 290311ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler bInterfaceNumber, intf->num_altsetting); 2904e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler JOT(4, "intf[%i]: cur_altsetting - altsetting=%li\n", 2905e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler bInterfaceNumber, 290611ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler (long int)(intf->cur_altsetting - intf->altsetting)); 2907e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler JOT(4, "intf[%i]: bInterfaceClass=0x%02X bInterfaceSubClass=0x%02X\n", 2908e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler bInterfaceNumber, bInterfaceClass, bInterfaceSubClass); 29092bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa 29102bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa /* 29112bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa * A new struct easycap is always allocated when interface 0 is probed. 29122bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa * It is not possible here to free any existing struct easycap. 29132bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa * This should have been done by easycap_delete() when the device was 29142bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa * physically unplugged. 29152bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa * The allocated struct easycap is saved for later usage when 29162bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa * interfaces 1 and 2 are probed. 29172bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa */ 29187dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (0 == bInterfaceNumber) { 29197dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap = kzalloc(sizeof(struct easycap), GFP_KERNEL); 29206888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 29217dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAY("ERROR: Could not allocate peasycap\n"); 29227dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOMEM; 29237dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 29242bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa 29252bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa /* Perform urgent initializations */ 29267dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->minor = -1; 29277dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler kref_init(&peasycap->kref); 29287dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(8, "intf[%i]: after kref_init(..._video) " 29297dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "%i=peasycap->kref.refcount.counter\n", 29307dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler bInterfaceNumber, peasycap->kref.refcount.counter); 2931702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 29327dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler /* module params */ 29337dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->gain = (s8)clamp(easycap_gain, 0, 31); 29342a9a05c43294d703e351753da49231c47e0aad0dTomas Winkler 29357dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler init_waitqueue_head(&peasycap->wq_video); 29367dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler init_waitqueue_head(&peasycap->wq_audio); 29377dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler init_waitqueue_head(&peasycap->wq_trigger); 2938e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas 29397dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (mutex_lock_interruptible(&mutex_dongle)) { 2940dfcce7bf0913cc81d57a41d8da3175b201ec1664Tomas Winkler SAY("ERROR: cannot down mutex_dongle\n"); 29417dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ERESTARTSYS; 2942101dca425da49edb3093000d72490216fa322911Tomas Winkler } 2943101dca425da49edb3093000d72490216fa322911Tomas Winkler 2944101dca425da49edb3093000d72490216fa322911Tomas Winkler for (ndong = 0; ndong < DONGLE_MANY; ndong++) { 2945101dca425da49edb3093000d72490216fa322911Tomas Winkler if ((!easycapdc60_dongle[ndong].peasycap) && 2946101dca425da49edb3093000d72490216fa322911Tomas Winkler (!mutex_is_locked(&easycapdc60_dongle 2947101dca425da49edb3093000d72490216fa322911Tomas Winkler [ndong].mutex_video)) && 2948101dca425da49edb3093000d72490216fa322911Tomas Winkler (!mutex_is_locked(&easycapdc60_dongle 2949101dca425da49edb3093000d72490216fa322911Tomas Winkler [ndong].mutex_audio))) { 2950101dca425da49edb3093000d72490216fa322911Tomas Winkler easycapdc60_dongle[ndong].peasycap = peasycap; 2951101dca425da49edb3093000d72490216fa322911Tomas Winkler peasycap->isdongle = ndong; 2952101dca425da49edb3093000d72490216fa322911Tomas Winkler JOM(8, "intf[%i]: peasycap-->easycap" 2953101dca425da49edb3093000d72490216fa322911Tomas Winkler "_dongle[%i].peasycap\n", 2954101dca425da49edb3093000d72490216fa322911Tomas Winkler bInterfaceNumber, ndong); 2955101dca425da49edb3093000d72490216fa322911Tomas Winkler break; 2956ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas } 2957101dca425da49edb3093000d72490216fa322911Tomas Winkler } 2958101dca425da49edb3093000d72490216fa322911Tomas Winkler 2959101dca425da49edb3093000d72490216fa322911Tomas Winkler if (DONGLE_MANY <= ndong) { 2960101dca425da49edb3093000d72490216fa322911Tomas Winkler SAM("ERROR: too many dongles\n"); 2961a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas mutex_unlock(&mutex_dongle); 2962101dca425da49edb3093000d72490216fa322911Tomas Winkler return -ENOMEM; 2963a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas } 2964101dca425da49edb3093000d72490216fa322911Tomas Winkler mutex_unlock(&mutex_dongle); 2965101dca425da49edb3093000d72490216fa322911Tomas Winkler 29667dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->allocation_video_struct = sizeof(struct easycap); 2967e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas 29682bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa /* and further initialize the structure */ 296911ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler peasycap->pusb_device = usbdev; 297011ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler peasycap->pusb_interface = intf; 2971702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 29727dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->microphone = false; 2973702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 29747dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_interface = -1; 29757dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_altsetting_on = -1; 29767dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_altsetting_off = -1; 29777dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_endpointnumber = -1; 29787dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_maxframesize = -1; 29797dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_buffer_size = -1; 2980702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 29817dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_interface = -1; 29827dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_altsetting_on = -1; 29837dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_altsetting_off = -1; 29847dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_endpointnumber = -1; 29857dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_maxframesize = -1; 29867dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_buffer_size = -1; 2987702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 29887dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->frame_buffer_many = FRAME_BUFFER_MANY; 2989e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas 29902bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa /* Dynamically fill in the available formats */ 299196bec7dd72511e3c16588d9af52da2cc937f7ea1Tomas Winkler rc = easycap_video_fillin_formats(); 29927dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (0 > rc) { 2993c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: fillin_formats() rc = %i\n", rc); 29947dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 29957dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 29967dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%i formats available\n", rc); 29977dfdae8e32a26ef3b3aa8d114d2fed93d7680169Tomas Winkler 29982bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa /* Populate easycap.inputset[] */ 2999b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler inputset = peasycap->inputset; 3000b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler fmtidx = peasycap->ntsc ? NTSC_M : PAL_BGHIN; 3001b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler m = 0; 3002b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler mask = 0; 3003b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler for (i = 0; 0xFFFF != easycap_standard[i].mask; i++) { 3004b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler if (fmtidx == easycap_standard[i].v4l2_standard.index) { 3005b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler m++; 3006b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler for (k = 0; k < INPUT_MANY; k++) 3007b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler inputset[k].standard_offset = i; 3008b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler 30097dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler mask = easycap_standard[i].mask; 3010f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 3011f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 30127dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (1 != m) { 3013b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler SAM("ERROR: " 3014b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler "inputset->standard_offset unpopulated, %i=m\n", m); 30157dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOENT; 30167dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 30177dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler 30187dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap_format = &easycap_format[0]; 3019f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas m = 0; 3020b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler for (i = 0; peasycap_format->v4l2_format.fmt.pix.width; i++) { 3021b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler struct v4l2_pix_format *pix = 3022b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler &peasycap_format->v4l2_format.fmt.pix; 30237dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (((peasycap_format->mask & 0x0F) == (mask & 0x0F)) && 3024b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler pix->field == V4L2_FIELD_NONE && 3025b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler pix->pixelformat == V4L2_PIX_FMT_UYVY && 3026b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler pix->width == 640 && pix->height == 480) { 3027f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas m++; 30287dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (k = 0; k < INPUT_MANY; k++) 3029b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler inputset[k].format_offset = i; 30307dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler break; 3031f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 3032e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler peasycap_format++; 3033f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 30347dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (1 != m) { 3035b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler SAM("ERROR: inputset[]->format_offset unpopulated\n"); 3036e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler return -ENOENT; 3037f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 3038f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas 30397dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler m = 0; 3040b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler for (i = 0; 0xFFFFFFFF != easycap_control[i].id; i++) { 30417dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler value = easycap_control[i].default_value; 30427dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (V4L2_CID_BRIGHTNESS == easycap_control[i].id) { 30437dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler m++; 30447dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (k = 0; k < INPUT_MANY; k++) 3045b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler inputset[k].brightness = value; 30467dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else if (V4L2_CID_CONTRAST == easycap_control[i].id) { 30477dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler m++; 30487dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (k = 0; k < INPUT_MANY; k++) 3049b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler inputset[k].contrast = value; 30507dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else if (V4L2_CID_SATURATION == easycap_control[i].id) { 30517dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler m++; 30527dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (k = 0; k < INPUT_MANY; k++) 3053b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler inputset[k].saturation = value; 30547dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else if (V4L2_CID_HUE == easycap_control[i].id) { 30557dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler m++; 30567dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (k = 0; k < INPUT_MANY; k++) 3057b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler inputset[k].hue = value; 30587dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3059f36bc37a48148f31f936557b811431b98dbfe347Mike Thomas } 3060e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler 30617dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (4 != m) { 3062b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler SAM("ERROR: inputset[]->brightness underpopulated\n"); 30637dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOENT; 30647dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 30657dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (k = 0; k < INPUT_MANY; k++) 3066b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler inputset[k].input = k; 3067b4a5916e6bdbd5585a961179799a59871d8722ccTomas Winkler JOM(4, "populated inputset[]\n"); 30687dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "finished initialization\n"); 30697dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else { 30702bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa 30712bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa /* 30722bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa * FIXME: Identify the appropriate pointer 30732bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa * peasycap for interfaces 1 and 2. 30742bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa * The address of peasycap->pusb_device 30752bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa * is reluctantly used for this purpose. 30762bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa */ 30777dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (ndong = 0; ndong < DONGLE_MANY; ndong++) { 307811ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler if (usbdev == easycapdc60_dongle[ndong].peasycap-> 30797dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pusb_device) { 30807dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap = easycapdc60_dongle[ndong].peasycap; 3081c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOT(8, "intf[%i]: dongle[%i].peasycap\n", 3082c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bInterfaceNumber, ndong); 30837dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler break; 30847dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 30857dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 30867dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (DONGLE_MANY <= ndong) { 30877dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAY("ERROR: peasycap is unknown when probing interface %i\n", 30887dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler bInterfaceNumber); 30897dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENODEV; 30907dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 30916888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 30927dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAY("ERROR: peasycap is NULL when probing interface %i\n", 30937dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler bInterfaceNumber); 30947dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENODEV; 3095a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas } 3096dfcce7bf0913cc81d57a41d8da3175b201ec1664Tomas Winkler } 30972bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa 30987dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if ((USB_CLASS_VIDEO == bInterfaceClass) || 3099dfcce7bf0913cc81d57a41d8da3175b201ec1664Tomas Winkler (USB_CLASS_VENDOR_SPEC == bInterfaceClass)) { 31007dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->video_interface) { 31017dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_interface = bInterfaceNumber; 31027dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "setting peasycap->video_interface=%i\n", 31037dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_interface); 31047dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else { 31057dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (peasycap->video_interface != bInterfaceNumber) { 31067dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: attempting to reset " 31077dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "peasycap->video_interface\n"); 31087dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("...... continuing with " 31097dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "%i=peasycap->video_interface\n", 3110702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas peasycap->video_interface); 31117dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3112702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 31137dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else if ((USB_CLASS_AUDIO == bInterfaceClass) && 3114fc3cc2caa07568de92cc84780b89b5cf9fbf28b7Tomas Winkler (USB_SUBCLASS_AUDIOSTREAMING == bInterfaceSubClass)) { 31157dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->audio_interface) { 31167dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_interface = bInterfaceNumber; 31177dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "setting peasycap->audio_interface=%i\n", 31187dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_interface); 31197dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else { 31207dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (peasycap->audio_interface != bInterfaceNumber) { 31217dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: attempting to reset " 31227dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "peasycap->audio_interface\n"); 31237dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("...... continuing with " 31247dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "%i=peasycap->audio_interface\n", 31257dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_interface); 31267dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3127702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 3128702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 3129702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 31302bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa /* 31312bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa * Investigate all altsettings. This is done in detail 31322bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa * because USB device 05e1:0408 has disparate incarnations. 31332bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa */ 31342bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa isokalt = 0; 313511ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler for (i = 0; i < intf->num_altsetting; i++) { 313611ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler alt = usb_altnum_to_altsetting(intf, i); 313711ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler if (!alt) { 313811ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler SAM("ERROR: alt is NULL\n"); 31397dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 3140702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 314111ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler interface = &alt->desc; 314211ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler if (!interface) { 314311ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler SAM("ERROR: intf_descriptor is NULL\n"); 31447dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 3145702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 31467dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler 314711ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler if (0 == interface->bNumEndpoints) 3148e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler JOM(4, "intf[%i]alt[%i] has no endpoints\n", 3149e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler bInterfaceNumber, i); 315011ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler for (j = 0; j < interface->bNumEndpoints; j++) { 315111ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler ep = &alt->endpoint[j].desc; 315211ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler if (!ep) { 315311ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler SAM("ERROR: ep is NULL.\n"); 31547dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("...... skipping\n"); 31557dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler continue; 31567dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 31571d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler 31581d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler if (!usb_endpoint_is_isoc_in(ep)) { 31591d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler JOM(4, "intf[%i]alt[%i]end[%i] is a %d endpoint\n", 31601d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler bInterfaceNumber, 31611d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler i, j, ep->bmAttributes); 31621d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler if (usb_endpoint_dir_out(ep)) { 31631d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler SAM("ERROR: OUT endpoint unexpected\n"); 31641d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler SAM("...... continuing\n"); 31651d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler } 31661d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler continue; 31677dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 31681d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler switch (bInterfaceClass) { 31691d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler case USB_CLASS_VIDEO: 31701d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler case USB_CLASS_VENDOR_SPEC: { 31711d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler if (ep->wMaxPacketSize) { 31721d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler if (8 > isokalt) { 31731d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler okalt[isokalt] = i; 31741d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler JOM(4, 31751d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "%i=okalt[%i]\n", 31761d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler okalt[isokalt], 31771d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler isokalt); 31781d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler okepn[isokalt] = 31791d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler ep-> 31801d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler bEndpointAddress & 31811d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler 0x0F; 31821d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler JOM(4, 31831d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "%i=okepn[%i]\n", 31841d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler okepn[isokalt], 31851d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler isokalt); 31861d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler okmps[isokalt] = 31871d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler le16_to_cpu(ep-> 31881d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler wMaxPacketSize); 31891d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler JOM(4, 31901d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "%i=okmps[%i]\n", 31911d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler okmps[isokalt], 31921d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler isokalt); 31931d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler isokalt++; 3194702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 31951d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler } else { 31961d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler if (-1 == peasycap-> 31971d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler video_altsetting_off) { 31981d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler peasycap-> 31991d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler video_altsetting_off = 32001d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler i; 32011d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler JOM(4, "%i=video_" 32021d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "altsetting_off " 32031d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "<====\n", 32041d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler peasycap-> 32051d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler video_altsetting_off); 32061d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler } else { 32071d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler SAM("ERROR: peasycap" 32081d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "->video_altsetting_" 32091d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "off already set\n"); 32101d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler SAM("...... " 32111d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "continuing with " 32121d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "%i=peasycap->video_" 32131d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "altsetting_off\n", 32141d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler peasycap-> 32151d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler video_altsetting_off); 32161d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler } 32171d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler } 32181d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler break; 32191d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler } 32201d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler case USB_CLASS_AUDIO: { 32211d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler if (bInterfaceSubClass != 32221d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler USB_SUBCLASS_AUDIOSTREAMING) 3223702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas break; 32241d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler if (!peasycap) { 32251d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler SAM("MISTAKE: " 32261d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "peasycap is NULL\n"); 32271d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler return -EFAULT; 32281d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler } 32291d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler if (ep->wMaxPacketSize) { 32301d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler if (8 > isokalt) { 32311d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler okalt[isokalt] = i ; 32321d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler JOM(4, 32331d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "%i=okalt[%i]\n", 32341d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler okalt[isokalt], 32351d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler isokalt); 32361d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler okepn[isokalt] = 32371d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler ep-> 32381d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler bEndpointAddress & 32391d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler 0x0F; 32401d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler JOM(4, 32411d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "%i=okepn[%i]\n", 32421d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler okepn[isokalt], 32431d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler isokalt); 32441d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler okmps[isokalt] = 32451d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler le16_to_cpu(ep-> 32461d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler wMaxPacketSize); 32471d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler JOM(4, 32481d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "%i=okmps[%i]\n", 32491d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler okmps[isokalt], 32501d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler isokalt); 32511d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler isokalt++; 32527dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 32531d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler } else { 32541d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler if (-1 == peasycap-> 32551d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler audio_altsetting_off) { 32561d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler peasycap-> 32571d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler audio_altsetting_off = 32581d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler i; 32591d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler JOM(4, "%i=audio_" 32601d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "altsetting_off " 32611d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "<====\n", 32621d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler peasycap-> 32631d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler audio_altsetting_off); 32641d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler } else { 32651d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler SAM("ERROR: peasycap" 32661d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "->audio_altsetting_" 32671d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "off already set\n"); 32681d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler SAM("...... " 32691d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "continuing with " 32701d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "%i=peasycap->" 32711d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "audio_altsetting_" 32721d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler "off\n", 32731d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler peasycap-> 32741d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler audio_altsetting_off); 32757dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3276702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 32771d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler break; 32781d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler } 32791d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler default: 32801d243c2e18a6070f4029b774966c51967c3240e0Tomas Winkler break; 32817dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 328211ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler if (0 == ep->wMaxPacketSize) { 32837dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "intf[%i]alt[%i]end[%i] " 32847dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "has zero packet size\n", 32857dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler bInterfaceNumber, i, j); 3286702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 3287702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 3288702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 32892bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa 32902bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa /* Perform initialization of the probed interface */ 32917dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "initialization begins for interface %i\n", 329211ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler interface->bInterfaceNumber); 32937dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler switch (bInterfaceNumber) { 32942bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa /* 0: Video interface */ 32957dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler case 0: { 32967dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (!peasycap) { 32977dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: peasycap is NULL\n"); 32987dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 32997dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 33007dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (!isokalt) { 33017dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: no viable video_altsetting_on\n"); 33027dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOENT; 33037dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3304101dca425da49edb3093000d72490216fa322911Tomas Winkler peasycap->video_altsetting_on = okalt[isokalt - 1]; 3305101dca425da49edb3093000d72490216fa322911Tomas Winkler JOM(4, "%i=video_altsetting_on <====\n", 3306101dca425da49edb3093000d72490216fa322911Tomas Winkler peasycap->video_altsetting_on); 33072bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa 33082bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa /* Decide video streaming parameters */ 33097dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_endpointnumber = okepn[isokalt - 1]; 33107dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%i=video_endpointnumber\n", peasycap->video_endpointnumber); 33117dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler maxpacketsize = okmps[isokalt - 1]; 3312e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler 3313e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler peasycap->video_isoc_maxframesize = 3314e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler min(maxpacketsize, USB_2_0_MAXPACKETSIZE); 33157dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (0 >= peasycap->video_isoc_maxframesize) { 33167dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: bad video_isoc_maxframesize\n"); 33177dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM(" possibly because port is USB 1.1\n"); 33187dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOENT; 33197dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3320e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler JOM(4, "%i=video_isoc_maxframesize\n", 3321e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler peasycap->video_isoc_maxframesize); 3322e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler 33237dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_framesperdesc = VIDEO_ISOC_FRAMESPERDESC; 33247dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%i=video_isoc_framesperdesc\n", 33257dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_framesperdesc); 33267dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (0 >= peasycap->video_isoc_framesperdesc) { 33277dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: bad video_isoc_framesperdesc\n"); 33287dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOENT; 33297dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 33307dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_buffer_size = 33317dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_maxframesize * 33327dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_framesperdesc; 33337dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%i=video_isoc_buffer_size\n", 33347dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_buffer_size); 33357dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if ((PAGE_SIZE << VIDEO_ISOC_ORDER) < 33367dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_buffer_size) { 33377dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: peasycap->video_isoc_buffer_size too big\n"); 33387dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 33397dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 33407dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->video_interface) { 33417dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: video_interface is unset\n"); 33427dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 33437dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 33447dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->video_altsetting_on) { 33457dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: video_altsetting_on is unset\n"); 33467dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 33477dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 33487dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->video_altsetting_off) { 33497dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: video_interface_off is unset\n"); 33507dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 33517dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 33527dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->video_endpointnumber) { 33537dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: video_endpointnumber is unset\n"); 33547dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 33557dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 33567dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->video_isoc_maxframesize) { 33577dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: video_isoc_maxframesize is unset\n"); 33587dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 33597dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 33607dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->video_isoc_buffer_size) { 33617dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: video_isoc_buffer_size is unset\n"); 33627dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 33637dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 33642bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa 33652bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa /* 33662bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa * Allocate memory for video buffers. 33672bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa * Lists must be initialized first. 33682bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa */ 33697dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler INIT_LIST_HEAD(&(peasycap->urb_video_head)); 33707dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->purb_video_head = &(peasycap->urb_video_head); 33717dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "allocating %i frame buffers of size %li\n", 33727dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler FRAME_BUFFER_MANY, (long int)FRAME_BUFFER_SIZE); 33737dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, ".... each scattered over %li pages\n", 33747dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler FRAME_BUFFER_SIZE/PAGE_SIZE); 33757dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler 33767dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (k = 0; k < FRAME_BUFFER_MANY; k++) { 33777dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) { 33786888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (peasycap->frame_buffer[k][m].pgo) 33797dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("attempting to reallocate frame " 33807dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler " buffers\n"); 33817dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler else { 33827dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pbuf = (void *)__get_free_page(GFP_KERNEL); 33836888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pbuf) { 33847dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: Could not allocate frame " 33857dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "buffer %i page %i\n", k, m); 33867dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOMEM; 3387101dca425da49edb3093000d72490216fa322911Tomas Winkler } 3388101dca425da49edb3093000d72490216fa322911Tomas Winkler 3389101dca425da49edb3093000d72490216fa322911Tomas Winkler peasycap->allocation_video_page += 1; 33907dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->frame_buffer[k][m].pgo = pbuf; 33917dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 33927dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->frame_buffer[k][m].pto = 33937dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->frame_buffer[k][m].pgo; 3394702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 3395702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 3396702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 33977dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->frame_fill = 0; 33987dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->frame_read = 0; 33997dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "allocation of frame buffers done: %i pages\n", k * 34007dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler m); 34017dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "allocating %i field buffers of size %li\n", 34027dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler FIELD_BUFFER_MANY, (long int)FIELD_BUFFER_SIZE); 34037dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, ".... each scattered over %li pages\n", 34047dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler FIELD_BUFFER_SIZE/PAGE_SIZE); 34057dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler 34067dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (k = 0; k < FIELD_BUFFER_MANY; k++) { 34077dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) { 34086888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (peasycap->field_buffer[k][m].pgo) { 34097dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: attempting to reallocate " 34107dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "field buffers\n"); 34117dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else { 34127dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pbuf = (void *) __get_free_page(GFP_KERNEL); 34136888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pbuf) { 34147dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: Could not allocate field" 34157dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler " buffer %i page %i\n", k, m); 34167dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOMEM; 3417702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 3418101dca425da49edb3093000d72490216fa322911Tomas Winkler 3419101dca425da49edb3093000d72490216fa322911Tomas Winkler peasycap->allocation_video_page += 1; 3420101dca425da49edb3093000d72490216fa322911Tomas Winkler peasycap->field_buffer[k][m].pgo = pbuf; 3421101dca425da49edb3093000d72490216fa322911Tomas Winkler } 34227dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->field_buffer[k][m].pto = 34237dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->field_buffer[k][m].pgo; 34247dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 34257dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->field_buffer[k][0].kount = 0x0200; 3426702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 34277dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->field_fill = 0; 34287dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->field_page = 0; 34297dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->field_read = 0; 34307dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "allocation of field buffers done: %i pages\n", k * 34317dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler m); 34327dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "allocating %i isoc video buffers of size %i\n", 34337dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler VIDEO_ISOC_BUFFER_MANY, 34347dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_buffer_size); 34357dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, ".... each occupying contiguous memory pages\n"); 34367dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler 34377dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { 3438a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler pbuf = (void *)__get_free_pages(GFP_KERNEL, 3439a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler VIDEO_ISOC_ORDER); 34406888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pbuf) { 34417dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: Could not allocate isoc video buffer " 34427dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "%i\n", k); 34437dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOMEM; 3444101dca425da49edb3093000d72490216fa322911Tomas Winkler } 3445101dca425da49edb3093000d72490216fa322911Tomas Winkler peasycap->allocation_video_page += 3446101dca425da49edb3093000d72490216fa322911Tomas Winkler BIT(VIDEO_ISOC_ORDER); 3447702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 34487dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_buffer[k].pgo = pbuf; 3449a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->video_isoc_buffer[k].pto = 3450a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler pbuf + peasycap->video_isoc_buffer_size; 34517dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_buffer[k].kount = k; 34527dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 34537dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "allocation of isoc video buffers done: %i pages\n", 34547dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler k * (0x01 << VIDEO_ISOC_ORDER)); 34552bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa 34562bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa /* Allocate and initialize multiple struct usb */ 34577dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY); 34587dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "using %i=peasycap->video_isoc_framesperdesc\n", 34597dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_framesperdesc); 34607dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "using %i=peasycap->video_isoc_maxframesize\n", 34617dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_maxframesize); 34627dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "using %i=peasycap->video_isoc_buffer_sizen", 34637dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_buffer_size); 34647dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler 34657dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { 34667dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb = usb_alloc_urb(peasycap->video_isoc_framesperdesc, 34677dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler GFP_KERNEL); 34686888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!purb) { 34697dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: usb_alloc_urb returned NULL for buffer " 34707dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "%i\n", k); 34717dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOMEM; 3472101dca425da49edb3093000d72490216fa322911Tomas Winkler } 3473101dca425da49edb3093000d72490216fa322911Tomas Winkler 3474101dca425da49edb3093000d72490216fa322911Tomas Winkler peasycap->allocation_video_urb += 1; 34757dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL); 34766888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pdata_urb) { 34777dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: Could not allocate struct data_urb.\n"); 34787dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOMEM; 3479101dca425da49edb3093000d72490216fa322911Tomas Winkler } 3480101dca425da49edb3093000d72490216fa322911Tomas Winkler 3481101dca425da49edb3093000d72490216fa322911Tomas Winkler peasycap->allocation_video_struct += 34827dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler sizeof(struct data_urb); 3483702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 34847dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pdata_urb->purb = purb; 34857dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pdata_urb->isbuf = k; 34867dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pdata_urb->length = 0; 34877dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler list_add_tail(&(pdata_urb->list_head), 34887dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->purb_video_head); 34892bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa 34902bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa /* Initialize allocated urbs */ 34917dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (!k) { 34927dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "initializing video urbs thus:\n"); 34937dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->interval = 1;\n"); 34947dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->dev = peasycap->pusb_device;\n"); 34957dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->pipe = usb_rcvisocpipe" 34967dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "(peasycap->pusb_device,%i);\n", 34977dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_endpointnumber); 34987dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n"); 34997dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->transfer_buffer = peasycap->" 35007dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "video_isoc_buffer[.].pgo;\n"); 35017dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->transfer_buffer_length = %i;\n", 35027dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_buffer_size); 35037dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->complete = easycap_complete;\n"); 35047dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->context = peasycap;\n"); 35057dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->start_frame = 0;\n"); 35067dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->number_of_packets = %i;\n", 35077dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_framesperdesc); 35087dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " for (j = 0; j < %i; j++)\n", 35097dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_framesperdesc); 35107dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " {\n"); 35117dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n", 35127dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_maxframesize); 35137dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->iso_frame_desc[j].length = %i;\n", 35147dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_maxframesize); 35157dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " }\n"); 35167dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3517702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 35187dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->interval = 1; 35197dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->dev = peasycap->pusb_device; 35207dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, 35217dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_endpointnumber); 35227dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->transfer_flags = URB_ISO_ASAP; 35237dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->transfer_buffer = peasycap->video_isoc_buffer[k].pgo; 35247dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->transfer_buffer_length = 35257dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_buffer_size; 35267dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->complete = easycap_complete; 35277dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->context = peasycap; 35287dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->start_frame = 0; 35297dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->number_of_packets = peasycap->video_isoc_framesperdesc; 35307dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (j = 0; j < peasycap->video_isoc_framesperdesc; j++) { 35317dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->iso_frame_desc[j].offset = j * 35327dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_maxframesize; 35337dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->iso_frame_desc[j].length = 35347dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_isoc_maxframesize; 35357dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3536702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 35377dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "allocation of %i struct urb done.\n", k); 35382bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa 35392bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa /* Save pointer peasycap in this interface */ 354011ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler usb_set_intfdata(intf, peasycap); 35412bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa 35422bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa /* 35432bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa * It is essential to initialize the hardware before, 35442bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa * rather than after, the device is registered, 3545d994c46d4309df85aea86049024cadfcbf523116Ezequiel GarcÃa * because some udev rules triggers easycap_open() 3546d994c46d4309df85aea86049024cadfcbf523116Ezequiel GarcÃa * immediately after registration, causing a clash. 35472bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa */ 35488d6139547ca349f9acea6536dd6b7f6140d3507fTomas Winkler peasycap->ntsc = easycap_ntsc; 35498d6139547ca349f9acea6536dd6b7f6140d3507fTomas Winkler JOM(8, "defaulting initially to %s\n", 35508d6139547ca349f9acea6536dd6b7f6140d3507fTomas Winkler easycap_ntsc ? "NTSC" : "PAL"); 35517dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler rc = reset(peasycap); 35527dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (rc) { 3553c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: reset() rc = %i\n", rc); 35547dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 35557dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 35562bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa 35572bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa /* The video device can now be registered */ 3558cdaa898b5efcc598ab1004e8f913061dc7005091Tomas Winkler if (v4l2_device_register(&intf->dev, &peasycap->v4l2_device)) { 35597dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("v4l2_device_register() failed\n"); 35607dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENODEV; 35617dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3562cdaa898b5efcc598ab1004e8f913061dc7005091Tomas Winkler JOM(4, "registered device instance: %s\n", 3563cdaa898b5efcc598ab1004e8f913061dc7005091Tomas Winkler peasycap->v4l2_device.name); 35642bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa 35652bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa /* 35662bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa * FIXME: This is believed to be harmless, 35672bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa * but may well be unnecessary or wrong. 35682bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa */ 35697dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_device.v4l2_dev = NULL; 3570702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 3571e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas 35727dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler strcpy(&peasycap->video_device.name[0], "easycapdc60"); 35737dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_device.fops = &v4l2_fops; 35747dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_device.minor = -1; 35757dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_device.release = (void *)(&videodev_release); 3576702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 35777dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler video_set_drvdata(&(peasycap->video_device), (void *)peasycap); 3578702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 35797dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (0 != (video_register_device(&(peasycap->video_device), 35807dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler VFL_TYPE_GRABBER, -1))) { 35817dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler err("Not able to register with videodev"); 35827dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler videodev_release(&(peasycap->video_device)); 35837dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENODEV; 35847dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3585101dca425da49edb3093000d72490216fa322911Tomas Winkler 3586101dca425da49edb3093000d72490216fa322911Tomas Winkler peasycap->registered_video++; 3587101dca425da49edb3093000d72490216fa322911Tomas Winkler SAM("registered with videodev: %i=minor\n", 3588101dca425da49edb3093000d72490216fa322911Tomas Winkler peasycap->video_device.minor); 3589101dca425da49edb3093000d72490216fa322911Tomas Winkler peasycap->minor = peasycap->video_device.minor; 3590a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas 35917dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler break; 3592dfcce7bf0913cc81d57a41d8da3175b201ec1664Tomas Winkler } 35932bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa /* 1: Audio control */ 35947dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler case 1: { 35957dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (!peasycap) { 35967dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: peasycap is NULL\n"); 35977dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 35987dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 35992bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa /* Save pointer peasycap in this interface */ 360011ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler usb_set_intfdata(intf, peasycap); 36017dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "no initialization required for interface %i\n", 360211ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler interface->bInterfaceNumber); 36037dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler break; 3604702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 36052bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa /* 2: Audio streaming */ 36067dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler case 2: { 36077dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (!peasycap) { 36087dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: peasycap is NULL\n"); 36097dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 36107dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 36117dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (!isokalt) { 36127dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: no viable audio_altsetting_on\n"); 36137dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOENT; 36147dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3615101dca425da49edb3093000d72490216fa322911Tomas Winkler peasycap->audio_altsetting_on = okalt[isokalt - 1]; 3616101dca425da49edb3093000d72490216fa322911Tomas Winkler JOM(4, "%i=audio_altsetting_on <====\n", 3617101dca425da49edb3093000d72490216fa322911Tomas Winkler peasycap->audio_altsetting_on); 3618e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas 36197dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_endpointnumber = okepn[isokalt - 1]; 36207dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%i=audio_endpointnumber\n", peasycap->audio_endpointnumber); 3621e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas 36227dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_maxframesize = okmps[isokalt - 1]; 36237dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%i=audio_isoc_maxframesize\n", 36247dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_maxframesize); 36257dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (0 >= peasycap->audio_isoc_maxframesize) { 36267dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: bad audio_isoc_maxframesize\n"); 36277dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOENT; 36287dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 36297dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (9 == peasycap->audio_isoc_maxframesize) { 36307dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->ilk |= 0x02; 36317dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("audio hardware is microphone\n"); 36327dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->microphone = true; 3633a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->audio_pages_per_fragment = 3634a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler PAGES_PER_AUDIO_FRAGMENT; 36357dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else if (256 == peasycap->audio_isoc_maxframesize) { 36367dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->ilk &= ~0x02; 36377dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("audio hardware is AC'97\n"); 36387dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->microphone = false; 3639a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->audio_pages_per_fragment = 3640a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler PAGES_PER_AUDIO_FRAGMENT; 36417dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } else { 36427dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("hardware is unidentified:\n"); 36437dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("%i=audio_isoc_maxframesize\n", 3644a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->audio_isoc_maxframesize); 36457dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOENT; 36467dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3647702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 36487dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_bytes_per_fragment = 3649a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->audio_pages_per_fragment * PAGE_SIZE; 36507dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_buffer_page_many = (AUDIO_FRAGMENT_MANY * 3651a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->audio_pages_per_fragment); 36527dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler 36537dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%6i=AUDIO_FRAGMENT_MANY\n", AUDIO_FRAGMENT_MANY); 36547dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%6i=audio_pages_per_fragment\n", 36557dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_pages_per_fragment); 36567dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%6i=audio_bytes_per_fragment\n", 36577dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_bytes_per_fragment); 36587dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%6i=audio_buffer_page_many\n", 36597dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_buffer_page_many); 36607dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler 36617dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_framesperdesc = AUDIO_ISOC_FRAMESPERDESC; 36627dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler 36637dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%i=audio_isoc_framesperdesc\n", 36647dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_framesperdesc); 36657dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (0 >= peasycap->audio_isoc_framesperdesc) { 36667dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: bad audio_isoc_framesperdesc\n"); 36677dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOENT; 36687dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3669702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 36707dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_buffer_size = 36717dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_maxframesize * 36727dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_framesperdesc; 36737dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "%i=audio_isoc_buffer_size\n", 36747dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_buffer_size); 36757dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (AUDIO_ISOC_BUFFER_SIZE < peasycap->audio_isoc_buffer_size) { 36767dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: audio_isoc_buffer_size bigger " 36777dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "than %li=AUDIO_ISOC_BUFFER_SIZE\n", 36787dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler AUDIO_ISOC_BUFFER_SIZE); 36797dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 36807dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 36817dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->audio_interface) { 36827dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: audio_interface is unset\n"); 36837dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 36847dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 36857dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->audio_altsetting_on) { 36867dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: audio_altsetting_on is unset\n"); 36877dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 36887dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 36897dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->audio_altsetting_off) { 36907dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: audio_interface_off is unset\n"); 36917dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 36927dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 36937dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->audio_endpointnumber) { 36947dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: audio_endpointnumber is unset\n"); 36957dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 36967dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 36977dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->audio_isoc_maxframesize) { 36987dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: audio_isoc_maxframesize is unset\n"); 36997dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 37007dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 37017dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (-1 == peasycap->audio_isoc_buffer_size) { 37027dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("MISTAKE: audio_isoc_buffer_size is unset\n"); 37037dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -EFAULT; 37047dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 37052bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa 37062bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa /* 37072bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa * Allocate memory for audio buffers. 37082bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa * Lists must be initialized first. 37092bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa */ 37107dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler INIT_LIST_HEAD(&(peasycap->urb_audio_head)); 37117dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->purb_audio_head = &(peasycap->urb_audio_head); 3712702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 37137dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "allocating %i isoc audio buffers of size %i\n", 3714a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler AUDIO_ISOC_BUFFER_MANY, 3715a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->audio_isoc_buffer_size); 37167dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, ".... each occupying contiguous memory pages\n"); 3717702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 37187dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { 3719a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler pbuf = (void *)__get_free_pages(GFP_KERNEL, 3720a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler AUDIO_ISOC_ORDER); 37216888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pbuf) { 37227dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: Could not allocate isoc audio buffer " 37237dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "%i\n", k); 37247dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOMEM; 3725101dca425da49edb3093000d72490216fa322911Tomas Winkler } 3726101dca425da49edb3093000d72490216fa322911Tomas Winkler peasycap->allocation_audio_page += 3727a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler BIT(AUDIO_ISOC_ORDER); 3728702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 37297dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_buffer[k].pgo = pbuf; 37307dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_buffer[k].pto = pbuf + 37317dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_buffer_size; 37327dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_buffer[k].kount = k; 37337dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 37347dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "allocation of isoc audio buffers done.\n"); 37352bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa 37362bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa /* Allocate and initialize urbs */ 37377dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY); 37387dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "using %i=peasycap->audio_isoc_framesperdesc\n", 3739a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->audio_isoc_framesperdesc); 37407dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "using %i=peasycap->audio_isoc_maxframesize\n", 3741a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->audio_isoc_maxframesize); 37427dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "using %i=peasycap->audio_isoc_buffer_size\n", 3743a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->audio_isoc_buffer_size); 37447dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler 37457dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { 37467dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb = usb_alloc_urb(peasycap->audio_isoc_framesperdesc, 3747a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler GFP_KERNEL); 37486888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!purb) { 37497dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: usb_alloc_urb returned NULL for buffer " 37507dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "%i\n", k); 37517dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOMEM; 3752e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler } 3753e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler peasycap->allocation_audio_urb += 1 ; 37547dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL); 37556888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pdata_urb) { 37569fa728ea35501fb5cd56880839ad867265c61822Jesper Juhl usb_free_urb(purb); 37577dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAM("ERROR: Could not allocate struct data_urb.\n"); 37587dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENOMEM; 3759e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler } 3760e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler peasycap->allocation_audio_struct += 3761e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler sizeof(struct data_urb); 3762702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 37637dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pdata_urb->purb = purb; 37647dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pdata_urb->isbuf = k; 37657dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pdata_urb->length = 0; 37667dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler list_add_tail(&(pdata_urb->list_head), 37677dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->purb_audio_head); 37682bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa 37697dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (!k) { 37707dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "initializing audio urbs thus:\n"); 37717dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->interval = 1;\n"); 37727dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->dev = peasycap->pusb_device;\n"); 37737dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->pipe = usb_rcvisocpipe(peasycap->" 37747dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "pusb_device,%i);\n", 37757dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_endpointnumber); 37767dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n"); 37777dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->transfer_buffer = " 37787dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler "peasycap->audio_isoc_buffer[.].pgo;\n"); 37797dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->transfer_buffer_length = %i;\n", 3780a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->audio_isoc_buffer_size); 37817dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->complete = easycap_alsa_complete;\n"); 37827dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->context = peasycap;\n"); 37837dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->start_frame = 0;\n"); 37847dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->number_of_packets = %i;\n", 37857dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_framesperdesc); 37867dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " for (j = 0; j < %i; j++)\n", 37877dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_framesperdesc); 37887dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " {\n"); 37897dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n", 3790a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->audio_isoc_maxframesize); 37917dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " purb->iso_frame_desc[j].length = %i;\n", 3792a90f36206f0af9d6e2378a5f9c02dea081a04ae5Tomas Winkler peasycap->audio_isoc_maxframesize); 37937dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, " }\n"); 3794dfcce7bf0913cc81d57a41d8da3175b201ec1664Tomas Winkler } 3795702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 37967dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->interval = 1; 37977dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->dev = peasycap->pusb_device; 37987dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->pipe = usb_rcvisocpipe(peasycap->pusb_device, 37997dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_endpointnumber); 38007dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->transfer_flags = URB_ISO_ASAP; 38017dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->transfer_buffer = peasycap->audio_isoc_buffer[k].pgo; 38027dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->transfer_buffer_length = 38037dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_buffer_size; 38047dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->complete = easycap_alsa_complete; 38057dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->context = peasycap; 38067dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->start_frame = 0; 38077dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->number_of_packets = peasycap->audio_isoc_framesperdesc; 38087dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler for (j = 0; j < peasycap->audio_isoc_framesperdesc; j++) { 38097dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->iso_frame_desc[j].offset = j * 38107dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_maxframesize; 38117dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler purb->iso_frame_desc[j].length = 38127dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_isoc_maxframesize; 38137dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3814702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas } 38157dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "allocation of %i struct urb done.\n", k); 38162bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa 38172bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa /* Save pointer peasycap in this interface */ 381811ff12feb40dc663cad0f2da86729f1af9d1356eTomas Winkler usb_set_intfdata(intf, peasycap); 38192bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa 38202bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa /* The audio device can now be registered */ 38217dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOM(4, "initializing ALSA card\n"); 3822a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas 38237dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler rc = easycap_alsa_probe(peasycap); 38247dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (rc) { 3825c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler err("easycap_alsa_probe() rc = %i\n", rc); 38267dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return -ENODEV; 38277dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3828a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas 3829a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas 3830ad30d7af14c778a63304e42acdcedc365b26e8d8Tomas Winkler JOM(8, "kref_get() with %i=kref.refcount.counter\n", 3831ad30d7af14c778a63304e42acdcedc365b26e8d8Tomas Winkler peasycap->kref.refcount.counter); 3832ad30d7af14c778a63304e42acdcedc365b26e8d8Tomas Winkler kref_get(&peasycap->kref); 3833ad30d7af14c778a63304e42acdcedc365b26e8d8Tomas Winkler peasycap->registered_audio++; 38347dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler break; 3835dfcce7bf0913cc81d57a41d8da3175b201ec1664Tomas Winkler } 38362bc1e212b3f1f783cae9adc5d16aa1a899dc2f82Ezequiel GarcÃa /* Interfaces other than 0,1,2 are unexpected */ 3837dfcce7bf0913cc81d57a41d8da3175b201ec1664Tomas Winkler default: 3838dfcce7bf0913cc81d57a41d8da3175b201ec1664Tomas Winkler JOM(4, "ERROR: unexpected interface %i\n", bInterfaceNumber); 3839dfcce7bf0913cc81d57a41d8da3175b201ec1664Tomas Winkler return -EINVAL; 38407dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3841e03da5e2b77dee7d0535c036a09e9f613dce7c48Tomas Winkler SAM("ends successfully for interface %i\n", bInterfaceNumber); 38427dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return 0; 3843702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 3844702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 3845702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 3846702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 3847ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * WHEN THIS FUNCTION IS CALLED THE EasyCAP HAS ALREADY BEEN PHYSICALLY 3848ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * UNPLUGGED. HENCE peasycap->pusb_device IS NO LONGER VALID. 3849a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas * 385073019286cddc8bba1773944a7b6b603137fd66ffTomas Winkler * THIS FUNCTION AFFECTS ALSA. BEWARE. 3851702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 3852702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 3853d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic void easycap_usb_disconnect(struct usb_interface *pusb_interface) 3854702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 38557dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler struct usb_host_interface *pusb_host_interface; 38567dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler struct usb_interface_descriptor *pusb_interface_descriptor; 38577dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler struct easycap *peasycap; 38588b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler int minor, kd; 38598b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler u8 bInterfaceNumber; 3860702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 38617dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOT(4, "\n"); 3862702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 38637dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pusb_host_interface = pusb_interface->cur_altsetting; 38646888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pusb_host_interface) { 38657dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOT(4, "ERROR: pusb_host_interface is NULL\n"); 38667dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return; 38677dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 38687dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler pusb_interface_descriptor = &(pusb_host_interface->desc); 38696888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!pusb_interface_descriptor) { 38707dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOT(4, "ERROR: pusb_interface_descriptor is NULL\n"); 38717dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return; 38727dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 38737dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler bInterfaceNumber = pusb_interface_descriptor->bInterfaceNumber; 38747dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler minor = pusb_interface->minor; 38757dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler JOT(4, "intf[%i]: minor=%i\n", bInterfaceNumber, minor); 3876702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 38777dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler if (1 == bInterfaceNumber) 38787dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return; 3879e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas 38807dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap = usb_get_intfdata(pusb_interface); 38816888393c43c95a40d551989e89cbf572423619e6Tomas Winkler if (!peasycap) { 38827dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler SAY("ERROR: peasycap is NULL\n"); 38837dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler return; 38847dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler } 3885e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas/*---------------------------------------------------------------------------*/ 3886268dfede46e24eef55a2ef7a10a462617936771eMike Thomas/* 3887e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas * IF THE WAIT QUEUES ARE NOT CLEARED A DEADLOCK IS POSSIBLE. BEWARE. 3888e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas*/ 3889e68703cfe8dd2f5605c53b46fae6c9c027e7ef50Mike Thomas/*---------------------------------------------------------------------------*/ 38907dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->video_eof = 1; 38917dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler peasycap->audio_eof = 1; 38927dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler wake_up_interruptible(&(peasycap->wq_video)); 38937dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler wake_up_interruptible(&(peasycap->wq_audio)); 38948b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler 38957dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler switch (bInterfaceNumber) { 38968b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler case 0: 38978b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler easycap_video_kill_urbs(peasycap); 38987dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler break; 38998b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler case 2: 39008b1fad2f046fb825046fee3a41885a70123de988Tomas Winkler easycap_audio_kill_urbs(peasycap); 39017dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler break; 39027dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler default: 39037dcef374d17fd20ecd96b1aeccafe8a4a8c15740Tomas Winkler break; 3904c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 3905702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*--------------------------------------------------------------------------*/ 3906702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 3907702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * DEREGISTER 3908ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * 3909ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * THIS PROCEDURE WILL BLOCK UNTIL easycap_poll(), VIDEO IOCTL AND AUDIO 3910ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * IOCTL ARE ALL UNLOCKED. IF THIS IS NOT DONE AN Oops CAN OCCUR WHEN 3911ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas * AN EasyCAP IS UNPLUGGED WHILE THE URBS ARE RUNNING. BEWARE. 3912702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 3913702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*--------------------------------------------------------------------------*/ 391496bec7dd72511e3c16588d9af52da2cc937f7ea1Tomas Winkler kd = easycap_isdongle(peasycap); 3915c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler switch (bInterfaceNumber) { 3916c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 0: { 3917c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 <= kd && DONGLE_MANY > kd) { 3918c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler wake_up_interruptible(&peasycap->wq_video); 3919c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "about to lock dongle[%i].mutex_video\n", kd); 3920c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (mutex_lock_interruptible(&easycapdc60_dongle[kd]. 3921ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas mutex_video)) { 3922c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: " 3923c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "cannot lock dongle[%i].mutex_video\n", kd); 3924c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 3925c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 3926c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "locked dongle[%i].mutex_video\n", kd); 3927c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 3928c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd); 3929ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas } 3930ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas/*---------------------------------------------------------------------------*/ 3931c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!peasycap->v4l2_device.name[0]) { 3932c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: peasycap->v4l2_device.name is empty\n"); 3933c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 <= kd && DONGLE_MANY > kd) 3934c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mutex_unlock(&easycapdc60_dongle[kd].mutex_video); 3935c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 3936c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 3937c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v4l2_device_disconnect(&peasycap->v4l2_device); 3938c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "v4l2_device_disconnect() OK\n"); 3939c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler v4l2_device_unregister(&peasycap->v4l2_device); 3940c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "v4l2_device_unregister() OK\n"); 3941c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler 3942c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler video_unregister_device(&peasycap->video_device); 3943c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "intf[%i]: video_unregister_device() minor=%i\n", 3944c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bInterfaceNumber, minor); 3945c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->registered_video--; 3946268dfede46e24eef55a2ef7a10a462617936771eMike Thomas/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ 3947268dfede46e24eef55a2ef7a10a462617936771eMike Thomas 3948c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 <= kd && DONGLE_MANY > kd) { 3949c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mutex_unlock(&easycapdc60_dongle[kd].mutex_video); 3950c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "unlocked dongle[%i].mutex_video\n", kd); 3951c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 3952c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 3953ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas } 3954c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler case 2: { 3955c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 <= kd && DONGLE_MANY > kd) { 3956c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler wake_up_interruptible(&peasycap->wq_audio); 3957c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "about to lock dongle[%i].mutex_audio\n", kd); 3958c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (mutex_lock_interruptible(&easycapdc60_dongle[kd]. 3959ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas mutex_audio)) { 3960c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: " 3961c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "cannot lock dongle[%i].mutex_audio\n", kd); 3962c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 3963c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 3964c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "locked dongle[%i].mutex_audio\n", kd); 3965c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else 3966c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd); 3967c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 != snd_card_free(peasycap->psnd_card)) { 3968c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: snd_card_free() failed\n"); 3969c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } else { 3970c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler peasycap->psnd_card = NULL; 3971c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler (peasycap->registered_audio)--; 3972c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 3973c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 <= kd && DONGLE_MANY > kd) { 3974c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mutex_unlock(&easycapdc60_dongle[kd].mutex_audio); 3975c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "unlocked dongle[%i].mutex_audio\n", kd); 3976c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 3977c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 3978c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 3979c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler default: 3980c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler break; 3981ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas } 3982702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 3983702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 3984702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas * CALL easycap_delete() IF NO REMAINING REFERENCES TO peasycap 3985a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas * (ALSO WHEN ALSA HAS BEEN IN USE) 3986702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 3987702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 3988c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (!peasycap->kref.refcount.counter) { 3989c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ERROR: peasycap->kref.refcount.counter is zero " 3990c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler "so cannot call kref_put()\n"); 3991ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas SAM("ending unsuccessfully: may cause memory leak\n"); 3992ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas return; 3993ae59dad4fef271222d65ac6afe2889eb12ea6ca9Mike Thomas } 3994c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 <= kd && DONGLE_MANY > kd) { 3995c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "about to lock dongle[%i].mutex_video\n", kd); 3996c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_video)) { 3997c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: cannot lock dongle[%i].mutex_video\n", kd); 3998c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ending unsuccessfully: may cause memory leak\n"); 3999c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 4000c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 4001c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "locked dongle[%i].mutex_video\n", kd); 4002c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "about to lock dongle[%i].mutex_audio\n", kd); 4003c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (mutex_lock_interruptible(&easycapdc60_dongle[kd].mutex_audio)) { 4004c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAY("ERROR: cannot lock dongle[%i].mutex_audio\n", kd); 4005c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mutex_unlock(&(easycapdc60_dongle[kd].mutex_video)); 4006c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "unlocked dongle[%i].mutex_video\n", kd); 4007c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler SAM("ending unsuccessfully: may cause memory leak\n"); 4008c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 4009c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 4010c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "locked dongle[%i].mutex_audio\n", kd); 4011c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 4012c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "intf[%i]: %i=peasycap->kref.refcount.counter\n", 4013c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler bInterfaceNumber, (int)peasycap->kref.refcount.counter); 4014c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler kref_put(&peasycap->kref, easycap_delete); 4015c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOT(4, "intf[%i]: kref_put() done.\n", bInterfaceNumber); 4016c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler if (0 <= kd && DONGLE_MANY > kd) { 4017c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mutex_unlock(&(easycapdc60_dongle[kd].mutex_audio)); 4018c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOT(4, "unlocked dongle[%i].mutex_audio\n", kd); 4019c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler mutex_unlock(&easycapdc60_dongle[kd].mutex_video); 4020c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOT(4, "unlocked dongle[%i].mutex_video\n", kd); 4021c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler } 4022702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 4023c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler JOM(4, "ends\n"); 4024c750665850dfed34d3ff0f73ddf367cc7b729b77Tomas Winkler return; 4025702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 4026702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 4027a9855917290fc40dbfd67d3ee06c190667d6c5b5Mike Thomas 4028702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 4029702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/* 4030d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler * PARAMETERS APPLICABLE TO ENTIRE DRIVER, I.E. BOTH VIDEO AND AUDIO 4031702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas */ 4032702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*---------------------------------------------------------------------------*/ 4033d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic struct usb_device_id easycap_usb_device_id_table[] = { 4034d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler {USB_DEVICE(USB_EASYCAP_VENDOR_ID, USB_EASYCAP_PRODUCT_ID)}, 4035d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler { } 4036d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler}; 4037d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler 4038d090bf57492bde9cb6281246c92963476c40b512Tomas WinklerMODULE_DEVICE_TABLE(usb, easycap_usb_device_id_table); 40394329f3c6a5fb4ed2332c7552894e7e4b8efef194Tomas Winklerstatic struct usb_driver easycap_usb_driver = { 4040d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .name = "easycap", 4041d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .id_table = easycap_usb_device_id_table, 4042d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .probe = easycap_usb_probe, 4043d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler .disconnect = easycap_usb_disconnect, 4044d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler}; 4045702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 4046d090bf57492bde9cb6281246c92963476c40b512Tomas Winklerstatic int __init easycap_module_init(void) 4047d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler{ 4048d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler int k, rc; 4049d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler 4050aff512c8a4582c7f74af57bb09a9979edf92b6d8Tomas Winkler printk(KERN_INFO "Easycap version: "EASYCAP_DRIVER_VERSION "\n"); 4051aff512c8a4582c7f74af57bb09a9979edf92b6d8Tomas Winkler 4052d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler JOT(4, "begins. %i=debug %i=bars %i=gain\n", 4053d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler easycap_debug, easycap_bars, easycap_gain); 4054d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler 4055d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler mutex_init(&mutex_dongle); 4056d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler for (k = 0; k < DONGLE_MANY; k++) { 40573c1fb66ede917d54079a959a95f79777e95920bdTomas Winkler easycapdc60_dongle[k].peasycap = NULL; 4058d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler mutex_init(&easycapdc60_dongle[k].mutex_video); 4059d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler mutex_init(&easycapdc60_dongle[k].mutex_audio); 4060d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler } 4061d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler rc = usb_register(&easycap_usb_driver); 40626911e7e4a6bed8ac7989137387f6a33ef65c2b56Tomas Winkler if (rc) 4063aff512c8a4582c7f74af57bb09a9979edf92b6d8Tomas Winkler printk(KERN_ERR "Easycap: usb_register failed rc=%d\n", rc); 4064d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler 4065d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler return rc; 4066702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 4067702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 4068dbf4805ee6a850e941110b0df1e96049287ecf75Tomas Winklerstatic void __exit easycap_module_exit(void) 4069702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas{ 4070d090bf57492bde9cb6281246c92963476c40b512Tomas Winkler usb_deregister(&easycap_usb_driver); 4071702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas} 4072702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 4073702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 4074702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomasmodule_init(easycap_module_init); 4075702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomasmodule_exit(easycap_module_exit); 4076702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas 4077702422bd2d3f44e454a97ca7054edde84cc18126R.M. Thomas/*****************************************************************************/ 4078