📄 saa7134-video.c
字号:
/* * * device driver for philips saa7134 based TV cards * video4linux video interface * * (c) 2001-03 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] * * 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. */#include <linux/init.h>#include <linux/list.h>#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/kernel.h>#include <linux/slab.h>#include "saa7134-reg.h"#include "saa7134.h"/* Include V4L1 specific functions. Should be removed soon */#include <linux/videodev.h>/* ------------------------------------------------------------------ */static unsigned int video_debug = 0;static unsigned int gbuffers = 8;static unsigned int noninterlaced = 0;static unsigned int gbufsize = 720*576*4;static unsigned int gbufsize_max = 720*576*4;module_param(video_debug, int, 0644);MODULE_PARM_DESC(video_debug,"enable debug messages [video]");module_param(gbuffers, int, 0444);MODULE_PARM_DESC(gbuffers,"number of capture buffers, range 2-32");module_param(noninterlaced, int, 0644);MODULE_PARM_DESC(noninterlaced,"video input is noninterlaced");#define dprintk(fmt, arg...) if (video_debug) \ printk(KERN_DEBUG "%s/video: " fmt, dev->name , ## arg)/* ------------------------------------------------------------------ *//* Defines for Video Output Port Register at address 0x191 *//* Bit 0: VIP code T bit polarity */#define VP_T_CODE_P_NON_INVERTED 0x00#define VP_T_CODE_P_INVERTED 0x01/* ------------------------------------------------------------------ *//* Defines for Video Output Port Register at address 0x195 *//* Bit 2: Video output clock delay control */#define VP_CLK_CTRL2_NOT_DELAYED 0x00#define VP_CLK_CTRL2_DELAYED 0x04/* Bit 1: Video output clock invert control */#define VP_CLK_CTRL1_NON_INVERTED 0x00#define VP_CLK_CTRL1_INVERTED 0x02/* ------------------------------------------------------------------ *//* Defines for Video Output Port Register at address 0x196 *//* Bits 2 to 0: VSYNC pin video vertical sync type */#define VP_VS_TYPE_MASK 0x07#define VP_VS_TYPE_OFF 0x00#define VP_VS_TYPE_V123 0x01#define VP_VS_TYPE_V_ITU 0x02#define VP_VS_TYPE_VGATE_L 0x03#define VP_VS_TYPE_RESERVED1 0x04#define VP_VS_TYPE_RESERVED2 0x05#define VP_VS_TYPE_F_ITU 0x06#define VP_VS_TYPE_SC_FID 0x07/* ------------------------------------------------------------------ *//* data structs for video */static int video_out[][9] = { [CCIR656] = { 0x00, 0xb1, 0x00, 0xa1, 0x00, 0x04, 0x06, 0x00, 0x00 },};static struct saa7134_format formats[] = { { .name = "8 bpp gray", .fourcc = V4L2_PIX_FMT_GREY, .depth = 8, .pm = 0x06, },{ .name = "15 bpp RGB, le", .fourcc = V4L2_PIX_FMT_RGB555, .depth = 16, .pm = 0x13 | 0x80, },{ .name = "15 bpp RGB, be", .fourcc = V4L2_PIX_FMT_RGB555X, .depth = 16, .pm = 0x13 | 0x80, .bswap = 1, },{ .name = "16 bpp RGB, le", .fourcc = V4L2_PIX_FMT_RGB565, .depth = 16, .pm = 0x10 | 0x80, },{ .name = "16 bpp RGB, be", .fourcc = V4L2_PIX_FMT_RGB565X, .depth = 16, .pm = 0x10 | 0x80, .bswap = 1, },{ .name = "24 bpp RGB, le", .fourcc = V4L2_PIX_FMT_BGR24, .depth = 24, .pm = 0x11, },{ .name = "24 bpp RGB, be", .fourcc = V4L2_PIX_FMT_RGB24, .depth = 24, .pm = 0x11, .bswap = 1, },{ .name = "32 bpp RGB, le", .fourcc = V4L2_PIX_FMT_BGR32, .depth = 32, .pm = 0x12, },{ .name = "32 bpp RGB, be", .fourcc = V4L2_PIX_FMT_RGB32, .depth = 32, .pm = 0x12, .bswap = 1, .wswap = 1, },{ .name = "4:2:2 packed, YUYV", .fourcc = V4L2_PIX_FMT_YUYV, .depth = 16, .pm = 0x00, .bswap = 1, .yuv = 1, },{ .name = "4:2:2 packed, UYVY", .fourcc = V4L2_PIX_FMT_UYVY, .depth = 16, .pm = 0x00, .yuv = 1, },{ .name = "4:2:2 planar, Y-Cb-Cr", .fourcc = V4L2_PIX_FMT_YUV422P, .depth = 16, .pm = 0x09, .yuv = 1, .planar = 1, .hshift = 1, .vshift = 0, },{ .name = "4:2:0 planar, Y-Cb-Cr", .fourcc = V4L2_PIX_FMT_YUV420, .depth = 12, .pm = 0x0a, .yuv = 1, .planar = 1, .hshift = 1, .vshift = 1, },{ .name = "4:2:0 planar, Y-Cb-Cr", .fourcc = V4L2_PIX_FMT_YVU420, .depth = 12, .pm = 0x0a, .yuv = 1, .planar = 1, .uvswap = 1, .hshift = 1, .vshift = 1, }};#define FORMATS ARRAY_SIZE(formats)#define NORM_625_50 \ .h_start = 0, \ .h_stop = 719, \ .video_v_start = 24, \ .video_v_stop = 311, \ .vbi_v_start_0 = 7, \ .vbi_v_stop_0 = 22, \ .vbi_v_start_1 = 319, \ .src_timing = 4#define NORM_525_60 \ .h_start = 0, \ .h_stop = 703, \ .video_v_start = 23, \ .video_v_stop = 262, \ .vbi_v_start_0 = 10, \ .vbi_v_stop_0 = 21, \ .vbi_v_start_1 = 273, \ .src_timing = 7static struct saa7134_tvnorm tvnorms[] = { { .name = "PAL", /* autodetect */ .id = V4L2_STD_PAL, NORM_625_50, .sync_control = 0x18, .luma_control = 0x40, .chroma_ctrl1 = 0x81, .chroma_gain = 0x2a, .chroma_ctrl2 = 0x06, .vgate_misc = 0x1c, },{ .name = "PAL-BG", .id = V4L2_STD_PAL_BG, NORM_625_50, .sync_control = 0x18, .luma_control = 0x40, .chroma_ctrl1 = 0x81, .chroma_gain = 0x2a, .chroma_ctrl2 = 0x06, .vgate_misc = 0x1c, },{ .name = "PAL-I", .id = V4L2_STD_PAL_I, NORM_625_50, .sync_control = 0x18, .luma_control = 0x40, .chroma_ctrl1 = 0x81, .chroma_gain = 0x2a, .chroma_ctrl2 = 0x06, .vgate_misc = 0x1c, },{ .name = "PAL-DK", .id = V4L2_STD_PAL_DK, NORM_625_50, .sync_control = 0x18, .luma_control = 0x40, .chroma_ctrl1 = 0x81, .chroma_gain = 0x2a, .chroma_ctrl2 = 0x06, .vgate_misc = 0x1c, },{ .name = "NTSC", .id = V4L2_STD_NTSC, NORM_525_60, .sync_control = 0x59, .luma_control = 0x40, .chroma_ctrl1 = 0x89, .chroma_gain = 0x2a, .chroma_ctrl2 = 0x0e, .vgate_misc = 0x18, },{ .name = "SECAM", .id = V4L2_STD_SECAM, NORM_625_50, .sync_control = 0x18, /* old: 0x58, */ .luma_control = 0x1b, .chroma_ctrl1 = 0xd1, .chroma_gain = 0x80, .chroma_ctrl2 = 0x00, .vgate_misc = 0x1c, },{ .name = "PAL-M", .id = V4L2_STD_PAL_M, NORM_525_60, .sync_control = 0x59, .luma_control = 0x40, .chroma_ctrl1 = 0xb9, .chroma_gain = 0x2a, .chroma_ctrl2 = 0x0e, .vgate_misc = 0x18, },{ .name = "PAL-Nc", .id = V4L2_STD_PAL_Nc, NORM_625_50, .sync_control = 0x18, .luma_control = 0x40, .chroma_ctrl1 = 0xa1, .chroma_gain = 0x2a, .chroma_ctrl2 = 0x06, .vgate_misc = 0x1c, },{ .name = "PAL-60", .id = V4L2_STD_PAL_60, .h_start = 0, .h_stop = 719, .video_v_start = 23, .video_v_stop = 262, .vbi_v_start_0 = 10, .vbi_v_stop_0 = 21, .vbi_v_start_1 = 273, .src_timing = 7, .sync_control = 0x18, .luma_control = 0x40, .chroma_ctrl1 = 0x81, .chroma_gain = 0x2a, .chroma_ctrl2 = 0x06, .vgate_misc = 0x1c, }};#define TVNORMS ARRAY_SIZE(tvnorms)#define V4L2_CID_PRIVATE_INVERT (V4L2_CID_PRIVATE_BASE + 0)#define V4L2_CID_PRIVATE_Y_ODD (V4L2_CID_PRIVATE_BASE + 1)#define V4L2_CID_PRIVATE_Y_EVEN (V4L2_CID_PRIVATE_BASE + 2)#define V4L2_CID_PRIVATE_AUTOMUTE (V4L2_CID_PRIVATE_BASE + 3)#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 4)static const struct v4l2_queryctrl no_ctrl = { .name = "42", .flags = V4L2_CTRL_FLAG_DISABLED,};static const struct v4l2_queryctrl video_ctrls[] = { /* --- video --- */ { .id = V4L2_CID_BRIGHTNESS, .name = "Brightness", .minimum = 0, .maximum = 255, .step = 1, .default_value = 128, .type = V4L2_CTRL_TYPE_INTEGER, },{ .id = V4L2_CID_CONTRAST, .name = "Contrast", .minimum = 0, .maximum = 127, .step = 1, .default_value = 68, .type = V4L2_CTRL_TYPE_INTEGER, },{ .id = V4L2_CID_SATURATION, .name = "Saturation", .minimum = 0, .maximum = 127, .step = 1, .default_value = 64, .type = V4L2_CTRL_TYPE_INTEGER, },{ .id = V4L2_CID_HUE, .name = "Hue", .minimum = -128, .maximum = 127, .step = 1, .default_value = 0, .type = V4L2_CTRL_TYPE_INTEGER, },{ .id = V4L2_CID_HFLIP, .name = "Mirror", .minimum = 0, .maximum = 1, .type = V4L2_CTRL_TYPE_BOOLEAN, }, /* --- audio --- */ { .id = V4L2_CID_AUDIO_MUTE, .name = "Mute", .minimum = 0, .maximum = 1, .type = V4L2_CTRL_TYPE_BOOLEAN, },{ .id = V4L2_CID_AUDIO_VOLUME, .name = "Volume", .minimum = -15, .maximum = 15, .step = 1, .default_value = 0, .type = V4L2_CTRL_TYPE_INTEGER, }, /* --- private --- */ { .id = V4L2_CID_PRIVATE_INVERT, .name = "Invert", .minimum = 0, .maximum = 1, .type = V4L2_CTRL_TYPE_BOOLEAN, },{ .id = V4L2_CID_PRIVATE_Y_ODD, .name = "y offset odd field", .minimum = 0, .maximum = 128, .default_value = 0, .type = V4L2_CTRL_TYPE_INTEGER, },{ .id = V4L2_CID_PRIVATE_Y_EVEN, .name = "y offset even field", .minimum = 0, .maximum = 128, .default_value = 0, .type = V4L2_CTRL_TYPE_INTEGER, },{ .id = V4L2_CID_PRIVATE_AUTOMUTE, .name = "automute", .minimum = 0, .maximum = 1, .default_value = 1, .type = V4L2_CTRL_TYPE_BOOLEAN, }};static const unsigned int CTRLS = ARRAY_SIZE(video_ctrls);static const struct v4l2_queryctrl* ctrl_by_id(unsigned int id){ unsigned int i; for (i = 0; i < CTRLS; i++) if (video_ctrls[i].id == id) return video_ctrls+i; return NULL;}static struct saa7134_format* format_by_fourcc(unsigned int fourcc){ unsigned int i; for (i = 0; i < FORMATS; i++) if (formats[i].fourcc == fourcc) return formats+i; return NULL;}/* ----------------------------------------------------------------------- *//* resource management */static int res_get(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bit){ if (fh->resources & bit) /* have it already allocated */ return 1; /* is it free? */ down(&dev->lock); if (dev->resources & bit) { /* no, someone else uses it */ up(&dev->lock); return 0; } /* it's free, grab it */ fh->resources |= bit; dev->resources |= bit; dprintk("res: get %d\n",bit); up(&dev->lock); return 1;}staticint res_check(struct saa7134_fh *fh, unsigned int bit){ return (fh->resources & bit);}staticint res_locked(struct saa7134_dev *dev, unsigned int bit){ return (dev->resources & bit);}staticvoid res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits){ if ((fh->resources & bits) != bits)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -