cregit-Linux how code gets into the kernel

Release 4.7 drivers/media/pci/bt8xx/bttv-driver.c

/*

    bttv - Bt848 frame grabber driver

    Copyright (C) 1996,97,98 Ralph  Metzler <rjkm@thp.uni-koeln.de>
                           & Marcus Metzler <mocm@thp.uni-koeln.de>
    (c) 1999-2002 Gerd Knorr <kraxel@bytesex.org>

    some v4l2 code lines are taken from Justin's bttv2 driver which is
    (c) 2000 Justin Schoeman <justin@suntiger.ee.up.ac.za>

    V4L1 removal from:
    (c) 2005-2006 Nickolay V. Shmyrev <nshmyrev@yandex.ru>

    Fixes to be fully V4L2 compliant by
    (c) 2006 Mauro Carvalho Chehab <mchehab@infradead.org>

    Cropping and overscan support
    Copyright (C) 2005, 2006 Michael H. Schimek <mschimek@gmx.at>
    Sponsored by OPQ Systems AB

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/


#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/init.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/kdev_t.h>
#include "bttvp.h"
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-event.h>
#include <media/i2c/tvaudio.h>
#include <media/drv-intf/msp3400.h>

#include <linux/dma-mapping.h>

#include <asm/io.h>
#include <asm/byteorder.h>

#include <media/i2c/saa6588.h>


#define BTTV_VERSION "0.9.19"


unsigned int bttv_num;			
/* number of Bt848s in use */

struct bttv *bttvs[BTTV_MAX];


unsigned int bttv_debug;

unsigned int bttv_verbose = 1;

unsigned int bttv_gpio;

/* config variables */
#ifdef __BIG_ENDIAN

static unsigned int bigendian=1;
#else

static unsigned int bigendian;
#endif

static unsigned int radio[BTTV_MAX];

static unsigned int irq_debug;

static unsigned int gbuffers = 8;

static unsigned int gbufsize = 0x208000;

static unsigned int reset_crop = 1;


static int video_nr[BTTV_MAX] = { [0 ... (BTTV_MAX-1)] = -1 };

static int radio_nr[BTTV_MAX] = { [0 ... (BTTV_MAX-1)] = -1 };

static int vbi_nr[BTTV_MAX] = { [0 ... (BTTV_MAX-1)] = -1 };

static int debug_latency;

static int disable_ir;


static unsigned int fdsr;

/* options */

static unsigned int combfilter;

static unsigned int lumafilter;

static unsigned int automute    = 1;

static unsigned int chroma_agc;

static unsigned int agc_crush   = 1;

static unsigned int whitecrush_upper = 0xCF;

static unsigned int whitecrush_lower = 0x7F;

static unsigned int vcr_hack;

static unsigned int irq_iswitch;

static unsigned int uv_ratio    = 50;

static unsigned int full_luma_range;

static unsigned int coring;

/* API features (turn on/off stuff for testing) */

static unsigned int v4l2        = 1;

/* insmod args */
module_param(bttv_verbose,      int, 0644);
module_param(bttv_gpio,         int, 0644);
module_param(bttv_debug,        int, 0644);
module_param(irq_debug,         int, 0644);
module_param(debug_latency,     int, 0644);
module_param(disable_ir,        int, 0444);

module_param(fdsr,              int, 0444);
module_param(gbuffers,          int, 0444);
module_param(gbufsize,          int, 0444);
module_param(reset_crop,        int, 0444);

module_param(v4l2,              int, 0644);
module_param(bigendian,         int, 0644);
module_param(irq_iswitch,       int, 0644);
module_param(combfilter,        int, 0444);
module_param(lumafilter,        int, 0444);
module_param(automute,          int, 0444);
module_param(chroma_agc,        int, 0444);
module_param(agc_crush,         int, 0444);
module_param(whitecrush_upper,  int, 0444);
module_param(whitecrush_lower,  int, 0444);
module_param(vcr_hack,          int, 0444);
module_param(uv_ratio,          int, 0444);
module_param(full_luma_range,   int, 0444);
module_param(coring,            int, 0444);

module_param_array(radio,       int, NULL, 0444);
module_param_array(video_nr,    int, NULL, 0444);
module_param_array(radio_nr,    int, NULL, 0444);
module_param_array(vbi_nr,      int, NULL, 0444);

MODULE_PARM_DESC(radio, "The TV card supports radio, default is 0 (no)");
MODULE_PARM_DESC(bigendian, "byte order of the framebuffer, default is native endian");
MODULE_PARM_DESC(bttv_verbose, "verbose startup messages, default is 1 (yes)");
MODULE_PARM_DESC(bttv_gpio, "log gpio changes, default is 0 (no)");
MODULE_PARM_DESC(bttv_debug, "debug messages, default is 0 (no)");
MODULE_PARM_DESC(irq_debug, "irq handler debug messages, default is 0 (no)");
MODULE_PARM_DESC(disable_ir, "disable infrared remote support");
MODULE_PARM_DESC(gbuffers, "number of capture buffers. range 2-32, default 8");
MODULE_PARM_DESC(gbufsize, "size of the capture buffers, default is 0x208000");
MODULE_PARM_DESC(reset_crop, "reset cropping parameters at open(), default "
		 "is 1 (yes) for compatibility with older applications");
MODULE_PARM_DESC(automute, "mute audio on bad/missing video signal, default is 1 (yes)");
MODULE_PARM_DESC(chroma_agc, "enables the AGC of chroma signal, default is 0 (no)");
MODULE_PARM_DESC(agc_crush, "enables the luminance AGC crush, default is 1 (yes)");
MODULE_PARM_DESC(whitecrush_upper, "sets the white crush upper value, default is 207");
MODULE_PARM_DESC(whitecrush_lower, "sets the white crush lower value, default is 127");
MODULE_PARM_DESC(vcr_hack, "enables the VCR hack (improves synch on poor VCR tapes), default is 0 (no)");
MODULE_PARM_DESC(irq_iswitch, "switch inputs in irq handler");
MODULE_PARM_DESC(uv_ratio, "ratio between u and v gains, default is 50");
MODULE_PARM_DESC(full_luma_range, "use the full luma range, default is 0 (no)");
MODULE_PARM_DESC(coring, "set the luma coring level, default is 0 (no)");
MODULE_PARM_DESC(video_nr, "video device numbers");
MODULE_PARM_DESC(vbi_nr, "vbi device numbers");
MODULE_PARM_DESC(radio_nr, "radio device numbers");

MODULE_DESCRIPTION("bttv - v4l/v4l2 driver module for bt848/878 based cards");
MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr");
MODULE_LICENSE("GPL");

MODULE_VERSION(BTTV_VERSION);


#define V4L2_CID_PRIVATE_COMBFILTER		(V4L2_CID_USER_BTTV_BASE + 0)

#define V4L2_CID_PRIVATE_AUTOMUTE		(V4L2_CID_USER_BTTV_BASE + 1)

#define V4L2_CID_PRIVATE_LUMAFILTER		(V4L2_CID_USER_BTTV_BASE + 2)

#define V4L2_CID_PRIVATE_AGC_CRUSH		(V4L2_CID_USER_BTTV_BASE + 3)

#define V4L2_CID_PRIVATE_VCR_HACK		(V4L2_CID_USER_BTTV_BASE + 4)

#define V4L2_CID_PRIVATE_WHITECRUSH_LOWER	(V4L2_CID_USER_BTTV_BASE + 5)

#define V4L2_CID_PRIVATE_WHITECRUSH_UPPER	(V4L2_CID_USER_BTTV_BASE + 6)

#define V4L2_CID_PRIVATE_UV_RATIO		(V4L2_CID_USER_BTTV_BASE + 7)

#define V4L2_CID_PRIVATE_FULL_LUMA_RANGE	(V4L2_CID_USER_BTTV_BASE + 8)

#define V4L2_CID_PRIVATE_CORING			(V4L2_CID_USER_BTTV_BASE + 9)

/* ----------------------------------------------------------------------- */
/* sysfs                                                                   */


static ssize_t show_card(struct device *cd, struct device_attribute *attr, char *buf) { struct video_device *vfd = to_video_device(cd); struct bttv *btv = video_get_drvdata(vfd); return sprintf(buf, "%d\n", btv ? btv->c.type : UNSET); }

Contributors

PersonTokensPropCommitsCommitProp
gerd knorrgerd knorr4882.76%120.00%
kay sieverskay sievers610.34%120.00%
andrew mortonandrew morton23.45%120.00%
geliang tanggeliang tang11.72%120.00%
hans verkuilhans verkuil11.72%120.00%
Total58100.00%5100.00%

static DEVICE_ATTR(card, S_IRUGO, show_card, NULL); /* ----------------------------------------------------------------------- */ /* dvb auto-load setup */ #if defined(CONFIG_MODULES) && defined(MODULE)
static void request_module_async(struct work_struct *work) { request_module("dvb-bt8xx"); }

Contributors

PersonTokensPropCommitsCommitProp
jarod wilsonjarod wilson16100.00%1100.00%
Total16100.00%1100.00%


static void request_modules(struct bttv *dev) { INIT_WORK(&dev->request_module_wk, request_module_async); schedule_work(&dev->request_module_wk); }

Contributors

PersonTokensPropCommitsCommitProp
jarod wilsonjarod wilson29100.00%1100.00%
Total29100.00%1100.00%


static void flush_request_modules(struct bttv *dev) { flush_work(&dev->request_module_wk); }

Contributors

PersonTokensPropCommitsCommitProp
tejun heotejun heo19100.00%2100.00%
Total19100.00%2100.00%

#else #define request_modules(dev) #define flush_request_modules(dev) do {} while(0) #endif /* CONFIG_MODULES */ /* ----------------------------------------------------------------------- */ /* static data */ /* special timing tables from conexant... */ static u8 SRAM_Table[][60] = { /* PAL digital input over GPIO[7:0] */ { 45, // 45 bytes following 0x36,0x11,0x01,0x00,0x90,0x02,0x05,0x10,0x04,0x16, 0x12,0x05,0x11,0x00,0x04,0x12,0xC0,0x00,0x31,0x00, 0x06,0x51,0x08,0x03,0x89,0x08,0x07,0xC0,0x44,0x00, 0x81,0x01,0x01,0xA9,0x0D,0x02,0x02,0x50,0x03,0x37, 0x37,0x00,0xAF,0x21,0x00 }, /* NTSC digital input over GPIO[7:0] */ { 51, // 51 bytes following 0x0C,0xC0,0x00,0x00,0x90,0x02,0x03,0x10,0x03,0x06, 0x10,0x04,0x12,0x12,0x05,0x02,0x13,0x04,0x19,0x00, 0x04,0x39,0x00,0x06,0x59,0x08,0x03,0x83,0x08,0x07, 0x03,0x50,0x00,0xC0,0x40,0x00,0x86,0x01,0x01,0xA6, 0x0D,0x02,0x03,0x11,0x01,0x05,0x37,0x00,0xAC,0x21, 0x00, }, // TGB_NTSC392 // quartzsight // This table has been modified to be used for Fusion Rev D { 0x2A, // size of table = 42 0x06, 0x08, 0x04, 0x0a, 0xc0, 0x00, 0x18, 0x08, 0x03, 0x24, 0x08, 0x07, 0x02, 0x90, 0x02, 0x08, 0x10, 0x04, 0x0c, 0x10, 0x05, 0x2c, 0x11, 0x04, 0x55, 0x48, 0x00, 0x05, 0x50, 0x00, 0xbf, 0x0c, 0x02, 0x2f, 0x3d, 0x00, 0x2f, 0x3f, 0x00, 0xc3, 0x20, 0x00 } }; /* minhdelayx1 first video pixel we can capture on a line and hdelayx1 start of active video, both relative to rising edge of /HRESET pulse (0H) in 1 / fCLKx1. swidth width of active video and totalwidth total line width, both in 1 / fCLKx1. sqwidth total line width in square pixels. vdelay start of active video in 2 * field lines relative to trailing edge of /VRESET pulse (VDELAY register). sheight height of active video in 2 * field lines. extraheight Added to sheight for cropcap.bounds.height only videostart0 ITU-R frame line number of the line corresponding to vdelay in the first field. */ #define CROPCAP(minhdelayx1, hdelayx1, swidth, totalwidth, sqwidth, \ vdelay, sheight, extraheight, videostart0) \ .cropcap.bounds.left = minhdelayx1, \ /* * 2 because vertically we count field lines times two, */ \ /* e.g. 23 * 2 to 23 * 2 + 576 in PAL-BGHI defrect. */ \ .cropcap.bounds.top = (videostart0) * 2 - (vdelay) + MIN_VDELAY, \ /* 4 is a safety margin at the end of the line. */ \ .cropcap.bounds.width = (totalwidth) - (minhdelayx1) - 4, \ .cropcap.bounds.height = (sheight) + (extraheight) + (vdelay) - \ MIN_VDELAY, \ .cropcap.defrect.left = hdelayx1, \ .cropcap.defrect.top = (videostart0) * 2, \ .cropcap.defrect.width = swidth, \ .cropcap.defrect.height = sheight, \ .cropcap.pixelaspect.numerator = totalwidth, \ .cropcap.pixelaspect.denominator = sqwidth, const struct bttv_tvnorm bttv_tvnorms[] = { /* PAL-BDGHI */ /* max. active video is actually 922, but 924 is divisible by 4 and 3! */ /* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */ { .v4l2_id = V4L2_STD_PAL, .name = "PAL", .Fsc = 35468950, .swidth = 924, .sheight = 576, .totalwidth = 1135, .adelay = 0x7f, .bdelay = 0x72, .iform = (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1), .scaledtwidth = 1135, .hdelayx1 = 186, .hactivex1 = 924, .vdelay = 0x20, .vbipack = 255, /* min (2048 / 4, 0x1ff) & 0xff */ .sram = 0, /* ITU-R frame line number of the first VBI line we can capture, of the first and second field. The last line is determined by cropcap.bounds. */ .vbistart = { 7, 320 }, CROPCAP(/* minhdelayx1 */ 68, /* hdelayx1 */ 186, /* Should be (768 * 1135 + 944 / 2) / 944. cropcap.defrect is used for image width checks, so we keep the old value 924. */ /* swidth */ 924, /* totalwidth */ 1135, /* sqwidth */ 944, /* vdelay */ 0x20, /* sheight */ 576, /* bt878 (and bt848?) can capture another line below active video. */ /* extraheight */ 2, /* videostart0 */ 23) },{ .v4l2_id = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR, .name = "NTSC", .Fsc = 28636363, .swidth = 768, .sheight = 480, .totalwidth = 910, .adelay = 0x68, .bdelay = 0x5d, .iform = (BT848_IFORM_NTSC|BT848_IFORM_XT0), .scaledtwidth = 910, .hdelayx1 = 128, .hactivex1 = 910, .vdelay = 0x1a, .vbipack = 144, /* min (1600 / 4, 0x1ff) & 0xff */ .sram = 1, .vbistart = { 10, 273 }, CROPCAP(/* minhdelayx1 */ 68, /* hdelayx1 */ 128, /* Should be (640 * 910 + 780 / 2) / 780? */ /* swidth */ 768, /* totalwidth */ 910, /* sqwidth */ 780, /* vdelay */ 0x1a, /* sheight */ 480, /* extraheight */ 0, /* videostart0 */ 23) },{ .v4l2_id = V4L2_STD_SECAM, .name = "SECAM", .Fsc = 35468950, .swidth = 924, .sheight = 576, .totalwidth = 1135, .adelay = 0x7f, .bdelay = 0xb0, .iform = (BT848_IFORM_SECAM|BT848_IFORM_XT1), .scaledtwidth = 1135, .hdelayx1 = 186, .hactivex1 = 922, .vdelay = 0x20, .vbipack = 255, .sram = 0, /* like PAL, correct? */ .vbistart = { 7, 320 }, CROPCAP(/* minhdelayx1 */ 68, /* hdelayx1 */ 186, /* swidth */ 924, /* totalwidth */ 1135, /* sqwidth */ 944, /* vdelay */ 0x20, /* sheight */ 576, /* extraheight */ 0, /* videostart0 */ 23) },{ .v4l2_id = V4L2_STD_PAL_Nc, .name = "PAL-Nc", .Fsc = 28636363, .swidth = 640, .sheight = 576, .totalwidth = 910, .adelay = 0x68, .bdelay = 0x5d, .iform = (BT848_IFORM_PAL_NC|BT848_IFORM_XT0), .scaledtwidth = 780, .hdelayx1 = 130, .hactivex1 = 734, .vdelay = 0x1a, .vbipack = 144, .sram = -1, .vbistart = { 7, 320 }, CROPCAP(/* minhdelayx1 */ 68, /* hdelayx1 */ 130, /* swidth */ (640 * 910 + 780 / 2) / 780, /* totalwidth */ 910, /* sqwidth */ 780, /* vdelay */ 0x1a, /* sheight */ 576, /* extraheight */ 0, /* videostart0 */ 23) },{ .v4l2_id = V4L2_STD_PAL_M, .name = "PAL-M", .Fsc = 28636363, .swidth = 640, .sheight = 480, .totalwidth = 910, .adelay = 0x68, .bdelay = 0x5d, .iform = (BT848_IFORM_PAL_M|BT848_IFORM_XT0), .scaledtwidth = 780, .hdelayx1 = 135, .hactivex1 = 754, .vdelay = 0x1a, .vbipack = 144, .sram = -1, .vbistart = { 10, 273 }, CROPCAP(/* minhdelayx1 */ 68, /* hdelayx1 */ 135, /* swidth */ (640 * 910 + 780 / 2) / 780, /* totalwidth */ 910, /* sqwidth */ 780, /* vdelay */ 0x1a, /* sheight */ 480, /* extraheight */ 0, /* videostart0 */ 23) },{ .v4l2_id = V4L2_STD_PAL_N, .name = "PAL-N", .Fsc = 35468950, .swidth = 768, .sheight = 576, .totalwidth = 1135, .adelay = 0x7f, .bdelay = 0x72, .iform = (BT848_IFORM_PAL_N|BT848_IFORM_XT1), .scaledtwidth = 944, .hdelayx1 = 186, .hactivex1 = 922, .vdelay = 0x20, .vbipack = 144, .sram = -1, .vbistart = { 7, 320 }, CROPCAP(/* minhdelayx1 */ 68, /* hdelayx1 */ 186, /* swidth */ (768 * 1135 + 944 / 2) / 944, /* totalwidth */ 1135, /* sqwidth */ 944, /* vdelay */ 0x20, /* sheight */ 576, /* extraheight */ 0, /* videostart0 */ 23) },{ .v4l2_id = V4L2_STD_NTSC_M_JP, .name = "NTSC-JP", .Fsc = 28636363, .swidth = 640, .sheight = 480, .totalwidth = 910, .adelay = 0x68, .bdelay = 0x5d, .iform = (BT848_IFORM_NTSC_J|BT848_IFORM_XT0), .scaledtwidth = 780, .hdelayx1 = 135, .hactivex1 = 754, .vdelay = 0x16, .vbipack = 144, .sram = -1, .vbistart = { 10, 273 }, CROPCAP(/* minhdelayx1 */ 68, /* hdelayx1 */ 135, /* swidth */ (640 * 910 + 780 / 2) / 780, /* totalwidth */ 910, /* sqwidth */ 780, /* vdelay */ 0x16, /* sheight */ 480, /* extraheight */ 0, /* videostart0 */ 23) },{ /* that one hopefully works with the strange timing * which video recorders produce when playing a NTSC * tape on a PAL TV ... */ .v4l2_id = V4L2_STD_PAL_60, .name = "PAL-60", .Fsc = 35468950, .swidth = 924, .sheight = 480, .totalwidth = 1135, .adelay = 0x7f, .bdelay = 0x72, .iform = (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1), .scaledtwidth = 1135, .hdelayx1 = 186, .hactivex1 = 924, .vdelay = 0x1a, .vbipack = 255, .vtotal = 524, .sram = -1, .vbistart = { 10, 273 }, CROPCAP(/* minhdelayx1 */ 68, /* hdelayx1 */ 186, /* swidth */ 924, /* totalwidth */ 1135, /* sqwidth */ 944, /* vdelay */ 0x1a, /* sheight */ 480, /* extraheight */ 0, /* videostart0 */ 23) } }; static const unsigned int BTTV_TVNORMS = ARRAY_SIZE(bttv_tvnorms); /* ----------------------------------------------------------------------- */ /* bttv format list packed pixel formats must come first */ static const struct bttv_format formats[] = { { .name = "8 bpp, gray", .fourcc = V4L2_PIX_FMT_GREY, .btformat = BT848_COLOR_FMT_Y8, .depth = 8, .flags = FORMAT_FLAGS_PACKED, },{ .name = "8 bpp, dithered color", .fourcc = V4L2_PIX_FMT_HI240, .btformat = BT848_COLOR_FMT_RGB8, .depth = 8, .flags = FORMAT_FLAGS_PACKED | FORMAT_FLAGS_DITHER, },{ .name = "15 bpp RGB, le", .fourcc = V4L2_PIX_FMT_RGB555, .btformat = BT848_COLOR_FMT_RGB15, .depth = 16, .flags = FORMAT_FLAGS_PACKED, },{ .name = "15 bpp RGB, be", .fourcc = V4L2_PIX_FMT_RGB555X, .btformat = BT848_COLOR_FMT_RGB15, .btswap = 0x03, /* byteswap */ .depth = 16, .flags = FORMAT_FLAGS_PACKED, },{ .name = "16 bpp RGB, le", .fourcc = V4L2_PIX_FMT_RGB565, .btformat = BT848_COLOR_FMT_RGB16, .depth = 16, .flags = FORMAT_FLAGS_PACKED, },{ .name = "16 bpp RGB, be", .fourcc = V4L2_PIX_FMT_RGB565X, .btformat = BT848_COLOR_FMT_RGB16, .btswap = 0x03, /* byteswap */ .depth = 16, .flags = FORMAT_FLAGS_PACKED, },{ .name = "24 bpp RGB, le", .fourcc = V4L2_PIX_FMT_BGR24, .btformat = BT848_COLOR_FMT_RGB24, .depth = 24, .flags = FORMAT_FLAGS_PACKED, },{ .name = "32 bpp RGB, le", .fourcc = V4L2_PIX_FMT_BGR32, .btformat = BT848_COLOR_FMT_RGB32, .depth = 32, .flags = FORMAT_FLAGS_PACKED, },{ .name = "32 bpp RGB, be", .fourcc = V4L2_PIX_FMT_RGB32, .btformat = BT848_COLOR_FMT_RGB32, .btswap = 0x0f, /* byte+word swap */ .depth = 32, .flags = FORMAT_FLAGS_PACKED, },{ .name = "4:2:2, packed, YUYV", .fourcc = V4L2_PIX_FMT_YUYV, .btformat = BT848_COLOR_FMT_YUY2, .depth = 16, .flags = FORMAT_FLAGS_PACKED, },{ .name = "4:2:2, packed, UYVY", .fourcc = V4L2_PIX_FMT_UYVY, .btformat = BT848_COLOR_FMT_YUY2, .btswap = 0x03, /* byteswap */ .depth = 16, .flags = FORMAT_FLAGS_PACKED, },{ .name = "4:2:2, planar, Y-Cb-Cr", .fourcc = V4L2_PIX_FMT_YUV422P, .btformat = BT848_COLOR_FMT_YCrCb422, .depth = 16, .flags = FORMAT_FLAGS_PLANAR, .hshift = 1, .vshift = 0, },{ .name = "4:2:0, planar, Y-Cb-Cr", .fourcc = V4L2_PIX_FMT_YUV420, .btformat = BT848_COLOR_FMT_YCrCb422, .depth = 12, .flags = FORMAT_FLAGS_PLANAR, .hshift = 1, .vshift = 1, },{ .name = "4:2:0, planar, Y-Cr-Cb", .fourcc = V4L2_PIX_FMT_YVU420, .btformat = BT848_COLOR_FMT_YCrCb422, .depth = 12, .flags = FORMAT_FLAGS_PLANAR | FORMAT_FLAGS_CrCb, .hshift = 1, .vshift = 1, },{ .name = "4:1:1, planar, Y-Cb-Cr", .fourcc = V4L2_PIX_FMT_YUV411P, .btformat = BT848_COLOR_FMT_YCrCb411, .depth = 12, .flags = FORMAT_FLAGS_PLANAR, .hshift = 2, .vshift = 0, },{ .name = "4:1:0, planar, Y-Cb-Cr", .fourcc = V4L2_PIX_FMT_YUV410, .btformat = BT848_COLOR_FMT_YCrCb411, .depth = 9, .flags = FORMAT_FLAGS_PLANAR, .hshift = 2, .vshift = 2, },{ .name = "4:1:0, planar, Y-Cr-Cb", .fourcc = V4L2_PIX_FMT_YVU410, .btformat = BT848_COLOR_FMT_YCrCb411, .depth = 9, .flags = FORMAT_FLAGS_PLANAR | FORMAT_FLAGS_CrCb, .hshift = 2, .vshift = 2, },{ .name = "raw scanlines", .fourcc = -1, .btformat = BT848_COLOR_FMT_RAW, .depth = 8, .flags = FORMAT_FLAGS_RAW, } }; static const unsigned int FORMATS = ARRAY_SIZE(formats); /* ----------------------------------------------------------------------- */ /* resource management */ /* RESOURCE_ allocated by freed by VIDEO_READ bttv_read 1) bttv_read 2) VIDEO_STREAM VIDIOC_STREAMON VIDIOC_STREAMOFF VIDIOC_QBUF 1) bttv_release VIDIOCMCAPTURE 1) OVERLAY VIDIOCCAPTURE on VIDIOCCAPTURE off VIDIOC_OVERLAY on VIDIOC_OVERLAY off 3) bttv_release VBI VIDIOC_STREAMON VIDIOC_STREAMOFF VIDIOC_QBUF 1) bttv_release bttv_read, bttv_poll 1) 4) 1) The resource must be allocated when we enter buffer prepare functions and remain allocated while buffers are in the DMA queue. 2) This is a single frame read. 3) VIDIOC_S_FBUF and VIDIOC_S_FMT (OVERLAY) still work when RESOURCE_OVERLAY is allocated. 4) This is a continuous read, implies VIDIOC_STREAMON. Note this driver permits video input and standard changes regardless if resources are allocated. */ #define VBI_RESOURCES (RESOURCE_VBI) #define VIDEO_RESOURCES (RESOURCE_VIDEO_READ | \ RESOURCE_VIDEO_STREAM | \ RESOURCE_OVERLAY)
static int check_alloc_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bit) { int xbits; /* mutual exclusive resources */ if (fh->resources & bit) /* have it already allocated */ return 1; xbits = bit; if (bit & (RESOURCE_VIDEO_READ | RESOURCE_VIDEO_STREAM)) xbits |= RESOURCE_VIDEO_READ | RESOURCE_VIDEO_STREAM; /* is it free? */ if (btv->resources & xbits) { /* no, someone else uses it */ goto fail; } if ((bit & VIDEO_RESOURCES) && 0 == (btv->resources & VIDEO_RESOURCES)) { /* Do crop - use current, don't - use default parameters. */ __s32 top = btv->crop[!!fh->do_crop].rect.top; if (btv->vbi_end > top) goto fail; /* We cannot capture the same line as video and VBI data. Claim scan lines crop[].rect.top to bottom. */ btv->crop_start = top; } else if (bit & VBI_RESOURCES) { __s32 end = fh->vbi_fmt.end; if (end > btv->crop_start) goto fail; /* Claim scan lines above fh->vbi_fmt.end. */ btv->vbi_end = end; } /* it's free, grab it */ fh->resources |= bit; btv->resources |= bit; return 1; fail: return 0; }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil17192.93%133.33%
gerd knorrgerd knorr84.35%133.33%
art haasart haas52.72%133.33%
Total184100.00%3100.00%


static int check_btres(struct bttv_fh *fh, int bit) { return (fh->resources & bit); }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil23100.00%1100.00%
Total23100.00%1100.00%


static int locked_btres(struct bttv *btv, int bit) { return (btv->resources & bit); }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil23100.00%1100.00%
Total23100.00%1100.00%

/* Call with btv->lock down. */
static void disclaim_vbi_lines(struct bttv *btv) { btv->vbi_end = 0; }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil1694.12%150.00%
art haasart haas15.88%150.00%
Total17100.00%2100.00%

/* Call with btv->lock down. */
static void disclaim_video_lines(struct bttv *btv) { const struct bttv_tvnorm *tvnorm; u8 crop; tvnorm = &bttv_tvnorms[btv->tvnorm]; btv->crop_start = tvnorm->cropcap.bounds.top + tvnorm->cropcap.bounds.height; /* VBI capturing ends at VDELAY, start of video capturing, no matter how many lines the VBI RISC program expects. When video capturing is off, it shall no longer "preempt" VBI capturing, so we set VDELAY to maximum. */ crop = btread(BT848_E_CROP) | 0xc0; btwrite(crop, BT848_E_CROP); btwrite(0xfe, BT848_E_VDELAY_LO); btwrite(crop, BT848_O_CROP); btwrite(0xfe, BT848_O_VDELAY_LO); }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil8192.05%150.00%
art haasart haas77.95%150.00%
Total88100.00%2100.00%


static void free_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bits) { if ((fh->resources & bits) != bits) { /* trying to free resources not allocated by us ... */ pr_err("BUG! (btres)\n"); } fh->resources &= ~bits; btv->resources &= ~bits; bits = btv->resources; if (0 == (bits & VIDEO_RESOURCES)) disclaim_video_lines(btv); if (0 == (bits & VBI_RESOURCES)) disclaim_vbi_lines(btv); }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil8696.63%133.33%
guilherme herrmann destefaniguilherme herrmann destefani22.25%133.33%
gerd knorrgerd knorr11.12%133.33%
Total89100.00%3100.00%

/* ----------------------------------------------------------------------- */ /* If Bt848a or Bt849, use PLL for PAL/SECAM and crystal for NTSC */ /* Frequency = (F_input / PLL_X) * PLL_I.PLL_F/PLL_C PLL_X = Reference pre-divider (0=1, 1=2) PLL_C = Post divider (0=6, 1=4) PLL_I = Integer input PLL_F = Fractional input F_input = 28.636363 MHz: PAL (CLKx2 = 35.46895 MHz): PLL_X = 1, PLL_I = 0x0E, PLL_F = 0xDCF9, PLL_C = 0 */
static void set_pll_freq(struct bttv *btv, unsigned int fin, unsigned int fout) { unsigned char fl, fh, fi; /* prevent overflows */ fin/=4; fout/=4; fout*=12; fi=fout/fin; fout=(fout%fin)*256; fh=fout/fin; fout=(fout%fin)*256; fl=fout/fin; btwrite(fl, BT848_PLL_F_LO); btwrite(fh, BT848_PLL_F_HI); btwrite(fi|BT848_PLL_X, BT848_PLL_XCI); }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil9493.07%125.00%
art haasart haas54.95%125.00%
guilherme herrmann destefaniguilherme herrmann destefani10.99%125.00%
gerd knorrgerd knorr10.99%125.00%
Total101100.00%4100.00%


static void set_pll(struct bttv *btv) { int i; if (!btv->pll.pll_crystal) return; if (btv->pll.pll_ofreq == btv->pll.pll_current) { dprintk("%d: PLL: no change required\n", btv->c.nr); return; } if (btv->pll.pll_ifreq == btv->pll.pll_ofreq) { /* no PLL needed */ if (btv->pll.pll_current == 0) return; if (bttv_verbose) pr_info("%d: PLL can sleep, using XTAL (%d)\n", btv->c.nr, btv->pll.pll_ifreq); btwrite(0x00,BT848_TGCTRL); btwrite(0x00,BT848_PLL_XCI); btv->pll.pll_current = 0; return; } if (bttv_verbose) pr_info("%d: Setting PLL: %d => %d (needs up to 100ms)\n", btv->c.nr, btv->pll.pll_ifreq, btv->pll.pll_ofreq); set_pll_freq(btv, btv->pll.pll_ifreq, btv->pll.pll_ofreq); for (i=0; i<10; i++) { /* Let other people run while the PLL stabilizes */ msleep(10); if (btread(BT848_DSTATUS) & BT848_DSTATUS_PLOCK) { btwrite(0,BT848_DSTATUS); } else { btwrite(0x08,BT848_TGCTRL); btv->pll.pll_current = btv->pll.pll_ofreq; if (bttv_verbose) pr_info("PLL set ok\n"); return; } } btv->pll.pll_current = -1; if (bttv_verbose) pr_info("Setting PLL failed\n"); return; }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil22888.37%133.33%
art haasart haas218.14%133.33%
gerd knorrgerd knorr93.49%133.33%
Total258100.00%3100.00%

/* used to switch between the bt848's analog/digital video capture modes */
static void bt848A_set_timing(struct bttv *btv) { int i, len; int table_idx = bttv_tvnorms[btv->tvnorm].sram; int fsc = bttv_tvnorms[btv->tvnorm].Fsc; if (btv->input == btv->dig) { dprintk("%d: load digital timing table (table_idx=%d)\n", btv->c.nr,table_idx); /* timing change...reset timing generator address */ btwrite(0x00, BT848_TGCTRL); btwrite(0x02, BT848_TGCTRL); btwrite(0x00, BT848_TGCTRL); len=SRAM_Table[table_idx][0]; for(i = 1; i <= len; i++) btwrite(SRAM_Table[table_idx][i],BT848_TGLB); btv->pll.pll_ofreq = 27000000; set_pll(btv); btwrite(0x11, BT848_TGCTRL); btwrite(0x41, BT848_DVSIF); } else { btv->pll.pll_ofreq = fsc; set_pll(btv); btwrite(0x0, BT848_DVSIF); } }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil16092.49%133.33%
art haasart haas95.20%133.33%
gerd knorrgerd knorr42.31%133.33%
Total173100.00%3100.00%

/* ----------------------------------------------------------------------- */
static void bt848_bright(struct bttv *btv, int bright) { int value; // printk("set bright: %d\n", bright); // DEBUG btv->bright = bright; /* We want -128 to 127 we get 0-65535 */ value = (bright >> 8) - 128; btwrite(value & 0xff, BT848_BRIGHT); }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil4193.18%133.33%
art haasart haas24.55%133.33%
gerd knorrgerd knorr12.27%133.33%
Total44100.00%3100.00%


static void bt848_hue(struct bttv *btv, int hue) { int value; btv->hue = hue; /* -128 to 127 */ value = (hue >> 8) - 128; btwrite(value & 0xff, BT848_HUE); }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil4195.35%150.00%
art haasart haas24.65%150.00%
Total43100.00%2100.00%


static void bt848_contrast(struct bttv *btv, int cont) { int value,hibit; btv->contrast = cont; /* 0-511 */ value = (cont >> 7); hibit = (value >> 6) & 4; btwrite(value & 0xff, BT848_CONTRAST_LO); btaor(hibit, ~4, BT848_E_CONTROL); btaor(hibit, ~4, BT848_O_CONTROL); }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil6994.52%133.33%
art haasart haas34.11%133.33%
gerd knorrgerd knorr11.37%133.33%
Total73100.00%3100.00%


static void bt848_sat(struct bttv *btv, int color) { int val_u,val_v,hibits; btv->saturation = color; /* 0-511 for the color */ val_u = ((color * btv->opt_uv_ratio) / 50) >> 7; val_v = (((color * (100 - btv->opt_uv_ratio) / 50) >>7)*180L)/254; hibits = (val_u >> 7) & 2; hibits |= (val_v >> 8) & 1; btwrite(val_u & 0xff, BT848_SAT_U_LO); btwrite(val_v & 0xff, BT848_SAT_V_LO); btaor(hibits, ~3, BT848_E_CONTROL); btaor(hibits, ~3, BT848_O_CONTROL); }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil12295.31%150.00%
gerd knorrgerd knorr64.69%150.00%
Total128100.00%2100.00%

/* ----------------------------------------------------------------------- */
static int video_mux(struct bttv *btv, unsigned int input) { int mux,mask2; if (input >= bttv_tvcards[btv->c.type].video_inputs) return -EINVAL; /* needed by RemoteVideo MX */ mask2 = bttv_tvcards[btv->c.type].gpiomask2; if (mask2) gpio_inout(mask2,mask2); if (input == btv->svhs) { btor(BT848_CONTROL_COMP, BT848_E_CONTROL); btor(BT848_CONTROL_COMP, BT848_O_CONTROL); } else { btand(~BT848_CONTROL_COMP, BT848_E_CONTROL); btand(~BT848_CONTROL_COMP, BT848_O_CONTROL); } mux = bttv_muxsel(btv, input); btaor(mux<<5, ~(3<<5), BT848_IFORM); dprintk("%d: video mux: input=%d mux=%d\n", btv->c.nr, input, mux); /* card specific hook */ if(bttv_tvcards[btv->c.type].muxsel_hook) bttv_tvcards[btv->c.type].muxsel_hook (btv, input); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil16390.56%133.33%
mauro carvalho chehabmauro carvalho chehab105.56%133.33%
andrew mortonandrew morton73.89%133.33%
Total180100.00%3100.00%

static char *audio_modes[] = { "audio: tuner", "audio: radio", "audio: extern", "audio: intern", "audio: mute" };
static void audio_mux_gpio(struct bttv *btv, int input, int mute) { int gpio_val, signal, mute_gpio; gpio_inout(bttv_tvcards[btv->c.type].gpiomask, bttv_tvcards[btv->c.type].gpiomask); signal = btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC; /* automute */ mute_gpio = mute || (btv->opt_automute && (!signal || !btv->users) && !btv->has_radio_tuner); if (mute_gpio) gpio_val = bttv_tvcards[btv->c.type].gpiomute; else gpio_val = bttv_tvcards[btv->c.type].gpiomux[input]; switch (btv->c.type) { case BTTV_BOARD_VOODOOTV_FM: case BTTV_BOARD_VOODOOTV_200: gpio_val = bttv_tda9880_setnorm(btv, gpio_val); break; default: gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpio_val); } if (bttv_gpio) bttv_gpio_tracking(btv, audio_modes[mute_gpio ? 4 : input]); }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil12972.07%220.00%
michael h. schimekmichael h. schimek2413.41%110.00%
pre-gitpre-git126.70%330.00%
frank schaeferfrank schaefer84.47%220.00%
gerd knorrgerd knorr52.79%110.00%
douglas schilling landgrafdouglas schilling landgraf10.56%110.00%
Total179100.00%10100.00%


static int audio_mute(struct bttv *btv, int mute) { struct v4l2_ctrl *ctrl; audio_mux_gpio(btv, btv->audio_input, mute); if (btv->sd_msp34xx) { ctrl = v4l2_ctrl_find(btv->sd_msp34xx->ctrl_handler, V4L2_CID_AUDIO_MUTE); if (ctrl) v4l2_ctrl_s_ctrl(ctrl, mute); } if (btv->sd_tvaudio) { ctrl = v4l2_ctrl_find(btv->sd_tvaudio->ctrl_handler, V4L2_CID_AUDIO_MUTE); if (ctrl) v4l2_ctrl_s_ctrl(ctrl, mute); } if (btv->sd_tda7432) { ctrl = v4l2_ctrl_find(btv->sd_tda7432->ctrl_handler, V4L2_CID_AUDIO_MUTE); if (ctrl) v4l2_ctrl_s_ctrl(ctrl, mute); } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
frank schaeferfrank schaefer9875.97%250.00%
hans verkuilhans verkuil1713.18%125.00%
michael h. schimekmichael h. schimek1410.85%125.00%
Total129100.00%4100.00%


static int audio_input(struct bttv *btv, int input) { audio_mux_gpio(btv, input, btv->mute); if (btv->sd_msp34xx) { u32 in; /* Note: the inputs tuner/radio/extern/intern are translated to msp routings. This assumes common behavior for all msp3400 based TV cards. When this assumption fails, then the specific MSP routing must be added to the card table. For now this is sufficient. */ switch (input) { case TVAUDIO_INPUT_RADIO: /* Some boards need the msp do to the radio demod */ if (btv->radio_uses_msp_demodulator) { in = MSP_INPUT_DEFAULT; break; } in = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1, MSP_DSP_IN_SCART, MSP_DSP_IN_SCART); break; case TVAUDIO_INPUT_EXTERN: in = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, MSP_DSP_IN_SCART, MSP_DSP_IN_SCART); break; case TVAUDIO_INPUT_INTERN: /* Yes, this is the same input as for RADIO. I doubt if this is ever used. The only board with an INTERN input is the BTTV_BOARD_AVERMEDIA98. I wonder how that was tested. My guess is that the whole INTERN input does not work. */ in = MSP_INPUT(MSP_IN_SCART2, MSP_IN_TUNER1, MSP_DSP_IN_SCART, MSP_DSP_IN_SCART); break; case TVAUDIO_INPUT_TUNER: default: /* This is the only card that uses TUNER2, and afaik, is the only difference between the VOODOOTV_FM and VOODOOTV_200 */ if (btv->c.type == BTTV_BOARD_VOODOOTV_200) in = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER2, \ MSP_DSP_IN_TUNER, MSP_DSP_IN_TUNER); else in = MSP_INPUT_DEFAULT; break; } v4l2_subdev_call(btv->sd_msp34xx, audio, s_routing, in, MSP_OUTPUT_DEFAULT, 0); } if (btv->sd_tvaudio) { v4l2_subdev_call(btv->sd_tvaudio, audio, s_routing, input, 0, 0); } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil13370.74%114.29%
frank schaeferfrank schaefer3418.09%114.29%
gerd knorrgerd knorr94.79%228.57%
michael h. schimekmichael h. schimek94.79%114.29%
pre-gitpre-git31.60%228.57%
Total188100.00%7100.00%


static void bttv_crop_calc_limits(struct bttv_crop *c) { /* Scale factor min. 1:1, max. 16:1. Min. image size 48 x 32. Scaled width must be a multiple of 4. */ if (1) { /* For bug compatibility with VIDIOCGCAP and image size checks in earlier driver versions. */ c->min_scaled_width = 48; c->min_scaled_height = 32; } else { c->min_scaled_width = (max_t(unsigned int, 48, c->rect.width >> 4) + 3) & ~3; c->min_scaled_height = max_t(unsigned int, 32, c->rect.height >> 4); } c->max_scaled_width = c->rect.width & ~3; c->max_scaled_height = c->rect.height; }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil5660.87%114.29%
pre-gitpre-git2628.26%457.14%
ricardo ribaldaricardo ribalda88.70%114.29%
gerd knorrgerd knorr22.17%114.29%
Total92100.00%7100.00%


static void bttv_crop_reset(struct bttv_crop *c, unsigned int norm) { c->rect = bttv_tvnorms[norm].cropcap.defrect; bttv_crop_calc_limits(c); }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil2678.79%133.33%
pre-gitpre-git721.21%266.67%
Total33100.00%3100.00%

/* Call with btv->lock down. */
static int set_tvnorm(struct bttv *btv, unsigned int norm) { const struct bttv_tvnorm *tvnorm; v4l2_std_id id; BUG_ON(norm >= BTTV_TVNORMS); BUG_ON(btv->tvnorm >= BTTV_TVNORMS); tvnorm = &bttv_tvnorms[norm]; if (memcmp(&bttv_tvnorms[btv->tvnorm].cropcap, &tvnorm->cropcap, sizeof (tvnorm->cropcap))) { bttv_crop_reset(&btv->crop[0], norm); btv->crop[1] = btv->crop[0]; /* current = default */ if (0 == (btv->resources & VIDEO_RESOURCES)) { btv->crop_start = tvnorm->cropcap.bounds.top + tvnorm->cropcap.bounds.height; } } btv->tvnorm = norm; btwrite(tvnorm->adelay, BT848_ADELAY); btwrite(tvnorm->bdelay, BT848_BDELAY); btaor(tvnorm->iform,~(BT848_IFORM_NORM|BT848_IFORM_XTBOTH), BT848_IFORM); btwrite(tvnorm->vbipack, BT848_VBI_PACK_SIZE); btwrite(1, BT848_VBI_PACK_DEL); bt848A_set_timing(btv); switch (btv->c.type) { case BTTV_BOARD_VOODOOTV_FM: case BTTV_BOARD_VOODOOTV_200: bttv_tda9880_setnorm(btv, gpio_read()); break; } id = tvnorm->v4l2_id; bttv_call_all(btv, video, s_std, id); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil17571.43%120.00%
gerd knorrgerd knorr6928.16%360.00%
laurent pinchartlaurent pinchart10.41%120.00%
Total245100.00%5100.00%

/* Call with btv->lock down. */
static void set_input(struct bttv *btv, unsigned int input, unsigned int norm) { unsigned long flags; btv->input = input; if (irq_iswitch) { spin_lock_irqsave(&btv->s_lock,flags); if (btv->curr.frame_irq) { /* active capture -> delayed input switch */ btv->new_input = input; } else { video_mux(btv,input); } spin_unlock_irqrestore(&btv->s_lock,flags); } else { video_mux(btv,input); } btv->audio_input = (btv->tuner_type != TUNER_ABSENT && input == 0) ? TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN; audio_input(btv, btv->audio_input); set_tvnorm(btv, norm); }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil7155.47%114.29%
gerd knorrgerd knorr2721.09%114.29%
pre-gitpre-git1914.84%342.86%
frank schaeferfrank schaefer118.59%228.57%
Total128100.00%7100.00%


static void init_irqreg(struct bttv *btv) { /* clear status */ btwrite(0xfffffUL, BT848_INT_STAT); if (bttv_tvcards[btv->c.type].no_video) { /* i2c only */ btwrite(BT848_INT_I2CDONE, BT848_INT_MASK); } else { /* full video */ btwrite((btv->triton1) | (btv->gpioirq ? BT848_INT_GPINT : 0) | BT848_INT_SCERR | (fdsr ? BT848_INT_FDSR : 0) | BT848_INT_RISCI | BT848_INT_OCERR | BT848_INT_FMTCHG|BT848_INT_HLOCK| BT848_INT_I2CDONE, BT848_INT_MASK); } }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil6170.11%116.67%
gerd knorrgerd knorr1314.94%116.67%
mauro carvalho chehabmauro carvalho chehab78.05%116.67%
pre-gitpre-git66.90%350.00%
Total87100.00%6100.00%


static void init_bt848(struct bttv *btv) { if (bttv_tvcards[btv->c.type].no_video) { /* very basic init only */ init_irqreg(btv); return; } btwrite(0x00, BT848_CAP_CTL); btwrite(BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL); btwrite(BT848_IFORM_XTAUTO | BT848_IFORM_AUTO, BT848_IFORM); /* set planar and packed mode trigger points and */ /* set rising edge of inverted GPINTR pin as irq trigger */ btwrite(BT848_GPIO_DMA_CTL_PKTP_32| BT848_GPIO_DMA_CTL_PLTP1_16| BT848_GPIO_DMA_CTL_PLTP23_16| BT848_GPIO_DMA_CTL_GPINTC| BT848_GPIO_DMA_CTL_GPINTI, BT848_GPIO_DMA_CTL); btwrite(0x20, BT848_E_VSCALE_HI); btwrite(0x20, BT848_O_VSCALE_HI); v4l2_ctrl_handler_setup(&btv->ctrl_handler); /* interrupt */ init_irqreg(btv); }

Contributors

PersonTokensPropCommitsCommitProp
gerd knorrgerd knorr4443.56%114.29%
hans verkuilhans verkuil4443.56%114.29%
pre-gitpre-git87.92%342.86%
trent piephotrent piepho32.97%114.29%
andrew mortonandrew morton21.98%114.29%
Total101100.00%7100.00%


static void bttv_reinit_bt848(struct bttv *btv) { unsigned long flags; if (bttv_verbose) pr_info("%d: reset, reinitialize\n", btv->c.nr); spin_lock_irqsave(&btv->s_lock,flags); btv->errors=0; bttv_set_dma(btv,0); spin_unlock_irqrestore(&btv->s_lock,flags); init_bt848(btv); btv->pll.pll_current = -1; set_input(btv, btv->input, btv->tvnorm); }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil5965.56%228.57%
gerd knorrgerd knorr1718.89%228.57%
pre-gitpre-git1213.33%228.57%
andrew mortonandrew morton22.22%114.29%
Total90100.00%7100.00%


static int bttv_s_ctrl(struct v4l2_ctrl *c) { struct bttv *btv = container_of(c->handler, struct bttv, ctrl_handler); int val; switch (c->id) { case V4L2_CID_BRIGHTNESS: bt848_bright(btv, c->val); break; case V4L2_CID_HUE: bt848_hue(btv, c->val); break; case V4L2_CID_CONTRAST: bt848_contrast(btv, c->val); break; case V4L2_CID_SATURATION: bt848_sat(btv, c->val); break; case V4L2_CID_COLOR_KILLER: if (c->val) { btor(BT848_SCLOOP_CKILL, BT848_E_SCLOOP); btor(BT848_SCLOOP_CKILL, BT848_O_SCLOOP); } else { btand(~BT848_SCLOOP_CKILL, BT848_E_SCLOOP); btand(~BT848_SCLOOP_CKILL, BT848_O_SCLOOP); } break; case V4L2_CID_AUDIO_MUTE: audio_mute(btv, c->val); btv->mute = c->val; break; case V4L2_CID_AUDIO_VOLUME: btv->volume_gpio(btv, c->val); break; case V4L2_CID_CHROMA_AGC: val = c->val ? BT848_SCLOOP_CAGC : 0; btwrite(val, BT848_E_SCLOOP); btwrite(val, BT848_O_SCLOOP); break; case V4L2_CID_PRIVATE_COMBFILTER: btv->opt_combfilter = c->val; break; case V4L2_CID_PRIVATE_LUMAFILTER: if (c->val) { btand(~BT848_CONTROL_LDEC, BT848_E_CONTROL); btand(~BT848_CONTROL_LDEC, BT848_O_CONTROL); } else { btor(BT848_CONTROL_LDEC, BT848_E_CONTROL); btor(BT848_CONTROL_LDEC, BT848_O_CONTROL); } break; case V4L2_CID_PRIVATE_AUTOMUTE: btv->opt_automute = c->val; break; case V4L2_CID_PRIVATE_AGC_CRUSH: btwrite(BT848_ADC_RESERVED | (c->val ? BT848_ADC_CRUSH : 0), BT848_ADC); break; case V4L2_CID_PRIVATE_VCR_HACK: btv->opt_vcr_hack = c->val; break; case V4L2_CID_PRIVATE_WHITECRUSH_UPPER: btwrite(c->val, BT848_WC_UP); break; case V4L2_CID_PRIVATE_WHITECRUSH_LOWER: btwrite(c->val, BT848_WC_DOWN); break; case V4L2_CID_PRIVATE_UV_RATIO: btv->opt_uv_ratio = c->val; bt848_sat(btv, btv->saturation); break; case V4L2_CID_PRIVATE_FULL_LUMA_RANGE: btaor((c->val << 7), ~BT848_OFORM_RANGE, BT848_OFORM); break; case V4L2_CID_PRIVATE_CORING: btaor((c->val << 5), ~BT848_OFORM_CORE32, BT848_OFORM); break; default: return -EINVAL; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil32481.61%535.71%
michael h. schimekmichael h. schimek205.04%17.14%
trent piephotrent piepho133.27%17.14%
gerd knorrgerd knorr102.52%17.14%
frank schaeferfrank schaefer82.02%17.14%
wade berrierwade berrier82.02%17.14%
pre-gitpre-git71.76%214.29%
hans de goedehans de goede61.51%17.14%
andrew mortonandrew morton10.25%17.14%
Total397100.00%14100.00%

/* ----------------------------------------------------------------------- */ static const struct v4l2_ctrl_ops bttv_ctrl_ops = { .s_ctrl = bttv_s_ctrl, }; static struct v4l2_ctrl_config bttv_ctrl_combfilter = { .ops = &bttv_ctrl_ops, .id = V4L2_CID_PRIVATE_COMBFILTER, .name = "Comb Filter", .type = V4L2_CTRL_TYPE_BOOLEAN, .min = 0, .max = 1, .step = 1, .def = 1, }; static struct v4l2_ctrl_config bttv_ctrl_automute = { .ops = &bttv_ctrl_ops, .id = V4L2_CID_PRIVATE_AUTOMUTE, .name = "Auto Mute", .type = V4L2_CTRL_TYPE_BOOLEAN, .min = 0, .max = 1, .step = 1, .def = 1, }; static struct v4l2_ctrl_config bttv_ctrl_lumafilter = { .ops = &bttv_ctrl_ops, .id = V4L2_CID_PRIVATE_LUMAFILTER, .name = "Luma Decimation Filter", .type = V4L2_CTRL_TYPE_BOOLEAN, .min = 0, .max = 1, .step = 1, .def = 1, }; static struct v4l2_ctrl_config bttv_ctrl_agc_crush = { .ops = &bttv_ctrl_ops, .id = V4L2_CID_PRIVATE_AGC_CRUSH, .name = "AGC Crush", .type = V4L2_CTRL_TYPE_BOOLEAN, .min = 0, .max = 1, .step = 1, .def = 1, }; static struct v4l2_ctrl_config bttv_ctrl_vcr_hack = { .ops = &bttv_ctrl_ops, .id = V4L2_CID_PRIVATE_VCR_HACK, .name = "VCR Hack", .type = V4L2_CTRL_TYPE_BOOLEAN, .min = 0, .max = 1, .step = 1, .def = 1, }; static struct v4l2_ctrl_config bttv_ctrl_whitecrush_lower = { .ops = &bttv_ctrl_ops, .id = V4L2_CID_PRIVATE_WHITECRUSH_LOWER, .name = "Whitecrush Lower", .type = V4L2_CTRL_TYPE_INTEGER, .min = 0, .max = 255, .step = 1, .def = 0x7f, }; static struct v4l2_ctrl_config bttv_ctrl_whitecrush_upper = { .ops = &bttv_ctrl_ops, .id = V4L2_CID_PRIVATE_WHITECRUSH_UPPER, .name = "Whitecrush Upper", .type = V4L2_CTRL_TYPE_INTEGER, .min = 0, .max = 255, .step = 1, .def = 0xcf, }; static struct v4l2_ctrl_config bttv_ctrl_uv_ratio = { .ops = &bttv_ctrl_ops, .id = V4L2_CID_PRIVATE_UV_RATIO, .name = "UV Ratio", .type = V4L2_CTRL_TYPE_INTEGER, .min = 0, .max = 100, .step = 1, .def = 50, }; static struct v4l2_ctrl_config bttv_ctrl_full_luma = { .ops = &bttv_ctrl_ops, .id = V4L2_CID_PRIVATE_FULL_LUMA_RANGE, .name = "Full Luma Range", .type = V4L2_CTRL_TYPE_BOOLEAN, .min = 0, .max = 1, .step = 1, }; static struct v4l2_ctrl_config bttv_ctrl_coring = { .ops = &bttv_ctrl_ops, .id = V4L2_CID_PRIVATE_CORING, .name = "Coring", .type = V4L2_CTRL_TYPE_INTEGER, .min = 0, .max = 3, .step = 1, }; /* ----------------------------------------------------------------------- */
void bttv_gpio_tracking(struct bttv *btv, char *comment) { unsigned int outbits, data; outbits = btread(BT848_GPIO_OUT_EN); data = btread(BT848_GPIO_DATA); pr_debug("%d: gpio: en=%08x, out=%08x in=%08x [%s]\n", btv->c.nr, outbits, data & outbits, data & ~outbits, comment); }

Contributors

PersonTokensPropCommitsCommitProp
mauro carvalho chehabmauro carvalho chehab4272.41%116.67%
douglas schilling landgrafdouglas schilling landgraf610.34%116.67%
gerd knorrgerd knorr58.62%116.67%
pre-gitpre-git35.17%233.33%
joe perchesjoe perches23.45%116.67%
Total58100.00%6100.00%


static void bttv_field_count(struct bttv *btv) { int need_count = 0; if (btv->users) need_count++; if (need_count) { /* start field counter */ btor(BT848_INT_VSYNC,BT848_INT_MASK); } else { /* stop field counter */ btand(~BT848_INT_VSYNC,BT848_INT_MASK); btv->field_count = 0; } }

Contributors

PersonTokensPropCommitsCommitProp
mauro carvalho chehabmauro carvalho chehab4477.19%120.00%
douglas schilling landgrafdouglas schilling landgraf610.53%120.00%
gerd knorrgerd knorr58.77%240.00%
pre-gitpre-git23.51%120.00%
Total57100.00%5100.00%


static const struct bttv_format* format_by_fourcc(int fourcc) { unsigned int i; for (i = 0; i < FORMATS; i++) { if (-1 == formats[i].fourcc) continue; if (formats[i].fourcc == fourcc) return formats+i; } return NULL; }

Contributors

PersonTokensPropCommitsCommitProp
mauro carvalho chehabmauro carvalho chehab6095.24%150.00%
douglas schilling landgrafdouglas schilling landgraf34.76%150.00%
Total63100.00%2100.00%

/* ----------------------------------------------------------------------- */ /* misc helpers */
static int bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh, struct bttv_buffer *new) { struct bttv_buffer *old; unsigned long flags; dprintk("switch_overlay: enter [new=%p]\n", new); if (new) new->vb.state = VIDEOBUF_DONE; spin_lock_irqsave(&btv->s_lock,flags); old = btv->screen; btv->screen = new; btv->loop_irq |= 1; bttv_set_dma(btv, 0x03); spin_unlock_irqrestore(&btv->s_lock,flags); if (NULL != old) { dprintk("switch_overlay: old=%p state is %d\n", old, old->vb.state); bttv_dma_free(&fh->cap,btv, old); kfree(old); } if (NULL == new) free_btres_lock(btv,fh,RESOURCE_OVERLAY); dprintk("switch_overlay: done\n"); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
mauro carvalho chehabmauro carvalho chehab12781.94%450.00%
douglas schilling landgrafdouglas schilling landgraf1811.61%112.50%
michael h. schimekmichael h. schimek53.23%112.50%
pre-gitpre-git31.94%112.50%
gerd knorrgerd knorr21.29%112.50%
Total155100.00%8100.00%

/* ----------------------------------------------------------------------- */ /* video4linux (1) interface */
static int bttv_prepare_buffer(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf, const struct bttv_format *fmt, unsigned int width, unsigned int height, enum v4l2_field field) { struct bttv_fh *fh = q->priv_data; int redo_dma_risc = 0; struct bttv_crop c; int norm; int rc; /* check settings */ if (NULL == fmt) return -EINVAL; if (fmt->btformat == BT848_COLOR_FMT_RAW) { width = RAW_BPL; height = RAW_LINES*2; if (width*height > buf->vb.bsize) return -EINVAL; buf->vb.size = buf->vb.bsize; /* Make sure tvnorm and vbi_end remain consistent until we're done. */ norm = btv->tvnorm; /* In this mode capturing always starts at defrect.top (default VDELAY), ignoring cropping parameters. */ if (btv->vbi_end > bttv_tvnorms[norm].cropcap.defrect.top) { return -EINVAL; } c.rect = bttv_tvnorms[norm].cropcap.defrect; } else { norm = btv->tvnorm; c = btv->crop[!!fh->do_crop]; if (width < c.min_scaled_width || width > c.max_scaled_width || height < c.min_scaled_height) return -EINVAL; switch (field) { case V4L2_FIELD_TOP: case V4L2_FIELD_BOTTOM: case V4L2_FIELD_ALTERNATE: /* btv->crop counts frame lines. Max. scale factor is 16:1 for frames, 8:1 for fields. */ if (height * 2 > c.max_scaled_height) return -EINVAL; break; default: if (height > c.max_scaled_height) return -EINVAL; break; } buf->vb.size = (width * height * fmt->depth) >> 3; if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) return -EINVAL; } /* alloc + fill struct bttv_buffer (if changed) */ if (buf->vb.width != width || buf->vb.height != height || buf->vb.field != field || buf->tvnorm != norm || buf->fmt != fmt || buf->crop.top != c.rect.top || buf->crop.left != c.rect.left || buf->crop.width != c.rect.width || buf->crop.height != c.rect.height) { buf->vb.width = width; buf->vb.height = height; buf->vb.field = field; buf->tvnorm = norm; buf->fmt = fmt; buf->crop = c.rect; redo_dma_risc = 1; } /* alloc risc memory */ if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { redo_dma_risc = 1; if (0 != (rc = videobuf_iolock(q,&buf->vb,&btv->fbuf))) goto fail; } if (redo_dma_risc) if (0 != (rc = bttv_buffer_risc(btv,buf))) goto fail; buf->vb.state = VIDEOBUF_PREPARED; return 0; fail: bttv_dma_free(q,btv,buf); return rc; }

Contributors

PersonTokensPropCommitsCommitProp
mauro carvalho chehabmauro carvalho chehab39675.00%228.57%
douglas schilling landgrafdouglas schilling landgraf458.52%114.29%
michael h. schimekmichael h. schimek387.20%114.29%
gerd knorrgerd knorr366.82%228.57%
pre-gitpre-git132.46%114.29%
Total528100.00%7100.00%


static int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) { struct bttv_fh *fh = q->priv_data; *size = fh->fmt->depth*fh->width*fh->height >> 3; if (0 == *count) *count = gbuffers; if (*size * *count > gbuffers * gbufsize) *count = (gbuffers * gbufsize) / *size; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
mauro carvalho chehabmauro carvalho chehab6776.14%125.00%
douglas schilling landgrafdouglas schilling landgraf1112.50%125.00%
andreas bombeandreas bombe910.23%125.00%
pre-gitpre-git11.14%125.00%
Total88100.00%4100.00%


static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, enum v4l2_field field) { struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); struct bttv_fh *fh = q->priv_data; return bttv_prepare_buffer(q,fh->btv, buf, fh->fmt, fh->width, fh->height, field); }

Contributors

PersonTokensPropCommitsCommitProp
mauro carvalho chehabmauro carvalho chehab4767.14%150.00%
douglas schilling landgrafdouglas schilling landgraf2332.86%150.00%
Total70100.00%2100.00%


static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) { struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); struct bttv_fh *fh = q->priv_data; struct bttv *btv = fh->btv; buf->vb.state = VIDEOBUF_QUEUED; list_add_tail(&buf->vb.queue,&btv->capture); if (!btv->curr.frame_irq) { btv->loop_irq |= 1; bttv_set_dma(btv, 0x03); } }

Contributors

PersonTokensPropCommitsCommitProp
mauro carvalho chehabmauro carvalho chehab5456.25%116.67%
douglas schilling landgrafdouglas schilling landgraf2930.21%116.67%
gerd knorrgerd knorr1212.50%350.00%
pre-gitpre-git11.04%116.67%
Total96100.00%6100.00%


static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) { struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb); struct bttv_fh *fh = q->priv_data; bttv_dma_free(q,fh->btv,buf); }

Contributors

PersonTokensPropCommitsCommitProp
mauro carvalho chehabmauro carvalho chehab4282.35%125.00%
douglas schilling landgrafdouglas schilling landgraf47.84%125.00%
gerd knorrgerd knorr35.88%125.00%
pre-gitpre-git23.92%125.00%
Total51100.00%4100.00%

static struct videobuf_queue_ops bttv_video_qops = { .buf_setup = buffer_setup, .buf_prepare = buffer_prepare, .buf_queue = buffer_queue, .buf_release = buffer_release, };
static void radio_enable(struct bttv *btv) { /* Switch to the radio tuner */ if (!btv->has_radio_tuner) { btv->has_radio_tuner = 1; bttv_call_all(btv, tuner, s_radio); btv->audio_input = TVAUDIO_INPUT_RADIO; audio_input(btv, btv->audio_input); } }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil4282.35%133.33%
frank schaeferfrank schaefer917.65%266.67%
Total51100.00%3100.00%


static int bttv_s_std(struct file *file, void *priv, v4l2_std_id id) { struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; unsigned int i; for (i = 0; i < BTTV_TVNORMS; i++) if (id & bttv_tvnorms[i].v4l2_id) break; if (i == BTTV_TVNORMS) return -EINVAL; btv->std = id; set_tvnorm(btv, i); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
mauro carvalho chehabmauro carvalho chehab3134.83%112.50%
douglas schilling landgrafdouglas schilling landgraf2730.34%112.50%
gerd knorrgerd knorr2123.60%337.50%
hans verkuilhans verkuil66.74%112.50%
sf markus elfringsf markus elfring33.37%112.50%
pre-gitpre-git11.12%112.50%
Total89100.00%8100.00%


static int bttv_g_std(struct file *file, void *priv, v4l2_std_id *id) { struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; *id = btv->std; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil45100.00%1100.00%
Total45100.00%1100.00%


static int bttv_querystd(struct file *file, void *f, v4l2_std_id *id) { struct bttv_fh *fh = f; struct bttv *btv = fh->btv; if (btread(BT848_DSTATUS) & BT848_DSTATUS_NUML) *id &= V4L2_STD_625_50; else *id &= V4L2_STD_525_60; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
gerd knorrgerd knorr2034.48%342.86%
mauro carvalho chehabmauro carvalho chehab1831.03%114.29%
douglas schilling landgrafdouglas schilling landgraf1729.31%114.29%
hans verkuilhans verkuil23.45%114.29%
pre-gitpre-git11.72%114.29%
Total58100.00%7100.00%


static int bttv_enum_input(struct file *file, void *priv, struct v4l2_input *i) { struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; if (i->index >= bttv_tvcards[btv->c.type].video_inputs) return -EINVAL; i->type = V4L2_INPUT_TYPE_CAMERA; i->audioset = 0; if (btv->tuner_type != TUNER_ABSENT && i->index == 0) { sprintf(i->name, "Television"); i->type = V4L2_INPUT_TYPE_TUNER; i->tuner = 0; } else if (i->index == btv->svhs) { sprintf(i->name, "S-Video"); } else { sprintf(i->name, "Composite%d", i->index); } if (i->index == btv->input) { __u32 dstatus = btread(BT848_DSTATUS); if (0 == (dstatus & BT848_DSTATUS_PRES)) i->status |= V4L2_IN_ST_NO_SIGNAL; if (0 == (dstatus & BT848_DSTATUS_HLOC)) i->status |= V4L2_IN_ST_NO_H_LOCK; } i->std = BTTV_NORMS; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
mauro carvalho chehabmauro carvalho chehab13264.39%218.18%
gerd knorrgerd knorr3416.59%436.36%
douglas schilling landgrafdouglas schilling landgraf2612.68%19.09%
trent piephotrent piepho94.39%218.18%
sf markus elfringsf markus elfring31.46%19.09%
hans verkuilhans verkuil10.49%19.09%
Total205100.00%11100.00%


static int bttv_g_input(struct file *file, void *priv, unsigned int *i) { struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; *i = btv->input; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
mauro carvalho chehabmauro carvalho chehab2043.48%114.29%
gerd knorrgerd knorr1021.74%228.57%
douglas schilling landgrafdouglas schilling landgraf715.22%114.29%
pre-gitpre-git613.04%228.57%
nickolay v. shmyrevnickolay v. shmyrev36.52%114.29%
Total46100.00%7100.00%


static int bttv_s_input(struct file *file, void *priv, unsigned int i) { struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; if (i >= bttv_tvcards[btv->c.type].video_inputs) return -EINVAL; set_input(btv, i, btv->tvnorm); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
douglas schilling landgrafdouglas schilling landgraf3450.00%116.67%
mauro carvalho chehabmauro carvalho chehab2232.35%116.67%
nickolay v. shmyrevnickolay v. shmyrev57.35%116.67%
gerd knorrgerd knorr34.41%116.67%
hans verkuilhans verkuil34.41%116.67%
pre-gitpre-git11.47%116.67%
Total68100.00%6100.00%


static int bttv_s_tuner(struct file *file, void *priv, const struct v4l2_tuner *t) { struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; if (t->index) return -EINVAL; bttv_call_all(btv, tuner, s_tuner, t); if (btv->audio_mode_gpio) { struct v4l2_tuner copy = *t; btv->audio_mode_gpio(btv, &copy, 1); } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
douglas schilling landgrafdouglas schilling landgraf3539.77%110.00%
mauro carvalho chehabmauro carvalho chehab2629.55%220.00%
hans verkuilhans verkuil1618.18%220.00%
nickolay v. shmyrevnickolay v. shmyrev55.68%110.00%
gerd knorrgerd knorr44.55%220.00%
pre-gitpre-git22.27%220.00%
Total88100.00%10100.00%


static int bttv_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f) { struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; if (f->tuner) return -EINVAL; if (f->type == V4L2_TUNER_RADIO) radio_enable(btv); f->frequency = f->type == V4L2_TUNER_RADIO ? btv->radio_freq : btv->tv_freq; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
mauro carvalho chehabmauro carvalho chehab4252.50%114.29%
hans verkuilhans verkuil3240.00%342.86%
douglas schilling landgrafdouglas schilling landgraf33.75%114.29%
pre-gitpre-git22.50%114.29%
nickolay v. shmyrevnickolay v. shmyrev11.25%114.29%
Total80100.00%7100.00%


static void bttv_set_frequency(struct bttv *btv, const struct v4l2_frequency *f) { struct v4l2_frequency new_freq = *f; bttv_call_all(btv, tuner, s_frequency, f); /* s_frequency may clamp the frequency, so get the actual frequency before assigning radio/tv_freq. */ bttv_call_all(btv, tuner, g_frequency, &new_freq); if (new_freq.type == V4L2_TUNER_RADIO) { radio_enable(btv); btv->radio_freq = new_freq.frequency; if (btv->has_tea575x) { btv->tea.freq = btv->radio_freq; snd_tea575x_set_freq(&btv->tea); } } else { btv->tv_freq = new_freq.frequency; } }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil9386.11%375.00%
ondrej zaryondrej zary1513.89%125.00%
Total108100.00%4100.00%


static int bttv_s_frequency(struct file *file, void *priv, const struct v4l2_frequency *f) { struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; if (f->tuner) return -EINVAL; bttv_set_frequency(btv, f); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
mauro carvalho chehabmauro carvalho chehab4985.96%233.33%
nickolay v. shmyrevnickolay v. shmyrev47.02%116.67%
douglas schilling landgrafdouglas schilling landgraf23.51%116.67%
hans verkuilhans verkuil23.51%233.33%
Total57100.00%6100.00%


static int bttv_log_status(struct file *file, void *f) { struct video_device *vdev = video_devdata(file); struct bttv_fh *fh = f; struct bttv *btv = fh->btv; v4l2_ctrl_handler_log_status(vdev->ctrl_handler, btv->c.v4l2_dev.name); bttv_call_all(btv, core, log_status); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
mauro carvalho chehabmauro carvalho chehab3247.06%120.00%
hans verkuilhans verkuil2841.18%240.00%
nickolay v. shmyrevnickolay v. shmyrev57.35%120.00%
douglas schilling landgrafdouglas schilling landgraf34.41%120.00%
Total68100.00%5100.00%

#ifdef CONFIG_VIDEO_ADV_DEBUG
static int bttv_g_register(struct file *file, void *f, struct v4l2_dbg_register *reg) { struct bttv_fh *fh = f; struct bttv *btv = fh->btv; /* bt848 has a 12-bit register space */ reg->reg &= 0xfff; reg->val = btread(reg->reg); reg->size = 1; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
douglas schilling landgrafdouglas schilling landgraf5485.71%125.00%
hans verkuilhans verkuil711.11%125.00%
nickolay v. shmyrevnickolay v. shmyrev11.59%125.00%
mauro carvalho chehabmauro carvalho chehab11.59%125.00%
Total63100.00%4100.00%


static int bttv_s_register(struct file *file, void *f, const struct v4l2_dbg_register *reg) { struct bttv_fh *fh = f; struct bttv *btv = fh->btv; /* bt848 has a 12-bit register space */ btwrite(reg->val, reg->reg & 0xfff); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
douglas schilling landgrafdouglas schilling landgraf2851.85%110.00%
nickolay v. shmyrevnickolay v. shmyrev1120.37%110.00%
pre-gitpre-git59.26%330.00%
gerd knorrgerd knorr59.26%220.00%
hans verkuilhans verkuil47.41%220.00%
mauro carvalho chehabmauro carvalho chehab11.85%110.00%
Total54100.00%10100.00%

#endif /* Given cropping boundaries b and the scaled width and height of a single field or frame, which must not exceed hardware limits, this function adjusts the cropping parameters c. */
static void bttv_crop_adjust (struct bttv_crop * c, const struct v4l2_rect * b, __s32 width, __s32 height, enum v4l2_field field) { __s32 frame_height = height << !V4L2_FIELD_HAS_BOTH(field); __s32 max_left; __s32 max_top; if (width < c->min_scaled_width) { /* Max. hor. scale factor 16:1. */ c->rect.width = width * 16; } else if (width > c->max_scaled_width) { /* Min. hor. scale factor 1:1. */ c->rect.width = width; max_left = b->left + b->width - width; max_left = min(max_left, (__s32) MAX_HDELAY); if (c->rect.left > max_left) c->rect.left = max_left; } if (height < c->min_scaled_height) { /* Max. vert. scale factor 16:1, single fields 8:1. */ c->rect.height = height * 16; } else if (frame_height > c->max_scaled_height) { /* Min. vert. scale factor 1:1. Top and height count field lines times two. */ c->rect.height = (frame_height + 1) & ~1; max_top = b->top + b->height - c->rect.height; if (c->rect.top > max_top) c->rect.top = max_top; } bttv_crop_calc_limits(c); }

Contributors

PersonTokensPropCommitsCommitProp
nickolay v. shmyrevnickolay v. shmyrev15471.96%19.09%
gerd knorrgerd knorr2511.68%545.45%
michael h. schimekmichael h. schimek2210.28%19.09%
pre-gitpre-git83.74%327.27%
andrew mortonandrew morton52.34%19.09%
Total214100.00%11100.00%

/* Returns an error if scaling to a frame or single field with the given width and height is not possible with the current cropping parameters and width aligned according to width_mask. If adjust_size is TRUE the function may adjust the width and/or height instead, rounding width to (width + width_bias) & width_mask. If adjust_crop is TRUE it may also adjust the current cropping parameters to get closer to the desired image size. */
static int limit_scaled_size_lock (struct bttv_fh * fh, __s32 * width, __s32 * height, enum v4l2_field field, unsigned int width_mask, unsigned int width_bias, int adjust_size, int adjust_crop) { struct bttv *btv = fh->btv; const struct v4l2_rect *b; struct bttv_crop *c; __s32 min_width; __s32 min_height; __s32 max_width; __s32 max_height; int rc; BUG_ON((int) width_mask >= 0 || width_bias >= (unsigned int) -width_mask); /* Make sure tvnorm, vbi_end and the current cropping parameters remain consistent until we're done. */ b = &bttv_tvnorms[btv->tvnorm].cropcap.bounds; /* Do crop - use current, don't - use default parameters. */ c = &btv->crop[!!fh->do_crop]; if (fh->do_crop && adjust_size && adjust_crop && !locked_btres(btv, VIDEO_RESOURCES)) { min_width = 48; min_height = 32; /* We cannot scale up. When the scaled image is larger than crop.rect we adjust the crop.rect as required by the V4L2 spec, hence cropcap.bounds are our limit. */ max_width = min_t(unsigned int, b->width, MAX_HACTIVE); max_height = b->height; /* We cannot capture the same line as video and VBI data. Note btv->vbi_end is really a minimum, see bttv_vbi_try_fmt(). */ if (btv->vbi_end > b->top) { max_height -= btv->vbi_end - b->top; rc = -EBUSY; if (min_height > max_height) goto fail; } } else { rc = -EBUSY; if (btv->vbi_end > c->rect.top) goto fail; min_width = c->min_scaled_width; min_height = c->min_scaled_height; max_width = c->max_scaled_width; max_height = c->max_scaled_height; adjust_crop = 0; } min_width = (min_width - width_mask - 1) & width_mask; max_width = max_width & width_mask; /* Max. scale factor is 16:1 for frames, 8:1 for fields. */ min_height = min_height; /* Min. scale factor is 1:1. */ max_height >>= !V4L2_FIELD_HAS_BOTH(field); if (adjust_size) { *width = clamp(*width, min_width, max_width); *height = clamp(*height, min_height, max_height); /* Round after clamping to avoid overflow. */ *width = (*width + width_bias) & width_mask; if (adjust_crop) { bttv_crop_adjust(c, b, *width, *height, field); if (btv->vbi_end > c->rect.top) { /* Move the crop window out of the way. */ c->rect.top = btv->vbi_end; } } } else { rc = -EINVAL; if (*width < min_width || *height < min_height || *width > max_width || *height > max_height || 0 != (*width & ~width_mask)) goto fail; } rc = 0; /* success */ fail: return rc; }

Contributors

PersonTokensPropCommitsCommitProp
nickolay v. shmyrevnickolay v. shmyrev32074.25%16.67%
michael h. schimekmichael h. schimek4811.14%213.33%
gerd knorrgerd knorr399.05%320.00%
pre-gitpre-git163.71%640.00%
ricardo ribaldaricardo ribalda51.16%16.67%
mauro carvalho chehabmauro carvalho chehab30.70%213.33%
Total431100.00%15100.00%

/* Returns an error if the given overlay window dimensions are not possible with the current cropping parameters. If adjust_size is TRUE the function may adjust the window width and/or height instead, however it always rounds the horizontal position and width as btcx_align() does. If adjust_crop is TRUE the function may also adjust the current cropping parameters to get closer to the desired window size. */
static int verify_window_lock(struct bttv_fh *fh, struct v4l2_window *win, int adjust_size, int adjust_crop) { enum v4l2_field field; unsigned int width_mask; int rc; if (win->w.width < 48) win->w.width = 48; if (win->w.height < 32) win->w.height = 32; if (win->clipcount > 2048) win->clipcount = 2048; win->chromakey = 0; win->global_alpha = 0; field = win->field; switch (field) { case V4L2_FIELD_TOP: case V4L2_FIELD_BOTTOM: case V4L2_FIELD_INTERLACED: break; default: field = V4L2_FIELD_ANY; break; } if (V4L2_FIELD_ANY == field) { __s32 height2; height2 = fh->btv->crop[!!fh->do_crop].rect.height >> 1; field = (win->w.height > height2) ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; } win->field = field; if (NULL == fh->ovfmt) return -EINVAL; /* 4-byte alignment. */ width_mask = ~0; switch (fh->ovfmt->depth) { case 8: case 24: width_mask = ~3; break; case 16: width_mask = ~1; break; case 32: break; default: BUG(); } win->w.width -= win->w.left & ~width_mask; win->w.left = (win->w.left - width_mask - 1) & width_mask; rc = limit_scaled_size_lock(fh, &win->w.width, &win->w.height, field, width_mask, /* width_bias: round down */ 0, adjust_size, adjust_crop); if (0 != rc) return rc; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
nickolay v. shmyrevnickolay v. shmyrev18960.38%111.11%
hans verkuilhans verkuil6520.77%111.11%
gerd knorrgerd knorr319.90%333.33%
michael h. schimekmichael h. schimek237.35%111.11%
pre-gitpre-git30.96%222.22%
mauro carvalho chehabmauro carvalho chehab20.64%111.11%
Total313100.00%9100.00%


static int setup_window_lock(struct bttv_fh *fh, struct bttv *btv, struct v4l2_window *win, int fixup) { struct v4l2_clip *clips = NULL; int n,size,retval = 0; if (NULL == fh->ovfmt) return -EINVAL; if (!(fh->ovfmt->flags & FORMAT_FLAGS_PACKED)) return -EINVAL; retval = verify_window_lock(fh, win, /* adjust_size */ fixup, /* adjust_crop */ fixup); if (0 != retval) return retval; /* copy clips -- luckily v4l1 + v4l2 are binary compatible here ...*/ n = win->clipcount; size = sizeof(*clips)*(n+4); clips = kmalloc(size,GFP_KERNEL); if (NULL == clips) return -ENOMEM; if (n > 0) { if (copy_from_user(clips,win->clips,sizeof(struct v4l2_clip)*n)) { kfree(clips); return -EFAULT; } } /* clip against screen */ if (NULL != btv->fbuf.base) n = btcx_screen_clips(btv->fbuf.fmt.width, btv->fbuf.fmt.height, &win->w, clips, n); btcx_sort_clips(clips,n); /* 4-byte alignments */ switch (fh->ovfmt->depth) { case 8: case 24: btcx_align(&win->w, clips, n, 3); break; case 16: btcx_align(&win->w, clips, n, 1); break; case 32: /* no alignment fixups needed */ break; default: BUG(); } kfree(fh->ov.clips); fh->ov.clips = clips; fh->ov.nclips = n; fh->ov.w = win->w; fh->ov.field = win->field; fh->ov.setup_ok = 1; btv->init.ov.w.width = win->w.width; btv->init.ov.w.height = win->w.height; btv->init.ov.field = win->field; /* update overlay if needed */ retval = 0; if (check_btres(fh, RESOURCE_OVERLAY)) { struct bttv_buffer *new; new = videobuf_sg_alloc(sizeof(*new)); new->crop = btv->crop[!!fh->do_crop].rect; bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); retval = bttv_switch_overlay(btv,fh,new); } return retval; }

Contributors

PersonTokensPropCommitsCommitProp
nickolay v. shmyrevnickolay v. shmyrev34074.89%17.14%
michael h. schimekmichael h. schimek6313.88%17.14%
gerd knorrgerd knorr388.37%428.57%
pre-gitpre-git102.20%642.86%
mauro carvalho chehabmauro carvalho chehab20.44%17.14%
guennadi liakhovetskiguennadi liakhovetski10.22%17.14%
Total454100.00%14100.00%

/* ----------------------------------------------------------------------- */
static struct videobuf_queue* bttv_queue(struct bttv_fh *fh) { struct videobuf_queue* q = NULL; switch (fh->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: q = &fh->cap; break; case V4L2_BUF_TYPE_VBI_CAPTURE: q = &fh->vbi; break; default: BUG(); } return q; }

Contributors

PersonTokensPropCommitsCommitProp
nickolay v. shmyrevnickolay v. shmyrev4782.46%116.67%
michael h. schimekmichael h. schimek58.77%116.67%
mauro carvalho chehabmauro carvalho chehab23.51%116.67%
pre-gitpre-git23.51%233.33%
gerd knorrgerd knorr11.75%116.67%
Total57100.00%6100.00%


static int bttv_resource(struct bttv_fh *fh) { int res = 0; switch (fh->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: res = RESOURCE_VIDEO_STREAM; break; case V4L2_BUF_TYPE_VBI_CAPTURE: res = RESOURCE_VBI; break; default: BUG(); } return res; }

Contributors

PersonTokensPropCommitsCommitProp
nickolay v. shmyrevnickolay v. shmyrev3982.98%120.00%
pre-gitpre-git612.77%360.00%
michael h. schimekmichael h. schimek24.26%120.00%
Total47100.00%5100.00%


static int bttv_switch_type(struct bttv_fh *fh, enum v4l2_buf_type type) { struct videobuf_queue *q = bttv_queue(fh); int res = bttv_resource(fh); if (check_btres(fh,res)) return -EBUSY; if (videobuf_queue_is_busy(q)) return -EBUSY; fh->type = type; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
nickolay v. shmyrevnickolay v. shmyrev4974.24%120.00%
gerd knorrgerd knorr1015.15%240.00%
michael h. schimekmichael h. schimek69.09%120.00%
pre-gitpre-git11.52%120.00%
Total66100.00%5100.00%


static void pix_format_set_size (struct v4l2_pix_format * f, const struct bttv_format * fmt, unsigned int width, unsigned int height) { f->width = width; f->height = height; if (fmt->flags & FORMAT_FLAGS_PLANAR) { f->bytesperline = width; /* Y plane */ f->sizeimage = (width * height * fmt->depth) >> 3; } else { f->bytesperline = (width * fmt->depth) >> 3; f->sizeimage = height * f->bytesperline; } }

Contributors

PersonTokensPropCommitsCommitProp
nickolay v. shmyrevnickolay v. shmyrev7981.44%114.29%
michael h. schimekmichael h. schimek88.25%114.29%
gerd knorrgerd knorr77.22%228.57%
pre-gitpre-git33.09%342.86%
Total97100.00%7100.00%


static int bttv_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { struct bttv_fh *fh = priv; pix_format_set_size(&f->fmt.pix, fh->fmt, fh->width, fh->height); f->fmt.pix.field = fh->cap.field; f->fmt.pix.pixelformat = fh->fmt->fourcc; f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
nickolay v. shmyrevnickolay v. shmyrev4347.78%116.67%
douglas schilling landgrafdouglas schilling landgraf1415.56%116.67%
gerd knorrgerd knorr1314.44%116.67%
hans verkuilhans verkuil1112.22%233.33%
michael h. schimekmichael h. schimek910.00%116.67%
Total90100.00%6100.00%


static int bttv_g_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_format *f) { struct bttv_fh *fh = priv; f->fmt.win.w = fh->ov.w; f->fmt.win.field = fh->ov.field; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
douglas schilling landgrafdouglas schilling landgraf2441.38%120.00%
nickolay v. shmyrevnickolay v. shmyrev1729.31%120.00%
gerd knorrgerd knorr813.79%120.00%
michael h. schimekmichael h. schimek813.79%120.00%
hans verkuilhans verkuil11.72%120.00%
Total58100.00%5100.00%


static void bttv_get_width_mask_vid_cap(const struct bttv_format *fmt, unsigned int *width_mask, unsigned int *width_bias) { if (fmt->flags & FORMAT_FLAGS_PLANAR) { *width_mask = ~15; /* width must be a multiple of 16 pixels */ *width_bias = 8; /* nearest */ } else { *width_mask = ~3; /* width must be a multiple of 4 pixels */ *width_bias = 2; /* nearest */ } }

Contributors

PersonTokensPropCommitsCommitProp
hans de goedehans de goede61100.00%1100.00%
Total61100.00%1100.00%


static int bttv_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { const struct bttv_format *fmt; struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; enum v4l2_field field; __s32 width, height; __s32 height2; unsigned int width_mask, width_bias; int rc; fmt = format_by_fourcc(f->fmt.pix.pixelformat); if (NULL == fmt) return -EINVAL; field = f->fmt.pix.field; switch (field) { case V4L2_FIELD_TOP: case V4L2_FIELD_BOTTOM: case V4L2_FIELD_ALTERNATE: case V4L2_FIELD_INTERLACED: break; case V4L2_FIELD_SEQ_BT: case V4L2_FIELD_SEQ_TB: if (!(fmt->flags & FORMAT_FLAGS_PLANAR)) { field = V4L2_FIELD_SEQ_TB; break; } /* fall through */ default: /* FIELD_ANY case */ height2 = btv->crop[!!fh->do_crop].rect.height >> 1; field = (f->fmt.pix.height > height2) ? V4L2_FIELD_INTERLACED : V4L2_FIELD_BOTTOM; break; } width = f->fmt.pix.width; height = f->fmt.pix.height; bttv_get_width_mask_vid_cap(fmt, &width_mask, &width_bias); rc = limit_scaled_size_lock(fh, &width, &height, field, width_mask, width_bias, /* adjust_size */ 1, /* adjust_crop */ 0); if (0 != rc) return rc; /* update data for the application */ f->fmt.pix.field = field; pix_format_set_size(&f->fmt.pix, fmt, width, height); f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
nickolay v. shmyrevnickolay v. shmyrev10737.54%17.69%
hans verkuilhans verkuil5519.30%323.08%
mauro carvalho chehabmauro carvalho chehab3512.28%215.38%
douglas schilling landgrafdouglas schilling landgraf269.12%17.69%
michael h. schimekmichael h. schimek217.37%17.69%
hans de goedehans de goede196.67%17.69%
gerd knorrgerd knorr186.32%215.38%
pre-gitpre-git20.70%17.69%
brandon philipsbrandon philips20.70%17.69%
Total285100.00%13100.00%


static int bttv_try_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_format *f) { struct bttv_fh *fh = priv; verify_window_lock(fh, &f->fmt.win, /* adjust_size */ 1, /* adjust_crop */ 0); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
douglas schilling landgrafdouglas schilling landgraf2552.08%120.00%
nickolay v. shmyrevnickolay v. shmyrev1837.50%120.00%
hans verkuilhans verkuil48.33%240.00%
mauro carvalho chehabmauro carvalho chehab12.08%120.00%
Total48100.00%5100.00%


static int bttv_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { int retval; const struct bttv_format *fmt; struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; __s32 width, height; unsigned int width_mask, width_bias; enum v4l2_field field; retval = bttv_switch_type(fh, f->type); if (0 != retval) return retval; retval = bttv_try_fmt_vid_cap(file, priv, f); if (0 != retval) return retval; width = f->fmt.pix.width; height = f->fmt.pix.height; field = f->fmt.pix.field; fmt = format_by_fourcc(f->fmt.pix.pixelformat); bttv_get_width_mask_vid_cap(fmt, &width_mask, &width_bias); retval = limit_scaled_size_lock(fh, &width, &height, f->fmt.pix.field, width_mask, width_bias, /* adjust_size */ 1, /* adjust_crop */ 1); if (0 != retval) return retval; f->fmt.pix.field = field; /* update our state informations */ fh->fmt = fmt; fh->cap.field = f->fmt.pix.field; fh->cap.last = V4L2_FIELD_NONE; fh->width = f->fmt.pix.width; fh->height = f->fmt.pix.height; btv->init.fmt = fmt; btv->init.width = f->fmt.pix.width; btv->init.height = f->fmt.pix.height; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
nickolay v. shmyrevnickolay v. shmyrev9331.42%17.69%
mauro carvalho chehabmauro carvalho chehab8729.39%215.38%
hans de goedehans de goede3210.81%17.69%
michael h. schimekmichael h. schimek258.45%17.69%
douglas schilling landgrafdouglas schilling landgraf227.43%17.69%
trent piephotrent piepho186.08%17.69%
gerd knorrgerd knorr155.07%430.77%
pre-gitpre-git20.68%17.69%
hans verkuilhans verkuil20.68%17.69%
Total296100.00%13100.00%


static int bttv_s_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_format *f) { struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; if (no_overlay > 0) { pr_err("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); return -EINVAL; } return setup_window_lock(fh, btv, &f->fmt.win, 1); }

Contributors

PersonTokensPropCommitsCommitProp
nickolay v. shmyrevnickolay v. shmyrev3042.86%111.11%
douglas schilling landgrafdouglas schilling landgraf2130.00%111.11%
mauro carvalho chehabmauro carvalho chehab710.00%222.22%
gerd knorrgerd knorr57.14%111.11%
michael h. schimekmichael h. schimek45.71%111.11%
hans verkuilhans verkuil11.43%111.11%
pre-gitpre-git11.43%111.11%
joe perchesjoe perches11.43%111.11%
Total70100.00%9100.00%


static int bttv_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { struct video_device *vdev = video_devdata(file); struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; if (0 == v4l2) return -EINVAL; strlcpy(cap->driver, "bttv", sizeof(cap->driver)); strlcpy(cap->card, btv->video_dev.name, sizeof(cap->card)); snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", pci_name(btv->c.pci)); cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS; if (no_overlay <= 0) cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; if (video_is_registered(&btv->vbi_dev)) cap->capabilities |= V4L2_CAP_VBI_CAPTURE; if (video_is_registered(&btv->radio_dev)) cap->capabilities |= V4L2_CAP_RADIO; /* * No need to lock here: those vars are initialized during board * probe and remains untouched during the rest of the driver lifecycle */ if (btv->has_saa6588) cap->capabilities |= V4L2_CAP_RDS_CAPTURE; if (btv->tuner_type != TUNER_ABSENT) cap->capabilities |= V4L2_CAP_TUNER; if (vdev->vfl_type == VFL_TYPE_GRABBER) cap->device_caps = cap->capabilities & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_TUNER); else if (vdev->vfl_type == VFL_TYPE_VBI) cap->device_caps = cap->capabilities & (V4L2_CAP_VBI_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_TUNER); else { cap->device_caps = V4L2_CAP_RADIO | V4L2_CAP_TUNER; if (btv->has_saa6588) cap->device_caps |= V4L2_CAP_READWRITE | V4L2_CAP_RDS_CAPTURE; if (btv->has_tea575x) cap->device_caps |= V4L2_CAP_HW_FREQ_SEEK; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil13345.08%327.27%
michael h. schimekmichael h. schimek9431.86%19.09%
douglas schilling landgrafdouglas schilling landgraf289.49%19.09%
gerd knorrgerd knorr134.41%19.09%
ondrej zaryondrej zary124.07%19.09%
mauro carvalho chehabmauro carvalho chehab103.39%218.18%
pre-gitpre-git41.36%19.09%
trent piephotrent piepho10.34%19.09%
Total295100.00%11100.00%


static int bttv_enum_fmt_cap_ovr(struct v4l2_fmtdesc *f) { int index = -1, i; for (i = 0; i < FORMATS; i++) { if (formats[i].fourcc != -1) index++; if ((unsigned int)index == f->index) break; } if (FORMATS == i) return -EINVAL; f->pixelformat = formats[i].fourcc; strlcpy(f->description, formats[i].name, sizeof(f->description)); return i; }

Contributors

PersonTokensPropCommitsCommitProp
mauro carvalho chehabmauro carvalho chehab6762.62%120.00%
michael h. schimekmichael h. schimek2018.69%120.00%
douglas schilling landgrafdouglas schilling landgraf1715.89%120.00%
pre-gitpre-git21.87%120.00%
gerd knorrgerd knorr10.93%120.00%
Total107100.00%5100.00%


static int bttv_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { int rc = bttv_enum_fmt_cap_ovr(f); if (rc < 0) return rc; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
mauro carvalho chehabmauro carvalho chehab3382.50%125.00%
douglas schilling landgrafdouglas schilling landgraf512.50%125.00%
hans verkuilhans verkuil12.50%125.00%
michael h. schimekmichael h. schimek12.50%125.00%
Total40100.00%4100.00%


static int bttv_enum_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_fmtdesc *f) { int rc; if (no_overlay > 0) { pr_err("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); return -EINVAL; } rc = bttv_enum_fmt_cap_ovr(f); if (rc < 0) return rc; if (!(formats[rc].flags & FORMAT_FLAGS_PACKED)) return -EINVAL; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
douglas schilling landgrafdouglas schilling landgraf4355.84%120.00%
mauro carvalho chehabmauro carvalho chehab2836.36%120.00%
michael h. schimekmichael h. schimek45.19%120.00%
joe perchesjoe perches11.30%120.00%
hans verkuilhans verkuil11.30%120.00%
Total77100.00%5100.00%


static int bttv_g_fbuf(struct file *file, void *f, struct v4l2_framebuffer *fb) { struct bttv_fh *fh = f; struct bttv *btv = fh->btv; *fb = btv->fbuf; fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; fb->flags = V4L2_FBUF_FLAG_PRIMARY; if (fh->ovfmt) fb->fmt.pixelformat = fh->ovfmt->fourcc; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
michael h. schimekmichael h. schimek4356.58%120.00%
douglas schilling landgrafdouglas schilling landgraf2330.26%120.00%
hans verkuilhans verkuil67.89%120.00%
nickolay v. shmyrevnickolay v. shmyrev33.95%120.00%
mauro carvalho chehabmauro carvalho chehab11.32%120.00%
Total76100.00%5100.00%


static int bttv_overlay(struct file *file, void *f, unsigned int on) { struct bttv_fh *fh = f; struct bttv *btv = fh->btv; struct bttv_buffer *new; int retval = 0; if (on) { /* verify args */ if (unlikely(!btv->fbuf.base)) { return -EINVAL; } if (unlikely(!fh->ov.setup_ok)) { dprintk("%d: overlay: !setup_ok\n", btv->c.nr); retval = -EINVAL; } if (retval) return retval; } if (!check_alloc_btres_lock(btv, fh, RESOURCE_OVERLAY)) return -EBUSY; if (on) { fh->ov.tvnorm = btv->tvnorm; new = videobuf_sg_alloc(sizeof(*new)); new->crop = btv->crop[!!fh->do_crop].rect; bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); } else { new = NULL; } /* switch over */ retval = bttv_switch_overlay(btv, fh, new); return retval; }

Contributors

PersonTokensPropCommitsCommitProp
nickolay v. shmyrevnickolay v. shmyrev12862.44%111.11%
douglas schilling landgrafdouglas schilling landgraf3316.10%111.11%
mauro carvalho chehabmauro carvalho chehab2311.22%333.33%
robert fitzsimonsrobert fitzsimons178.29%111.11%
michael h. schimekmichael h. schimek20.98%111.11%
joe perchesjoe perches10.49%111.11%
guennadi liakhovetskiguennadi liakhovetski10.49%111.11%
Total205100.00%9100.00%


static int bttv_s_fbuf(struct file *file, void *f, const struct v4l2_framebuffer *fb) { struct bttv_fh *fh = f; struct bttv *btv = fh->btv; const struct bttv_format *fmt; int retval; if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO)) return -EPERM; /* check args */ fmt = format_by_fourcc(fb->fmt.pixelformat); if (NULL == fmt) return -EINVAL; if (0 == (fmt->flags & FORMAT_FLAGS_PACKED)) return -EINVAL; retval = -EINVAL; if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) { __s32 width = fb->fmt.width; __s32 height = fb->fmt.height; retval = limit_scaled_size_lock(fh, &width, &height, V4L2_FIELD_INTERLACED, /* width_mask */ ~3, /* width_bias */ 2, /* adjust_size */ 0, /* adjust_crop */ 0); if (0 != retval) return retval; } /* ok, accept it */ btv->fbuf.base = fb->base; btv->fbuf.fmt.width = fb->fmt.width; btv->fbuf.fmt.height = fb->fmt.height; if (0 != fb->fmt.bytesperline) btv->fbuf.fmt.bytesperline = fb->fmt.bytesperline; else btv->fbuf.fmt.bytesperline = btv->fbuf.fmt.width*fmt->depth/8; retval = 0; fh->ovfmt = fmt; btv->init.ovfmt = fmt; if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) { fh->ov.w.left = 0; fh->ov.w.top = 0; fh->ov.w.width = fb->fmt.width; fh->ov.w.height = fb->fmt.height; btv->init.ov.w.width = fb->fmt.width; btv->init.ov.w.height = fb->fmt.height; kfree(fh->ov.clips); fh->ov.clips = NULL; fh->ov.nclips = 0; if (check_btres(fh, RESOURCE_OVERLAY)) { struct bttv_buffer *new; new = videobuf_sg_alloc(sizeof(*new)); new->crop = btv->crop[!!fh->do_crop].rect; bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); retval = bttv_switch_overlay(btv, fh, new); } } return retval; }

Contributors

PersonTokensPropCommitsCommitProp
michael h. schimekmichael h. schimek43092.47%116.67%
douglas schilling landgrafdouglas schilling landgraf316.67%116.67%
mauro carvalho chehabmauro carvalho chehab20.43%233.33%
hans verkuilhans verkuil10.22%116.67%
guennadi liakhovetskiguennadi liakhovetski10.22%116.67%
Total465100.00%6100.00%


static int bttv_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *p) { struct bttv_fh *fh = priv; return videobuf_reqbufs(bttv_queue(fh), p); }

Contributors

PersonTokensPropCommitsCommitProp
douglas schilling landgrafdouglas schilling landgraf2771.05%133.33%
michael h. schimekmichael h. schimek1026.32%133.33%
mauro carvalho chehabmauro carvalho chehab12.63%133.33%
Total38100.00%3100.00%


static int bttv_querybuf(struct file *file, void *priv, struct v4l2_buffer *b) { struct bttv_fh *fh = priv; return videobuf_querybuf(bttv_queue(fh), b); }

Contributors

PersonTokensPropCommitsCommitProp
douglas schilling landgrafdouglas schilling landgraf2771.05%133.33%
michael h. schimekmichael h. schimek1026.32%133.33%
mauro carvalho chehabmauro carvalho chehab12.63%133.33%
Total38100.00%3100.00%


static int bttv_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) { struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; int res = bttv_resource(fh); if (!check_alloc_btres_lock(btv, fh, res)) return -EBUSY; return videobuf_qbuf(bttv_queue(fh), b); }

Contributors

PersonTokensPropCommitsCommitProp
michael h. schimekmichael h. schimek3549.30%125.00%
douglas schilling landgrafdouglas schilling landgraf3447.89%125.00%
mauro carvalho chehabmauro carvalho chehab22.82%250.00%
Total71100.00%4100.00%


static int bttv_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) { struct bttv_fh *fh = priv; return videobuf_dqbuf(bttv_queue(fh), b, file->f_flags & O_NONBLOCK); }

Contributors

PersonTokensPropCommitsCommitProp
douglas schilling landgrafdouglas schilling landgraf2761.36%133.33%
michael h. schimekmichael h. schimek1636.36%133.33%
mauro carvalho chehabmauro carvalho chehab12.27%133.33%
Total44100.00%3100.00%


static int bttv_streamon(struct file *file, void *priv, enum v4l2_buf_type type) { struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; int res = bttv_resource(fh); if (!check_alloc_btres_lock(btv, fh, res)) return -EBUSY; return videobuf_streamon(bttv_queue(fh)); }

Contributors

PersonTokensPropCommitsCommitProp
michael h. schimekmichael h. schimek3450.00%125.00%
douglas schilling landgrafdouglas schilling landgraf3247.06%125.00%
mauro carvalho chehabmauro carvalho chehab22.94%250.00%
Total68100.00%4100.00%


static int bttv_streamoff(struct file *file, void *priv, enum v4l2_buf_type type) { struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; int retval; int res = bttv_resource(fh); retval = videobuf_streamoff(bttv_queue(fh)); if (retval < 0) return retval; free_btres_lock(btv, fh, res); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
michael h. schimekmichael h. schimek4051.95%125.00%
douglas schilling landgrafdouglas schilling landgraf3545.45%125.00%
mauro carvalho chehabmauro carvalho chehab22.60%250.00%
Total77100.00%4100.00%


static int bttv_g_parm(struct file *file, void *f, struct v4l2_streamparm *parm) { struct bttv_fh *fh = f; struct bttv *btv = fh->btv; if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; parm->parm.capture.readbuffers = gbuffers; v4l2_video_std_frame_period(bttv_tvnorms[btv->tvnorm].v4l2_id, &parm->parm.capture.timeperframe); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
douglas schilling landgrafdouglas schilling landgraf2834.15%116.67%
nickolay v. shmyrevnickolay v. shmyrev2429.27%116.67%
hans verkuilhans verkuil2226.83%116.67%
michael h. schimekmichael h. schimek44.88%116.67%
trent piephotrent piepho33.66%116.67%
mauro carvalho chehabmauro carvalho chehab11.22%116.67%
Total82100.00%6100.00%


static int bttv_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) { struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; if (0 != t->index) return -EINVAL; t->rxsubchans = V4L2_TUNER_SUB_MONO; t->capability = V4L2_TUNER_CAP_NORM; bttv_call_all(btv, tuner, g_tuner, t); strcpy(t->name, "Television"); t->type = V4L2_TUNER_ANALOG_TV; if (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC) t->signal = 0xffff; if (btv->audio_mode_gpio) btv->audio_mode_gpio(btv, t, 0); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
nickolay v. shmyrevnickolay v. shmyrev7461.16%220.00%
douglas schilling landgrafdouglas schilling landgraf2823.14%110.00%
hans verkuilhans verkuil108.26%220.00%
gerd knorrgerd knorr43.31%220.00%
pre-gitpre-git21.65%110.00%
michael h. schimekmichael h. schimek21.65%110.00%
mauro carvalho chehabmauro carvalho chehab10.83%110.00%
Total121100.00%10100.00%


static int bttv_cropcap(struct file *file, void *priv, struct v4l2_cropcap *cap) { struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) return -EINVAL; *cap = bttv_tvnorms[btv->tvnorm].cropcap; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
michael h. schimekmichael h. schimek3652.17%125.00%
douglas schilling landgrafdouglas schilling landgraf3144.93%125.00%
mauro carvalho chehabmauro carvalho chehab11.45%125.00%
gerd knorrgerd knorr11.45%125.00%
Total69100.00%4100.00%


static int bttv_g_crop(struct file *file, void *f, struct v4l2_crop *crop) { struct bttv_fh *fh = f; struct bttv *btv = fh->btv; if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) return -EINVAL; /* No fh->do_crop = 1; because btv->crop[1] may be inconsistent with fh->width or fh->height and apps do not expect a change here. */ crop->c = btv->crop[!!fh->do_crop].rect; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
michael h. schimekmichael h. schimek4154.67%116.67%
douglas schilling landgrafdouglas schilling landgraf2938.67%116.67%
gerd knorrgerd knorr34.00%233.33%
pre-gitpre-git11.33%116.67%
mauro carvalho chehabmauro carvalho chehab11.33%116.67%
Total75100.00%6100.00%


static int bttv_s_crop(struct file *file, void *f, const struct v4l2_crop *crop) { struct bttv_fh *fh = f; struct bttv *btv = fh->btv; const struct v4l2_rect *b; int retval; struct bttv_crop c; __s32 b_left; __s32 b_top; __s32 b_right; __s32 b_bottom; if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) return -EINVAL; /* Make sure tvnorm, vbi_end and the current cropping parameters remain consistent until we're done. Note read() may change vbi_end in check_alloc_btres_lock(). */ retval = -EBUSY; if (locked_btres(fh->btv, VIDEO_RESOURCES)) { return retval; } b = &bttv_tvnorms[btv->tvnorm].cropcap.bounds; b_left = b->left; b_right = b_left + b->width; b_bottom = b->top + b->height; b_top = max(b->top, btv->vbi_end); if (b_top + 32 >= b_bottom) { return retval; } /* Min. scaled size 48 x 32. */ c.rect.left = clamp_t(s32, crop->c.left, b_left, b_right - 48); c.rect.left = min(c.rect.left, (__s32) MAX_HDELAY); c.rect.width = clamp_t(s32, crop->c.width, 48, b_right - c.rect.left); c.rect.top = clamp_t(s32, crop->c.top, b_top, b_bottom - 32); /* Top and height must be a multiple of two. */ c.rect.top = (c.rect.top + 1) & ~1; c.rect.height = clamp_t(s32, crop->c.height, 32, b_bottom - c.rect.top); c.rect.height = (c.rect.height + 1) & ~1; bttv_crop_calc_limits(&c); btv->crop[1] = c; fh->do_crop = 1; if (fh->width < c.min_scaled_width) { fh->width = c.min_scaled_width; btv->init.width = c.min_scaled_width; } else if (fh->width > c.max_scaled_width) { fh->width = c.max_scaled_width; btv->init.width = c.max_scaled_width; } if (fh->height < c.min_scaled_height) { fh->height = c.min_scaled_height; btv->init.height = c.min_scaled_height; } else if (fh->height > c.max_scaled_height) { fh->height = c.max_scaled_height; btv->init.height = c.max_scaled_height; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
michael h. schimekmichael h. schimek31466.53%15.56%
douglas schilling landgrafdouglas schilling landgraf6814.41%15.56%
gerd knorrgerd knorr5812.29%422.22%
pre-gitpre-git153.18%738.89%
hans verkuilhans verkuil132.75%15.56%
mauro carvalho chehabmauro carvalho chehab20.42%211.11%
nickolay v. shmyrevnickolay v. shmyrev10.21%15.56%
linus torvaldslinus torvalds10.21%15.56%
Total472100.00%18100.00%


static ssize_t bttv_read(struct file *file, char __user *data, size_t count, loff_t *ppos) { struct bttv_fh *fh = file->private_data; int retval = 0; if (fh->btv->errors) bttv_reinit_bt848(fh->btv); dprintk("%d: read count=%d type=%s\n", fh->btv->c.nr, (int)count, v4l2_type_names[fh->type]); switch (fh->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: if (!check_alloc_btres_lock(fh->btv, fh, RESOURCE_VIDEO_READ)) { /* VIDEO_READ in use by another fh, or VIDEO_STREAM by any fh. */ return -EBUSY; } retval = videobuf_read_one(&fh->cap, data, count, ppos, file->f_flags & O_NONBLOCK); free_btres_lock(fh->btv, fh, RESOURCE_VIDEO_READ); break; case V4L2_BUF_TYPE_VBI_CAPTURE: if (!check_alloc_btres_lock(fh->btv,fh,RESOURCE_VBI)) return -EBUSY; retval = videobuf_read_stream(&fh->vbi, data, count, ppos, 1, file->f_flags & O_NONBLOCK); break; default: BUG(); } return retval; }

Contributors

PersonTokensPropCommitsCommitProp
gerd knorrgerd knorr16483.67%640.00%
michael h. schimekmichael h. schimek178.67%16.67%
pre-gitpre-git84.08%426.67%
mauro carvalho chehabmauro carvalho chehab31.53%16.67%
andrew mortonandrew morton21.02%16.67%
al viroal viro10.51%16.67%
joe perchesjoe perches10.51%16.67%
Total196100.00%15100.00%


static unsigned int bttv_poll(struct file *file, poll_table *wait) { struct bttv_fh *fh = file->private_data; struct bttv_buffer *buf; enum v4l2_field field; unsigned int rc = 0; unsigned long req_events = poll_requested_events(wait); if (v4l2_event_pending(&fh->fh)) rc = POLLPRI; else if (req_events & POLLPRI) poll_wait(file, &fh->fh.wait, wait); if (!(req_events & (POLLIN | POLLRDNORM))) return rc; if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { if (!check_alloc_btres_lock(fh->btv,fh,RESOURCE_VBI)) return rc | POLLERR; return rc | videobuf_poll_stream(file, &fh->vbi, wait); } if (check_btres(fh,RESOURCE_VIDEO_STREAM)) { /* streaming capture */ if (list_empty(&fh->cap.stream)) return rc | POLLERR; buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream); } else { /* read() capture */ if (NULL == fh->cap.read_buf) { /* need to capture a new frame */ if (locked_btres(fh->btv,RESOURCE_VIDEO_STREAM)) return rc | POLLERR; fh->cap.read_buf = videobuf_sg_alloc(fh->cap.msize); if (NULL == fh->cap.read_buf) return rc | POLLERR; fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR; field = videobuf_next_field(&fh->cap); if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,field)) { kfree (fh->cap.read_buf); fh->cap.read_buf = NULL; return rc | POLLERR; } fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf); fh->cap.read_off = 0; } buf = (struct bttv_buffer*)fh->cap.read_buf; } poll_wait(file, &buf->vb.done, wait); if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) rc = rc | POLLIN|POLLRDNORM; return rc; }

Contributors

PersonTokensPropCommitsCommitProp
gerd knorrgerd knorr24559.76%842.11%
hans verkuilhans verkuil8721.22%15.26%
pre-gitpre-git358.54%210.53%
nickolay v. shmyrevnickolay v. shmyrev174.15%15.26%
mauro carvalho chehabmauro carvalho chehab133.17%315.79%
figo zhangfigo zhang92.20%15.26%
brandon philipsbrandon philips20.49%15.26%
guennadi liakhovetskiguennadi liakhovetski10.24%15.26%
michael h. schimekmichael h. schimek10.24%15.26%
Total410100.00%19100.00%


static int bttv_open(struct file *file) { struct video_device *vdev = video_devdata(file); struct bttv *btv = video_drvdata(file); struct bttv_fh *fh; enum v4l2_buf_type type = 0; dprintk("open dev=%s\n", video_device_node_name(vdev)); if (vdev->vfl_type == VFL_TYPE_GRABBER) { type = V4L2_BUF_TYPE_VIDEO_CAPTURE; } else if (vdev->vfl_type == VFL_TYPE_VBI) { type = V4L2_BUF_TYPE_VBI_CAPTURE; } else { WARN_ON(1); return -ENODEV; } dprintk("%d: open called (type=%s)\n", btv->c.nr, v4l2_type_names[type]); /* allocate per filehandle data */ fh = kmalloc(sizeof(*fh), GFP_KERNEL); if (unlikely(!fh)) return -ENOMEM; btv->users++; file->private_data = fh; *fh = btv->init; v4l2_fh_init(&fh->fh, vdev); fh->type = type; fh->ov.setup_ok = 0; videobuf_queue_sg_init(&fh->cap, &bttv_video_qops, &btv->c.pci->dev, &btv->s_lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_INTERLACED, sizeof(struct bttv_buffer), fh, &btv->lock); videobuf_queue_sg_init(&fh->vbi, &bttv_vbi_qops, &btv->c.pci->dev, &btv->s_lock, V4L2_BUF_TYPE_VBI_CAPTURE, V4L2_FIELD_SEQ_TB, sizeof(struct bttv_buffer), fh, &btv->lock); set_tvnorm(btv,btv->tvnorm); set_input(btv, btv->input, btv->tvnorm); audio_mute(btv, btv->mute); /* The V4L2 spec requires one global set of cropping parameters which only change on request. These are stored in btv->crop[1]. However for compatibility with V4L apps and cropping unaware V4L2 apps we now reset the cropping parameters as seen through this fh, which is to say VIDIOC_G_CROP and scaling limit checks will use btv->crop[0], the default cropping parameters for the current video standard, and VIDIOC_S_FMT will not implicitely change the cropping parameters until VIDIOC_S_CROP has been called. */ fh->do_crop = !reset_crop; /* module parameter */ /* Likewise there should be one global set of VBI capture parameters, but for compatibility with V4L apps and earlier driver versions each fh has its own parameters. */ bttv_vbi_fmt_reset(&fh->vbi_fmt, btv->tvnorm); bttv_field_count(btv); v4l2_fh_add(&fh->fh); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
gerd knorrgerd knorr15948.18%725.00%
pre-gitpre-git4212.73%517.86%
hans verkuilhans verkuil278.18%414.29%
mauro carvalho chehabmauro carvalho chehab257.58%310.71%
laurent pinchartlaurent pinchart206.06%27.14%
michael h. schimekmichael h. schimek144.24%13.57%
trent piephotrent piepho113.33%13.57%
frank schaeferfrank schaefer92.73%13.57%
andrew mortonandrew morton82.42%13.57%
guennadi liakhovetskiguennadi liakhovetski82.42%13.57%
nickolay v. shmyrevnickolay v. shmyrev51.52%13.57%
joe perchesjoe perches20.61%13.57%
Total330100.00%28100.00%


static int bttv_release(struct file *file) { struct bttv_fh *fh = file->private_data; struct bttv *btv = fh->btv; /* turn off overlay */ if (check_btres(fh, RESOURCE_OVERLAY)) bttv_switch_overlay(btv,fh,NULL); /* stop video capture */ if (check_btres(fh, RESOURCE_VIDEO_STREAM)) { videobuf_streamoff(&fh->cap); free_btres_lock(btv,fh,RESOURCE_VIDEO_STREAM); } if (fh->cap.read_buf) { buffer_release(&fh->cap,fh->cap.read_buf); kfree(fh->cap.read_buf); } if (check_btres(fh, RESOURCE_VIDEO_READ)) { free_btres_lock(btv, fh, RESOURCE_VIDEO_READ); } /* stop vbi capture */ if (check_btres(fh, RESOURCE_VBI)) { videobuf_stop(&fh->vbi); free_btres_lock(btv,fh,RESOURCE_VBI); } /* free stuff */ videobuf_mmap_free(&fh->cap); videobuf_mmap_free(&fh->vbi); file->private_data = NULL; btv->users--; bttv_field_count(btv); if (!btv->users) audio_mute(btv, btv->mute); v4l2_fh_del(&fh->fh); v4l2_fh_exit(&fh->fh); kfree(fh); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
gerd knorrgerd knorr14261.21%836.36%
pre-gitpre-git2812.07%836.36%
hans verkuilhans verkuil2410.34%29.09%
michael h. schimekmichael h. schimek219.05%14.55%
mauro carvalho chehabmauro carvalho chehab166.90%29.09%
brandon philipsbrandon philips10.43%14.55%
Total232100.00%22100.00%


static int bttv_mmap(struct file *file, struct vm_area_struct *vma) { struct bttv_fh *fh = file->private_data; dprintk("%d: mmap type=%s 0x%lx+%ld\n", fh->btv->c.nr, v4l2_type_names[fh->type], vma->vm_start, vma->vm_end - vma->vm_start); return videobuf_mmap_mapper(bttv_queue(fh),vma); }

Contributors

PersonTokensPropCommitsCommitProp
gerd knorrgerd knorr6392.65%457.14%
andrew mortonandrew morton22.94%114.29%
pre-gitpre-git22.94%114.29%
joe perchesjoe perches11.47%114.29%
Total68100.00%7100.00%

static const struct v4l2_file_operations bttv_fops = { .owner = THIS_MODULE, .open = bttv_open, .release = bttv_release, .unlocked_ioctl = video_ioctl2, .read = bttv_read, .mmap = bttv_mmap, .poll = bttv_poll, }; static const struct v4l2_ioctl_ops bttv_ioctl_ops = { .vidioc_querycap = bttv_querycap, .vidioc_enum_fmt_vid_cap = bttv_enum_fmt_vid_cap, .vidioc_g_fmt_vid_cap = bttv_g_fmt_vid_cap, .vidioc_try_fmt_vid_cap = bttv_try_fmt_vid_cap, .vidioc_s_fmt_vid_cap = bttv_s_fmt_vid_cap, .vidioc_enum_fmt_vid_overlay = bttv_enum_fmt_vid_overlay, .vidioc_g_fmt_vid_overlay = bttv_g_fmt_vid_overlay, .vidioc_try_fmt_vid_overlay = bttv_try_fmt_vid_overlay, .vidioc_s_fmt_vid_overlay = bttv_s_fmt_vid_overlay, .vidioc_g_fmt_vbi_cap = bttv_g_fmt_vbi_cap, .vidioc_try_fmt_vbi_cap = bttv_try_fmt_vbi_cap, .vidioc_s_fmt_vbi_cap = bttv_s_fmt_vbi_cap, .vidioc_cropcap = bttv_cropcap, .vidioc_reqbufs = bttv_reqbufs, .vidioc_querybuf = bttv_querybuf, .vidioc_qbuf = bttv_qbuf, .vidioc_dqbuf = bttv_dqbuf, .vidioc_s_std = bttv_s_std, .vidioc_g_std = bttv_g_std, .vidioc_enum_input = bttv_enum_input, .vidioc_g_input = bttv_g_input, .vidioc_s_input = bttv_s_input, .vidioc_streamon = bttv_streamon, .vidioc_streamoff = bttv_streamoff, .vidioc_g_tuner = bttv_g_tuner, .vidioc_s_tuner = bttv_s_tuner, .vidioc_g_crop = bttv_g_crop, .vidioc_s_crop = bttv_s_crop, .vidioc_g_fbuf = bttv_g_fbuf, .vidioc_s_fbuf = bttv_s_fbuf, .vidioc_overlay = bttv_overlay, .vidioc_g_parm = bttv_g_parm, .vidioc_g_frequency = bttv_g_frequency, .vidioc_s_frequency = bttv_s_frequency, .vidioc_log_status = bttv_log_status, .vidioc_querystd = bttv_querystd, .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, .vidioc_unsubscribe_event = v4l2_event_unsubscribe, #ifdef CONFIG_VIDEO_ADV_DEBUG .vidioc_g_register = bttv_g_register, .vidioc_s_register = bttv_s_register, #endif }; static struct video_device bttv_video_template = { .fops = &bttv_fops, .ioctl_ops = &bttv_ioctl_ops, .tvnorms = BTTV_NORMS, }; /* ----------------------------------------------------------------------- */ /* radio interface */
static int radio_open(struct file *file) { struct video_device *vdev = video_devdata(file); struct bttv *btv = video_drvdata(file); struct bttv_fh *fh; dprintk("open dev=%s\n", video_device_node_name(vdev)); dprintk("%d: open called (radio)\n", btv->c.nr); /* allocate per filehandle data */ fh = kmalloc(sizeof(*fh), GFP_KERNEL); if (unlikely(!fh)) return -ENOMEM; file->private_data = fh; *fh = btv->init; v4l2_fh_init(&fh->fh, vdev); btv->radio_user++; audio_mute(btv, btv->mute); v4l2_fh_add(&fh->fh); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
robert fitzsimonsrobert fitzsimons4030.53%112.50%
douglas schilling landgrafdouglas schilling landgraf4030.53%112.50%
laurent pinchartlaurent pinchart1410.69%112.50%
hans verkuilhans verkuil129.16%112.50%
mauro carvalho chehabmauro carvalho chehab107.63%112.50%
frank schaeferfrank schaefer96.87%112.50%
trent piephotrent piepho43.05%112.50%
joe perchesjoe perches21.53%112.50%
Total131100.00%8100.00%


static int radio_release(struct file *file) { struct bttv_fh *fh = file->private_data; struct bttv *btv = fh->btv; struct saa6588_command cmd; file->private_data = NULL; v4l2_fh_del(&fh->fh); v4l2_fh_exit(&fh->fh); kfree(fh); btv->radio_user--; bttv_call_all(btv, core, ioctl, SAA6588_CMD_CLOSE, &cmd); if (btv->radio_user == 0) btv->has_radio_tuner = 0; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
douglas schilling landgrafdouglas schilling landgraf3738.54%112.50%
hans verkuilhans verkuil3536.46%450.00%
robert fitzsimonsrobert fitzsimons1818.75%225.00%
udo steinbergudo steinberg66.25%112.50%
Total96100.00%8100.00%


static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) { struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; if (0 != t->index) return -EINVAL; strcpy(t->name, "Radio"); t->type = V4L2_TUNER_RADIO; radio_enable(btv); bttv_call_all(btv, tuner, g_tuner, t); if (btv->audio_mode_gpio) btv->audio_mode_gpio(btv, t, 0); if (btv->has_tea575x) return snd_tea575x_g_tuner(&btv->tea, t); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
douglas schilling landgrafdouglas schilling landgraf6757.76%17.69%
pre-gitpre-git1815.52%861.54%
ondrej zaryondrej zary1714.66%17.69%
hans verkuilhans verkuil97.76%215.38%
gerd knorrgerd knorr54.31%17.69%
Total116100.00%13100.00%


static int radio_s_tuner(struct file *file, void *priv, const struct v4l2_tuner *t) { struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; if (0 != t->index) return -EINVAL; radio_enable(btv); bttv_call_all(btv, tuner, s_tuner, t); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
douglas schilling landgrafdouglas schilling landgraf4566.18%112.50%
hans verkuilhans verkuil1217.65%450.00%
pre-gitpre-git68.82%225.00%
nickolay v. shmyrevnickolay v. shmyrev57.35%112.50%
Total68100.00%8100.00%


static int radio_s_hw_freq_seek(struct file *file, void *priv, const struct v4l2_hw_freq_seek *a) { struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; if (btv->has_tea575x) return snd_tea575x_s_hw_freq_seek(file, &btv->tea, a); return -ENOTTY; }

Contributors

PersonTokensPropCommitsCommitProp
ondrej zaryondrej zary60100.00%1100.00%
Total60100.00%1100.00%


static int radio_enum_freq_bands(struct file *file, void *priv, struct v4l2_frequency_band *band) { struct bttv_fh *fh = priv; struct bttv *btv = fh->btv; if (btv->has_tea575x) return snd_tea575x_enum_freq_bands(&btv->tea, band); return -ENOTTY; }

Contributors

PersonTokensPropCommitsCommitProp
ondrej zaryondrej zary57100.00%1100.00%
Total57100.00%1100.00%


static ssize_t radio_read(struct file *file, char __user *data, size_t count, loff_t *ppos) { struct bttv_fh *fh = file->private_data; struct bttv *btv = fh->btv; struct saa6588_command cmd; cmd.block_count = count / 3; cmd.nonblocking = file->f_flags & O_NONBLOCK; cmd.buffer = data; cmd.instance = file; cmd.result = -ENODEV; radio_enable(btv); bttv_call_all(btv, core, ioctl, SAA6588_CMD_READ, &cmd); return cmd.result; }

Contributors

PersonTokensPropCommitsCommitProp
mauro carvalho chehabmauro carvalho chehab7368.87%116.67%
hans verkuilhans verkuil2220.75%466.67%
robert fitzsimonsrobert fitzsimons1110.38%116.67%
Total106100.00%6100.00%


static unsigned int radio_poll(struct file *file, poll_table *wait) { struct bttv_fh *fh = file->private_data; struct bttv *btv = fh->btv; unsigned long req_events = poll_requested_events(wait); struct saa6588_command cmd; unsigned int res = 0; if (v4l2_event_pending(&fh->fh)) res = POLLPRI; else if (req_events & POLLPRI) poll_wait(file, &fh->fh.wait, wait); radio_enable(btv); cmd.instance = file; cmd.event_list = wait; cmd.result = res; bttv_call_all(btv, core, ioctl, SAA6588_CMD_POLL, &cmd); return cmd.result; }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil6348.46%466.67%
mauro carvalho chehabmauro carvalho chehab5643.08%116.67%
robert fitzsimonsrobert fitzsimons118.46%116.67%
Total130100.00%6100.00%

static const struct v4l2_file_operations radio_fops = { .owner = THIS_MODULE, .open = radio_open, .read = radio_read, .release = radio_release, .unlocked_ioctl = video_ioctl2, .poll = radio_poll, }; static const struct v4l2_ioctl_ops radio_ioctl_ops = { .vidioc_querycap = bttv_querycap, .vidioc_log_status = bttv_log_status, .vidioc_g_tuner = radio_g_tuner, .vidioc_s_tuner = radio_s_tuner, .vidioc_g_frequency = bttv_g_frequency, .vidioc_s_frequency = bttv_s_frequency, .vidioc_s_hw_freq_seek = radio_s_hw_freq_seek, .vidioc_enum_freq_bands = radio_enum_freq_bands, .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; static struct video_device radio_template = { .fops = &radio_fops, .ioctl_ops = &radio_ioctl_ops, }; /* ----------------------------------------------------------------------- */ /* some debug code */
static int bttv_risc_decode(u32 risc) { static char *instr[16] = { [ BT848_RISC_WRITE >> 28 ] = "write", [ BT848_RISC_SKIP >> 28 ] = "skip", [ BT848_RISC_WRITEC >> 28 ] = "writec", [ BT848_RISC_JUMP >> 28 ] = "jump", [ BT848_RISC_SYNC >> 28 ] = "sync", [ BT848_RISC_WRITE123 >> 28 ] = "write123", [ BT848_RISC_SKIP123 >> 28 ] = "skip123", [ BT848_RISC_WRITE1S23 >> 28 ] = "write1s23", }; static int incr[16] = { [ BT848_RISC_WRITE >> 28 ] = 2, [ BT848_RISC_JUMP >> 28 ] = 2, [ BT848_RISC_SYNC >> 28 ] = 2, [ BT848_RISC_WRITE123 >> 28 ] = 5, [ BT848_RISC_SKIP123 >> 28 ] = 2, [ BT848_RISC_WRITE1S23 >> 28 ] = 3, }; static char *bits[] = { "be0", "be1", "be2", "be3/resync", "set0", "set1", "set2", "set3", "clr0", "clr1", "clr2", "clr3", "irq", "res", "eol", "sol", }; int i; pr_cont("0x%08x [ %s", risc, instr[risc >> 28] ? instr[risc >> 28] : "INVALID"); for (i = ARRAY_SIZE(bits)-1; i >= 0; i--) if (risc & (1 << (i + 12))) pr_cont(" %s", bits[i]); pr_cont(" count=%d ]\n", risc & 0xfff); return incr[risc >> 28] ? incr[risc >> 28] : 1; }

Contributors

PersonTokensPropCommitsCommitProp
gerd knorrgerd knorr26697.08%228.57%
pre-gitpre-git31.09%228.57%
joe perchesjoe perches31.09%114.29%
adrian bunkadrian bunk10.36%114.29%
andrew mortonandrew morton10.36%114.29%
Total274100.00%7100.00%


static void bttv_risc_disasm(struct bttv *btv, struct btcx_riscmem *risc) { unsigned int i,j,n; pr_info("%s: risc disasm: %p [dma=0x%08lx]\n", btv->c.v4l2_dev.name, risc->cpu, (unsigned long)risc->dma); for (i = 0; i < (risc->size >> 2); i += n) { pr_info("%s: 0x%lx: ", btv->c.v4l2_dev.name, (unsigned long)(risc->dma + (i<<2))); n = bttv_risc_decode(le32_to_cpu(risc->cpu[i])); for (j = 1; j < n; j++) pr_info("%s: 0x%lx: 0x%08x [ arg #%d ]\n", btv->c.v4l2_dev.name, (unsigned long)(risc->dma + ((i+j)<<2)), risc->cpu[i+j], j); if (0 == risc->cpu[i]) break; } }

Contributors

PersonTokensPropCommitsCommitProp
gerd knorrgerd knorr15986.41%327.27%
pre-gitpre-git126.52%436.36%
hans verkuilhans verkuil63.26%19.09%
al viroal viro31.63%19.09%
joe perchesjoe perches31.63%19.09%
adrian bunkadrian bunk10.54%19.09%
Total184100.00%11100.00%


static void bttv_print_riscaddr(struct bttv *btv) { pr_info(" main: %08llx\n", (unsigned long long)btv->main.dma); pr_info(" vbi : o=%08llx e=%08llx\n", btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0, btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0); pr_info(" cap : o=%08llx e=%08llx\n", btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0, btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0); pr_info(" scr : o=%08llx e=%08llx\n", btv->screen ? (unsigned long long)btv->screen->top.dma : 0, btv->screen ? (unsigned long long)btv->screen->bottom.dma : 0); bttv_risc_disasm(btv, &btv->main); }

Contributors

PersonTokensPropCommitsCommitProp
gerd knorrgerd knorr11867.82%538.46%
pre-gitpre-git3318.97%646.15%
david s. millerdavid s. miller158.62%17.69%
joe perchesjoe perches84.60%17.69%
Total174100.00%13100.00%

/* ----------------------------------------------------------------------- */ /* irq handler */ static char *irq_name[] = { "FMTCHG", // format change detected (525 vs. 625) "VSYNC", // vertical sync (new field) "HSYNC", // horizontal sync "OFLOW", // chroma/luma AGC overflow "HLOCK", // horizontal lock changed "VPRES", // video presence changed "6", "7", "I2CDONE", // hw irc operation finished "GPINT", // gpio port triggered irq "10", "RISCI", // risc instruction triggered irq "FBUS", // pixel data fifo dropped data (high pci bus latencies) "FTRGT", // pixel data fifo overrun "FDSR", // fifo data stream resyncronisation "PPERR", // parity error (data transfer) "RIPERR", // parity error (read risc instructions) "PABORT", // pci abort "OCERR", // risc instruction error "SCERR", // syncronisation error };
static void bttv_print_irqbits(u32 print, u32 mark) { unsigned int i; pr_cont("bits:"); for (i = 0; i < ARRAY_SIZE(irq_name); i++) { if (print & (1 << i)) pr_cont(" %s", irq_name[i]); if (mark & (1 << i)) pr_cont("*"); } }

Contributors

PersonTokensPropCommitsCommitProp
gerd knorrgerd knorr7195.95%266.67%
joe perchesjoe perches34.05%133.33%
Total74100.00%3100.00%


static void bttv_irq_debug_low_latency(struct bttv *btv, u32 rc) { pr_warn("%d: irq: skipped frame [main=%lx,o_vbi=%lx,o_field=%lx,rc=%lx]\n", btv->c.nr, (unsigned long)btv->main.dma, (unsigned long)le32_to_cpu(btv->main.cpu[RISC_SLOT_O_VBI+1]), (unsigned long)le32_to_cpu(btv->main.cpu[RISC_SLOT_O_FIELD+1]), (unsigned long)rc); if (0 == (btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC)) { pr_notice("%d: Oh, there (temporarily?) is no input signal. " "Ok, then this is harmless, don't worry ;)\n", btv->c.nr); return; } pr_notice("%d: Uhm. Looks like we have unusual high IRQ latencies\n", btv->c.nr); pr_notice("%d: Lets try to catch the culpit red-handed ...\n", btv->c.nr); dump_stack(); }

Contributors

PersonTokensPropCommitsCommitProp
andrew mortonandrew morton11588.46%125.00%
joe perchesjoe perches86.15%125.00%
al viroal viro64.62%125.00%
gerd knorrgerd knorr10.77%125.00%
Total130100.00%4100.00%


static int bttv_irq_next_video(struct bttv *btv, struct bttv_buffer_set *set) { struct bttv_buffer *item; memset(set,0,sizeof(*set)); /* capture request ? */ if (!list_empty(&btv->capture)) { set->frame_irq = 1; item = list_entry(btv->capture.next, struct bttv_buffer, vb.queue); if (V4L2_FIELD_HAS_TOP(item->vb.field)) set->top = item; if (V4L2_FIELD_HAS_BOTTOM(item->vb.field)) set->bottom = item; /* capture request for other field ? */ if (!V4L2_FIELD_HAS_BOTH(item->vb.field) && (item->vb.queue.next != &btv->capture)) { item = list_entry(item->vb.queue.next, struct bttv_buffer, vb.queue); /* Mike Isely <isely@pobox.com> - Only check * and set up the bottom field in the logic * below. Don't ever do the top field. This * of course means that if we set up the * bottom field in the above code that we'll * actually skip a field. But that's OK. * Having processed only a single buffer this * time, then the next time around the first * available buffer should be for a top field. * That will then cause us here to set up a * top then a bottom field in the normal way. * The alternative to this understanding is * that we set up the second available buffer * as a top field, but that's out of order * since this driver always processes the top * field first - the effect will be the two * buffers being returned in the wrong order, * with the second buffer also being delayed * by one field time (owing to the fifo nature * of videobuf). Worse still, we'll be stuck * doing fields out of order now every time * until something else causes a field to be * dropped. By effectively forcing a field to * drop this way then we always get back into * sync within a single frame time. (Out of * order fields can screw up deinterlacing * algorithms.) */ if (!V4L2_FIELD_HAS_BOTH(item->vb.field)) { if (NULL == set->bottom && V4L2_FIELD_BOTTOM == item->vb.field) { set->bottom = item; } if (NULL != set->top && NULL != set->bottom) set->top_irq = 2; } } } /* screen overlay ? */ if (NULL != btv->screen) { if (V4L2_FIELD_HAS_BOTH(btv->screen->vb.field)) { if (NULL == set->top && NULL == set->bottom) { set->top = btv->screen; set->bottom = btv->screen; } } else { if (V4L2_FIELD_TOP == btv->screen->vb.field && NULL == set->top) { set->top = btv->screen; } if (V4L2_FIELD_BOTTOM == btv->screen->vb.field && NULL == set->bottom) { set->bottom = btv->screen; } } } dprintk("%d: next set: top=%p bottom=%p [screen=%p,irq=%d,%d]\n", btv->c.nr, set->top, set->bottom, btv->screen, set->frame_irq, set->top_irq); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
gerd knorrgerd knorr29079.23%531.25%
pre-gitpre-git7119.40%743.75%
andrew mortonandrew morton20.55%16.25%
linus torvaldslinus torvalds10.27%16.25%
mike iselymike isely10.27%16.25%
joe perchesjoe perches10.27%16.25%
Total366100.00%16100.00%


static void bttv_irq_wakeup_video(struct bttv *btv, struct bttv_buffer_set *wakeup, struct bttv_buffer_set *curr, unsigned int state) { struct timeval ts; v4l2_get_timestamp(&ts); if (wakeup->top == wakeup->bottom) { if (NULL != wakeup->top && curr->top != wakeup->top) { if (irq_debug > 1) pr_debug("%d: wakeup: both=%p\n", btv->c.nr, wakeup->top); wakeup->top->vb.ts = ts; wakeup->top->vb.field_count = btv->field_count; wakeup->top->vb.state = state; wake_up(&wakeup->top->vb.done); } } else { if (NULL != wakeup->top && curr->top != wakeup->top) { if (irq_debug > 1) pr_debug("%d: wakeup: top=%p\n", btv->c.nr, wakeup->top); wakeup->top->vb.ts = ts; wakeup->top->vb.field_count = btv->field_count; wakeup->top->vb.state = state; wake_up(&wakeup->top->vb.done); } if (NULL != wakeup->bottom && curr->bottom != wakeup->bottom) { if (irq_debug > 1) pr_debug("%d: wakeup: bottom=%p\n", btv->c.nr, wakeup->bottom); wakeup->bottom->vb.ts = ts; wakeup->bottom->vb.field_count = btv->field_count; wakeup->bottom->vb.state = state; wake_up(&wakeup->bottom->vb.done); } } }

Contributors

PersonTokensPropCommitsCommitProp
gerd knorrgerd knorr25183.95%637.50%
pre-gitpre-git3210.70%637.50%
andrew mortonandrew morton62.01%16.25%
joe perchesjoe perches62.01%16.25%
linus torvaldslinus torvalds31.00%16.25%
sakari ailussakari ailus10.33%16.25%
Total299100.00%16100.00%


static void bttv_irq_wakeup_vbi(struct bttv *btv, struct bttv_buffer *wakeup, unsigned int state) { if (NULL == wakeup) return; v4l2_get_timestamp(&wakeup->vb.ts); wakeup->vb.field_count = btv->field_count; wakeup->vb.state = state; wake_up(&wakeup->vb.done); }

Contributors

PersonTokensPropCommitsCommitProp
gerd knorrgerd knorr6396.92%133.33%
sakari ailussakari ailus11.54%133.33%
arnd bergmannarnd bergmann11.54%133.33%
Total65100.00%3100.00%


static void bttv_irq_timeout(unsigned long data) { struct bttv *btv = (struct bttv *)data; struct bttv_buffer_set old,new; struct bttv_buffer *ovbi; struct bttv_buffer *item; unsigned long flags; if (bttv_verbose) { pr_info("%d: timeout: drop=%d irq=%d/%d, risc=%08x, ", btv->c.nr, btv->framedrop, btv->irq_me, btv->irq_total, btread(BT848_RISC_COUNT)); bttv_print_irqbits(btread(BT848_INT_STAT),0); pr_cont("\n"); } spin_lock_irqsave(&btv->s_lock,flags); /* deactivate stuff */ memset(&new,0,sizeof(new)); old = btv->curr; ovbi = btv->cvbi; btv->curr = new; btv->cvbi = NULL; btv->loop_irq = 0; bttv_buffer_activate_video(btv, &new); bttv_buffer_activate_vbi(btv, NULL); bttv_set_dma(btv, 0); /* wake up */ bttv_irq_wakeup_video(btv, &old, &new, VIDEOBUF_ERROR); bttv_irq_wakeup_vbi(btv, ovbi, VIDEOBUF_ERROR); /* cancel all outstanding capture / vbi requests */ while (!list_empty(&btv->capture)) { item = list_entry(btv->capture.next, struct bttv_buffer, vb.queue); list_del(&item->vb.queue); item->vb.state = VIDEOBUF_ERROR; wake_up(&item->vb.done); } while (!list_empty(&btv->vcapture)) { item = list_entry(btv->vcapture.next, struct bttv_buffer, vb.queue); list_del(&item->vb.queue); item->vb.state = VIDEOBUF_ERROR; wake_up(&item->vb.done); } btv->errors++; spin_unlock_irqrestore(&btv->s_lock,flags); }

Contributors

PersonTokensPropCommitsCommitProp
gerd knorrgerd knorr27785.49%533.33%
andrew mortonandrew morton247.41%213.33%
pre-gitpre-git164.94%640.00%
brandon philipsbrandon philips41.23%16.67%
joe perchesjoe perches30.93%16.67%
Total324100.00%15100.00%


static void bttv_irq_wakeup_top(struct bttv *btv) { struct bttv_buffer *wakeup = btv->curr.top; if (NULL == wakeup) return; spin_lock(&btv->s_lock); btv->curr.top_irq = 0; btv->curr.top = NULL; bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0); v4l2_get_timestamp(&wakeup->vb.ts); wakeup->vb.field_count = btv->field_count; wakeup->vb.state = VIDEOBUF_DONE; wake_up(&wakeup->vb.done); spin_unlock(&btv->s_lock); }

Contributors

PersonTokensPropCommitsCommitProp
gerd knorrgerd knorr8274.55%325.00%
pre-gitpre-git1917.27%650.00%
linus torvaldslinus torvalds76.36%18.33%
sakari ailussakari ailus10.91%18.33%
brandon philipsbrandon philips10.91%18.33%
Total110100.00%12100.00%


static inline int is_active(struct btcx_riscmem *risc, u32 rc) { if (rc < risc->dma) return 0; if (rc > risc->dma + risc->size) return 0; return 1; }

Contributors

PersonTokensPropCommitsCommitProp
gerd knorrgerd knorr44100.00%3100.00%
Total44100.00%3100.00%


static void bttv_irq_switch_video(struct bttv *btv) { struct bttv_buffer_set new; struct bttv_buffer_set old; dma_addr_t rc; spin_lock(&btv->s_lock); /* new buffer set */ bttv_irq_next_video(btv, &new); rc = btread(BT848_RISC_COUNT); if ((btv->curr.top && is_active(&btv->curr.top->top, rc)) || (btv->curr.bottom && is_active(&btv->curr.bottom->bottom, rc))) { btv->framedrop++; if (debug_latency) bttv_irq_debug_low_latency(btv, rc); spin_unlock(&btv->s_lock); return; } /* switch over */ old = btv->curr; btv->curr = new; btv->loop_irq &= ~1; bttv_buffer_activate_video(btv, &new); bttv_set_dma(btv, 0); /* switch input */ if (UNSET != btv->new_input) { video_mux(btv,btv->new_input); btv->new_input = UNSET; } /* wake up finished buffers */ bttv_irq_wakeup_video(btv, &old, &new, VIDEOBUF_DONE); spin_unlock(&btv->s_lock); }

Contributors

PersonTokensPropCommitsCommitProp
gerd knorrgerd knorr17084.16%533.33%
pre-gitpre-git199.41%640.00%
andrew mortonandrew morton104.95%213.33%
linus torvaldslinus torvalds20.99%16.67%
brandon philipsbrandon philips10.50%16.67%
Total202100.00%15100.00%


static void bttv_irq_switch_vbi(struct bttv *btv) { struct bttv_buffer *new = NULL; struct bttv_buffer *old; u32 rc; spin_lock(&btv->s_lock); if (!list_empty(&btv->vcapture)) new = list_entry(btv->vcapture.next, struct bttv_buffer, vb.queue); old = btv->cvbi; rc = btread(BT848_RISC_COUNT); if (NULL != old && (is_active(&old->top, rc) || is_active(&old->bottom, rc))) { btv->framedrop++; if (debug_latency) bttv_irq_debug_low_latency(btv, rc); spin_unlock(&btv->s_lock); return; } /* switch */ btv->cvbi = new; btv->loop_irq &= ~4; bttv_buffer_activate_vbi(btv, new); bttv_set_dma(btv, 0); bttv_irq_wakeup_vbi(btv, old, VIDEOBUF_DONE); spin_unlock(&btv->s_lock); }

Contributors

PersonTokensPropCommitsCommitProp
gerd knorrgerd knorr17599.43%266.67%
brandon philipsbrandon philips10.57%133.33%
Total176100.00%3100.00%


static irqreturn_t bttv_irq(int irq, void *dev_id) { u32 stat,astat; u32 dstat; int count; struct bttv *btv; int handled = 0; btv=(struct bttv *)dev_id; count=0; while (1) { /* get/clear interrupt status bits */ stat=btread(BT848_INT_STAT); astat=stat&btread(BT848_INT_MASK); if (!astat) break; handled = 1; btwrite(stat,BT848_INT_STAT); /* get device status bits */ dstat=btread(BT848_DSTATUS); if (irq_debug) { pr_debug("%d: irq loop=%d fc=%d riscs=%x, riscc=%08x, ", btv->c.nr, count, btv->field_count, stat>>28, btread(BT848_RISC_COUNT)); bttv_print_irqbits(stat,astat); if (stat & BT848_INT_HLOCK) pr_cont(" HLOC => %s", dstat & BT848_DSTATUS_HLOC ? "yes" : "no"); if (stat & BT848_INT_VPRES) pr_cont(" PRES => %s", dstat & BT848_DSTATUS_PRES ? "yes" : "no"); if (stat & BT848_INT_FMTCHG) pr_cont(" NUML => %s", dstat & BT848_DSTATUS_NUML ? "625" : "525"); pr_cont("\n"); } if (astat&BT848_INT_VSYNC) btv->field_count++; if ((astat & BT848_INT_GPINT) && btv->remote) { bttv_input_irq(btv); } if (astat & BT848_INT_I2CDONE) { btv->i2c_done = stat; wake_up(&btv->i2c_queue); } if ((astat & BT848_INT_RISCI) && (stat & (4<<28))) bttv_irq_switch_vbi(btv); if ((astat & BT848_INT_RISCI) && (stat & (2<<28))) bttv_irq_wakeup_top(btv); if ((astat & BT848_INT_RISCI) && (stat & (1<<28))) bttv_irq_switch_video(btv); if ((astat & BT848_INT_HLOCK) && btv->opt_automute) /* trigger automute */ audio_mux_gpio(btv, btv->audio_input, btv->mute); if (astat & (BT848_INT_SCERR|BT848_INT_OCERR)) { pr_info("%d: %s%s @ %08x,", btv->c.nr, (astat & BT848_INT_SCERR) ? "SCERR" : "", (astat & BT848_INT_OCERR) ? "OCERR" : "", btread(BT848_RISC_COUNT)); bttv_print_irqbits(stat,astat); pr_cont("\n"); if (bttv_debug) bttv_print_riscaddr(btv); } if (fdsr && astat & BT848_INT_FDSR) { pr_info("%d: FDSR @ %08x\n", btv->c.nr, btread(BT848_RISC_COUNT)); if (bttv_debug) bttv_print_riscaddr(btv); } count++; if (count > 4) { if (count > 8 || !(astat & BT848_INT_GPINT)) { btwrite(0, BT848_INT_MASK); pr_err("%d: IRQ lockup, cleared int mask [", btv->c.nr); } else { pr_err("%d: IRQ lockup, clearing GPINT from int mask [", btv->c.nr); btwrite(btread(BT848_INT_MASK) & (-1 ^ BT848_INT_GPINT), BT848_INT_MASK); } bttv_print_irqbits(stat,astat); pr_cont("]\n"); } } btv->irq_total++; if (handled) btv->irq_me++; return IRQ_RETVAL(handled); }

Contributors

PersonTokensPropCommitsCommitProp
gerd knorrgerd knorr24944.95%523.81%
pre-gitpre-git17531.59%942.86%
andrew mortonandrew morton549.75%29.52%
nickolay v. shmyrevnickolay v. shmyrev447.94%14.76%
joe perchesjoe perches162.89%14.76%
ricardo cerqueiraricardo cerqueira71.26%14.76%
frank schaeferfrank schaefer61.08%14.76%
hans verkuilhans verkuil30.54%14.76%
Total554100.00%21100.00%

/* ----------------------------------------------------------------------- */ /* initialization */
static void vdev_init(struct bttv *btv, struct video_device *vfd, const struct video_device *template, const char *type_name) { *vfd = *template; vfd->v4l2_dev = &btv->c.v4l2_dev; vfd->release = video_device_release_empty; video_set_drvdata(vfd, btv); snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)", btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "", type_name, bttv_tvcards[btv->c.type].name); if (btv->tuner_type == TUNER_ABSENT) { v4l2_disable_ioctl(vfd, VIDIOC_G_FREQUENCY); v4l2_disable_ioctl(vfd, VIDIOC_S_FREQUENCY); v4l2_disable_ioctl(vfd, VIDIOC_G_TUNER); v4l2_disable_ioctl(vfd, VIDIOC_S_TUNER); } }

Contributors

PersonTokensPropCommitsCommitProp
gerd knorrgerd knorr7652.05%215.38%
hans verkuilhans verkuil4732.19%323.08%
pre-gitpre-git85.48%538.46%
trent piephotrent piepho74.79%17.69%
andrew mortonandrew morton42.74%17.69%
mauro carvalho chehabmauro carvalho chehab42.74%17.69%
Total146100.00%13100.00%


static void bttv_unregister_video(struct bttv *btv) { video_unregister_device(&btv->video_dev); video_unregister_device(&btv->vbi_dev); video_unregister_device(&btv->radio_dev); }

Contributors

PersonTokensPropCommitsCommitProp
gerd knorrgerd knorr2777.14%250.00%
pre-gitpre-git514.29%125.00%
hans verkuilhans verkuil38.57%125.00%
Total35100.00%4100.00%

/* register video4linux devices */
static int bttv_register_video(struct bttv *btv) { if (no_overlay > 0) pr_notice("Overlay support disabled\n"); /* video */ vdev_init(btv, &btv->video_dev, &bttv_video_template, "video"); if (video_register_device(&btv->video_dev, VFL_TYPE_GRABBER, video_nr[btv->c.nr]) < 0) goto err; pr_info("%d: registered device %s\n", btv->c.nr, video_device_node_name(&btv->video_dev)); if (device_create_file(&btv->video_dev.dev, &dev_attr_card)<0) { pr_err("%d: device_create_file 'card' failed\n", btv->c.nr); goto err; } /* vbi */ vdev_init(btv, &btv->vbi_dev, &bttv_video_template, "vbi"); if (video_register_device(&btv->vbi_dev, VFL_TYPE_VBI, vbi_nr[btv->c.nr]) < 0) goto err; pr_info("%d: registered device %s\n", btv->c.nr, video_device_node_name(&btv->vbi_dev)); if (!btv->has_radio) return 0; /* radio */ vdev_init(btv, &btv->radio_dev, &radio_template, "radio"); btv->radio_dev.ctrl_handler = &btv->radio_ctrl_handler; if (video_register_device(&btv->radio_dev, VFL_TYPE_RADIO, radio_nr[btv->c.nr]) < 0) goto err; pr_info("%d: registered device %s\n", btv->c.nr, video_device_node_name(&btv->radio_dev)); /* all done */ return 0; err: bttv_unregister_video(btv); return -1; }

Contributors

PersonTokensPropCommitsCommitProp
gerd knorrgerd knorr14051.09%211.76%
hans verkuilhans verkuil3512.77%423.53%
pre-gitpre-git238.39%317.65%
jean delvarejean delvare217.66%15.88%
trent piephotrent piepho196.93%15.88%
joe perchesjoe perches103.65%15.88%
laurent pinchartlaurent pinchart93.28%15.88%
mauro carvalho chehabmauro carvalho chehab93.28%211.76%
andrew mortonandrew morton62.19%15.88%
kay sieverskay sievers20.73%15.88%
Total274100.00%17100.00%

/* on OpenFirmware machines (PowerMac at least), PCI memory cycle */ /* response on cards with no firmware is not enabled by OF */
static void pci_set_command(struct pci_dev *dev) { #if defined(__powerpc__) unsigned int cmd; pci_read_config_dword(dev, PCI_COMMAND, &cmd); cmd = (cmd | PCI_COMMAND_MEMORY ); pci_write_config_dword(dev, PCI_COMMAND, cmd); #endif }

Contributors

PersonTokensPropCommitsCommitProp
gerd knorrgerd knorr4386.00%125.00%
pre-gitpre-git714.00%375.00%
Total50100.00%4100.00%


static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) { struct v4l2_frequency init_freq = { .tuner = 0, .type = V4L2_TUNER_ANALOG_TV, .frequency = 980, }; int result; unsigned char lat; struct bttv *btv; struct v4l2_ctrl_handler *hdl; if (bttv_num == BTTV_MAX) return -ENOMEM; pr_info("Bt8xx card found (%d)\n", bttv_num); bttvs[bttv_num] = btv = kzalloc(sizeof(*btv), GFP_KERNEL); if (btv == NULL) { pr_err("out of memory\n"); return -ENOMEM; } btv->c.nr = bttv_num; snprintf(btv->c.v4l2_dev.name, sizeof(btv->c.v4l2_dev.name), "bttv%d", btv->c.nr); /* initialize structs / fill in defaults */ mutex_init(&btv->lock); spin_lock_init(&btv->s_lock); spin_lock_init(&btv->gpio_lock); init_waitqueue_head(&btv->i2c_queue); INIT_LIST_HEAD(&btv->c.subs); INIT_LIST_HEAD(&btv->capture); INIT_LIST_HEAD(&btv->vcapture); init_timer(&btv->timeout); btv->timeout.function = bttv_irq_timeout; btv->timeout.data = (unsigned long)btv; btv->i2c_rc = -1; btv->tuner_type = UNSET; btv->new_input = UNSET; btv->has_radio=radio[btv->c.nr]; /* pci stuff (init, get irq/mmio, ... */ btv->c.pci = dev; btv->id = dev->device; if (pci_enable_device(dev)) { pr_warn("%d: Can't enable device\n", btv->c.nr); return -EIO; } if (pci_set_dma_mask(dev, DMA_BIT_MASK(32))) { pr_warn("%d: No suitable DMA available\n", btv->c.nr); return -EIO; } if (!request_mem_region(pci_resource_start(dev,0), pci_resource_len(dev,0), btv->c.v4l2_dev.name)) { pr_warn("%d: can't request iomem (0x%llx)\n", btv->c.nr, (unsigned long long)pci_resource_start(dev, 0)); return -EBUSY; } pci_set_master(dev); pci_set_command(dev); result = v4l2_device_register(&dev->dev, &btv->c.v4l2_dev); if (result < 0) { pr_warn("%d: v4l2_device_register() failed\n", btv->c.nr); goto fail0; } hdl = &btv->ctrl_handler; v4l2_ctrl_handler_init(hdl, 20); btv->c.v4l2_dev.ctrl_handler = hdl; v4l2_ctrl_handler_init(&btv->radio_ctrl_handler, 6); btv->revision = dev->revision; pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); pr_info("%d: Bt%d (rev %d) at %s, irq: %d, latency: %d, mmio: 0x%llx\n", bttv_num, btv->id, btv->revision, pci_name(dev), btv->c.pci->irq, lat, (unsigned long long)pci_resource_start(dev, 0)); schedule(); btv->bt848_mmio = ioremap(pci_resource_start(dev, 0), 0x1000); if (NULL == btv->bt848_mmio) { pr_err("%d: ioremap() failed\n", btv->c.nr); result = -EIO; goto fail1; } /* identify card */ bttv_idcard(btv); /* disable irqs, register irq handler */ btwrite(0, BT848_INT_MASK); result = request_irq(btv->c.pci->irq, bttv_irq, IRQF_SHARED, btv->c.v4l2_dev.name, (void *)btv); if (result < 0) { pr_err("%d: can't get IRQ %d\n", bttv_num, btv->c.pci->irq); goto fail1; } if (0 != bttv_handle_chipset(btv)) { result = -EIO; goto fail2; } /* init options from insmod args */ btv->opt_combfilter = combfilter; bttv_ctrl_combfilter.def = combfilter; bttv_ctrl_lumafilter.def = lumafilter; btv->opt_automute = automute; bttv_ctrl_automute.def = automute; bttv_ctrl_agc_crush.def = agc_crush; btv->opt_vcr_hack = vcr_hack; bttv_ctrl_vcr_hack.def = vcr_hack; bttv_ctrl_whitecrush_upper.def = whitecrush_upper; bttv_ctrl_whitecrush_lower.def = whitecrush_lower; btv->opt_uv_ratio = uv_ratio; bttv_ctrl_uv_ratio.def = uv_ratio; bttv_ctrl_full_luma.def = full_luma_range; bttv_ctrl_coring.def = coring; /* fill struct bttv with some useful defaults */ btv->init.btv = btv; btv->init.ov.w.width = 320; btv->init.ov.w.height = 240; btv->init.fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); btv->init.width = 320; btv->init.height = 240; btv->init.ov.w.width = 320; btv->init.ov.w.height = 240; btv->init.ov.field = V4L2_FIELD_INTERLACED; btv->input = 0; v4l2_ctrl_new_std(hdl, &bttv_ctrl_ops, V4L2_CID_BRIGHTNESS, 0, 0xff00, 0x100, 32768); v4l2_ctrl_new_std(hdl, &bttv_ctrl_ops, V4L2_CID_CONTRAST, 0, 0xff80, 0x80, 0x6c00); v4l2_ctrl_new_std(hdl, &bttv_ctrl_ops, V4L2_CID_SATURATION, 0, 0xff80, 0x80, 32768); v4l2_ctrl_new_std(hdl, &bttv_ctrl_ops, V4L2_CID_COLOR_KILLER, 0, 1, 1, 0); v4l2_ctrl_new_std(hdl, &bttv_ctrl_ops, V4L2_CID_HUE, 0, 0xff00, 0x100, 32768); v4l2_ctrl_new_std(hdl, &bttv_ctrl_ops, V4L2_CID_CHROMA_AGC, 0, 1, 1, !!chroma_agc); v4l2_ctrl_new_std(hdl, &bttv_ctrl_ops, V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0); if (btv->volume_gpio) v4l2_ctrl_new_std(hdl, &bttv_ctrl_ops, V4L2_CID_AUDIO_VOLUME, 0, 0xff00, 0x100, 0xff00); v4l2_ctrl_new_custom(hdl, &bttv_ctrl_combfilter, NULL); v4l2_ctrl_new_custom(hdl, &bttv_ctrl_automute, NULL); v4l2_ctrl_new_custom(hdl, &bttv_ctrl_lumafilter, NULL); v4l2_ctrl_new_custom(hdl, &bttv_ctrl_agc_crush, NULL); v4l2_ctrl_new_custom(hdl, &bttv_ctrl_vcr_hack, NULL); v4l2_ctrl_new_custom(hdl, &bttv_ctrl_whitecrush_lower, NULL); v4l2_ctrl_new_custom(hdl, &bttv_ctrl_whitecrush_upper, NULL); v4l2_ctrl_new_custom(hdl, &bttv_ctrl_uv_ratio, NULL); v4l2_ctrl_new_custom(hdl, &bttv_ctrl_full_luma, NULL); v4l2_ctrl_new_custom(hdl, &bttv_ctrl_coring, NULL); /* initialize hardware */ if (bttv_gpio) bttv_gpio_tracking(btv,"pre-init"); bttv_risc_init_main(btv); init_bt848(btv); /* gpio */ btwrite(0x00, BT848_GPIO_REG_INP); btwrite(0x00, BT848_GPIO_OUT_EN); if (bttv_verbose) bttv_gpio_tracking(btv,"init"); /* needs to be done before i2c is registered */ bttv_init_card1(btv); /* register i2c + gpio */ init_bttv_i2c(btv); /* some card-specific stuff (needs working i2c) */ bttv_init_card2(btv); bttv_init_tuner(btv); if (btv->tuner_type != TUNER_ABSENT) { bttv_set_frequency(btv, &init_freq); btv->radio_freq = 90500 * 16; /* 90.5Mhz default */ } btv->std = V4L2_STD_PAL; init_irqreg(btv); if (!bttv_tvcards[btv->c.type].no_video) v4l2_ctrl_handler_setup(hdl); if (hdl->error) { result = hdl->error; goto fail2; } /* mute device */ audio_mute(btv, 1); /* register video4linux + input */ if (!bttv_tvcards[btv->c.type].no_video) { v4l2_ctrl_add_handler(&btv->radio_ctrl_handler, hdl, v4l2_ctrl_radio_filter); if (btv->radio_ctrl_handler.error) { result = btv->radio_ctrl_handler.error; goto fail2; } set_input(btv, 0, btv->tvnorm); bttv_crop_reset(&btv->crop[0], btv->tvnorm); btv->crop[1] = btv->crop[0]; /* current = default */ disclaim_vbi_lines(btv); disclaim_video_lines(btv); bttv_register_video(btv); } /* add subdevices and autoload dvb-bt8xx if needed */ if (bttv_tvcards[btv->c.type].has_dvb) { bttv_sub_add_device(&btv->c, "dvb"); request_modules(btv); } if (!disable_ir) { init_bttv_i2c_ir(btv); bttv_input_init(btv); } /* everything is fine */ bttv_num++; return 0; fail2: free_irq(btv->c.pci->irq,btv); fail1: v4l2_ctrl_handler_free(&btv->ctrl_handler); v4l2_ctrl_handler_free(&btv->radio_ctrl_handler); v4l2_device_unregister(&btv->c.v4l2_dev); fail0: if (btv->bt848_mmio) iounmap(btv->bt848_mmio); release_mem_region(pci_resource_start(btv->c.pci,0), pci_resource_len(btv->c.pci,0)); pci_disable_device(btv->c.pci); return result; }

Contributors

PersonTokensPropCommitsCommitProp
hans verkuilhans verkuil65743.28%817.39%
gerd knorrgerd knorr40526.68%24.35%
pre-gitpre-git22314.69%1736.96%
andrew mortonandrew morton956.26%12.17%
michael h. schimekmichael h. schimek402.64%12.17%
joe perchesjoe perches181.19%12.17%
jean delvarejean delvare120.79%24.35%
trent piephotrent piepho100.66%24.35%
greg kroah-hartmangreg kroah-hartman100.66%12.17%
thomas gleixnerthomas gleixner90.59%24.35%
frank schaeferfrank schaefer80.53%12.17%
jarod wilsonjarod wilson80.53%12.17%
ricardo cerqueiraricardo cerqueira50.33%12.17%
yang hongyangyang hongyang40.26%12.17%
bjorn morkbjorn mork40.26%12.17%
akinobu mitaakinobu mita30.20%12.17%
mauro carvalho chehabmauro carvalho chehab30.20%12.17%
randy dunlaprandy dunlap30.20%12.17%
ingo molnaringo molnar10.07%12.17%
Total1518100.00%46100.00%


static void bttv_remove(struct pci_dev *pci_dev) { struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); struct bttv *btv = to_bttv(v4l2_dev); if (bttv_verbose) pr_info("%d: unloading\n", btv->c.nr); if (bttv_tvcards[btv->c.type].has_dvb) flush_request_modules(btv); /* shutdown everything (DMA+IRQs) */ btand(~15, BT848_GPIO_DMA_CTL); btwrite(0, BT848_INT_MASK); btwrite(~0x0, BT848_INT_STAT); btwrite(0x0, BT848_GPIO_OUT_EN); if (bttv_gpio) bttv_gpio_tracking(btv,"cleanup"); /* tell gpio modules we are leaving ... */ btv->shutdown=1; bttv_input_fini(btv); bttv_sub_del_devices(&btv->c); /* unregister i2c_bus + input */ fini_bttv_i2c(btv); /* unregister video4linux */ bttv_unregister_video(btv); /* free allocated memory */ v4l2_ctrl_handler_free(&btv->ctrl_handler); v4l2_ctrl_handler_free(&btv->radio_ctrl_handler); btcx_riscmem_free(btv->c.pci,&btv->main); /* free resources */ free_irq(btv->c.pci->irq,btv); iounmap(btv->bt848_mmio); release_mem_region(pci_resource_start(btv->c.pci,0), pci_resource_len(btv->c.pci,0)); pci_disable_device(btv->c.pci); v4l2_device_unregister(&btv->c.v4l2_dev); bttvs[btv->c.nr] = NULL; kfree(btv); return; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git7329.08%838.10%
gerd knorrgerd knorr7228.69%419.05%
hans verkuilhans verkuil4517.93%314.29%
tejun heotejun heo187.17%14.76%
trent piephotrent piepho166.37%14.76%
andrew mortonandrew morton166.37%14.76%
chris pascoechris pascoe83.19%14.76%
joe perchesjoe perches20.80%14.76%
ricardo cerqueiraricardo cerqueira10.40%14.76%
Total251100.00%21100.00%

#ifdef CONFIG_PM
static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state) { struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); struct bttv *btv = to_bttv(v4l2_dev); struct bttv_buffer_set idle; unsigned long flags; dprintk("%d: suspend %d\n", btv->c.nr, state.event); /* stop dma + irqs */ spin_lock_irqsave(&btv->s_lock,flags); memset(&idle, 0, sizeof(idle)); btv->state.video = btv->curr; btv->state.vbi = btv->cvbi; btv->state.loop_irq = btv->loop_irq; btv->curr = idle; btv->loop_irq = 0; bttv_buffer_activate_video(btv, &idle); bttv_buffer_activate_vbi(btv, NULL); bttv_set_dma(btv, 0); btwrite(0, BT848_INT_MASK); spin_unlock_irqrestore(&btv->s_lock,flags); /* save bt878 state */ btv->state.gpio_enable = btread(BT848_GPIO_OUT_EN); btv->state.gpio_data = gpio_read(); /* save pci state */ pci_save_state(pci_dev); if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) { pci_disable_device(pci_dev); btv->state.disabled = 1; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
andrew mortonandrew morton15167.71%110.00%
gerd knorrgerd knorr3616.14%330.00%
mauro carvalho chehabmauro carvalho chehab146.28%110.00%
hans verkuilhans verkuil125.38%110.00%
pre-gitpre-git41.79%110.00%
pavel machekpavel machek41.79%110.00%
joe perchesjoe perches10.45%110.00%
greg kroah-hartmangreg kroah-hartman10.45%110.00%
Total223100.00%10100.00%


static int bttv_resume(struct pci_dev *pci_dev) { struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); struct bttv *btv = to_bttv(v4l2_dev); unsigned long flags; int err; dprintk("%d: resume\n", btv->c.nr); /* restore pci state */ if (btv->state.disabled) { err=pci_enable_device(pci_dev); if (err) { pr_warn("%d: Can't enable device\n", btv->c.nr); return err; } btv->state.disabled = 0; } err=pci_set_power_state(pci_dev, PCI_D0); if (err) { pci_disable_device(pci_dev); pr_warn("%d: Can't enable device\n", btv->c.nr); btv->state.disabled = 1; return err; } pci_restore_state(pci_dev); /* restore bt878 state */ bttv_reinit_bt848(btv); gpio_inout(0xffffff, btv->state.gpio_enable); gpio_write(btv->state.gpio_data); /* restart dma */ spin_lock_irqsave(&btv->s_lock,flags); btv->curr = btv->state.video; btv->cvbi = btv->state.vbi; btv->loop_irq = btv->state.loop_irq; bttv_buffer_activate_video(btv, &btv->curr); bttv_buffer_activate_vbi(btv, btv->cvbi); bttv_set_dma(btv, 0); spin_unlock_irqrestore(&btv->s_lock,flags); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
andrew mortonandrew morton14257.26%114.29%
mauro carvalho chehabmauro carvalho chehab5622.58%114.29%
gerd knorrgerd knorr3212.90%228.57%
hans verkuilhans verkuil124.84%114.29%
joe perchesjoe perches52.02%114.29%
pavel machekpavel machek10.40%114.29%
Total248100.00%7100.00%

#endif static struct pci_device_id bttv_pci_tbl[] = { {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT848), 0}, {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT849), 0}, {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT878), 0}, {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_BT879), 0}, {PCI_VDEVICE(BROOKTREE, PCI_DEVICE_ID_FUSION879), 0}, {0,} }; MODULE_DEVICE_TABLE(pci, bttv_pci_tbl); static struct pci_driver bttv_pci_driver = { .name = "bttv", .id_table = bttv_pci_tbl, .probe = bttv_probe, .remove = bttv_remove, #ifdef CONFIG_PM .suspend = bttv_suspend, .resume = bttv_resume, #endif };
static int __init bttv_init_module(void) { int ret; bttv_num = 0; pr_info("driver version %s loaded\n", BTTV_VERSION); if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME) gbuffers = 2; if (gbufsize > BTTV_MAX_FBUF) gbufsize = BTTV_MAX_FBUF; gbufsize = (gbufsize + PAGE_SIZE - 1) & PAGE_MASK; if (bttv_verbose) pr_info("using %d buffers with %dk (%d pages) each for capture\n", gbuffers, gbufsize >> 10, gbufsize >> PAGE_SHIFT); bttv_check_chipset(); ret = bus_register(&bttv_sub_bus_type); if (ret < 0) { pr_warn("bus_register error: %d\n", ret); return ret; } ret = pci_register_driver(&bttv_pci_driver); if (ret < 0) bus_unregister(&bttv_sub_bus_type); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git5643.08%642.86%
randy dunlaprandy dunlap2116.15%17.14%
gerd knorrgerd knorr1813.85%17.14%
akinobu mitaakinobu mita1713.08%17.14%
andrew mortonandrew morton96.92%17.14%
joe perchesjoe perches64.62%17.14%
otavio salvadorotavio salvador10.77%17.14%
adrian bunkadrian bunk10.77%17.14%
mauro carvalho chehabmauro carvalho chehab10.77%17.14%
Total130100.00%14100.00%


static void __exit bttv_cleanup_module(void) { pci_unregister_driver(&bttv_pci_driver); bus_unregister(&bttv_sub_bus_type); }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git1361.90%240.00%
andrew mortonandrew morton628.57%120.00%
adrian bunkadrian bunk14.76%120.00%
gerd knorrgerd knorr14.76%120.00%
Total21100.00%5100.00%

module_init(bttv_init_module); module_exit(bttv_cleanup_module);

Overall Contributors

PersonTokensPropCommitsCommitProp
gerd knorrgerd knorr631928.31%156.98%
hans verkuilhans verkuil472521.17%4420.47%
mauro carvalho chehabmauro carvalho chehab20509.18%2411.16%
michael h. schimekmichael h. schimek19798.86%31.40%
nickolay v. shmyrevnickolay v. shmyrev18698.37%52.33%
douglas schilling landgrafdouglas schilling landgraf14346.42%10.47%
pre-gitpre-git13766.16%2913.49%
andrew mortonandrew morton7803.49%31.40%
art haasart haas2981.33%10.47%
frank schaeferfrank schaefer2000.90%83.72%
ondrej zaryondrej zary1710.77%20.93%
jean delvarejean delvare1540.69%31.40%
hans de goedehans de goede1460.65%31.40%
joe perchesjoe perches1310.59%20.93%
trent piephotrent piepho1160.52%94.19%
robert fitzsimonsrobert fitzsimons970.43%31.40%
jarod wilsonjarod wilson770.34%10.47%
linus torvaldslinus torvalds470.21%73.26%
tejun heotejun heo460.21%31.40%
laurent pinchartlaurent pinchart440.20%41.86%
randy dunlaprandy dunlap240.11%20.93%
akinobu mitaakinobu mita200.09%20.93%
david s. millerdavid s. miller150.07%10.47%
ricardo ribaldaricardo ribalda130.06%10.47%
ricardo cerqueiraricardo cerqueira130.06%10.47%
brandon philipsbrandon philips120.05%31.40%
guennadi liakhovetskiguennadi liakhovetski120.05%10.47%
alexey dobriyanalexey dobriyan120.05%10.47%
peter de schrijverpeter de schrijver110.05%10.47%
greg kroah-hartmangreg kroah-hartman110.05%20.93%
al viroal viro100.04%20.93%
kay sieverskay sievers90.04%10.47%
andreas bombeandreas bombe90.04%10.47%
thomas gleixnerthomas gleixner90.04%20.93%
figo zhangfigo zhang90.04%10.47%
wade berrierwade berrier80.04%10.47%
chris pascoechris pascoe80.04%10.47%
adrian bunkadrian bunk70.03%31.40%
sf markus elfringsf markus elfring60.03%10.47%
udo steinbergudo steinberg60.03%10.47%
pavel machekpavel machek50.02%10.47%
zoltan devaizoltan devai50.02%10.47%
arnd bergmannarnd bergmann40.02%20.93%
bjorn morkbjorn mork40.02%10.47%
yang hongyangyang hongyang40.02%10.47%
guilherme herrmann destefaniguilherme herrmann destefani40.02%10.47%
sakari ailussakari ailus30.01%10.47%
michael krufkymichael krufky30.01%10.47%
dave jonesdave jones20.01%10.47%
arjan van de venarjan van de ven20.01%10.47%
mike iselymike isely10.00%10.47%
nathan laredonathan laredo10.00%10.47%
geliang tanggeliang tang10.00%10.47%
otavio salvadorotavio salvador10.00%10.47%
ingo molnaringo molnar10.00%10.47%
Total22324100.00%215100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}