• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/src/linux/linux-2.6/drivers/media/video/saa7134/
1/*
2 *
3 * device driver for philips saa7134 based TV cards
4 * video4linux video interface
5 *
6 * (c) 2001-03 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]
7 *
8 *  This program is free software; you can redistribute it and/or modify
9 *  it under the terms of the GNU General Public License as published by
10 *  the Free Software Foundation; either version 2 of the License, or
11 *  (at your option) any later version.
12 *
13 *  This program is distributed in the hope that it will be useful,
14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *  GNU General Public License for more details.
17 *
18 *  You should have received a copy of the GNU General Public License
19 *  along with this program; if not, write to the Free Software
20 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/init.h>
24#include <linux/list.h>
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/kernel.h>
28#include <linux/slab.h>
29#include <linux/sort.h>
30
31#include "saa7134-reg.h"
32#include "saa7134.h"
33#include <media/v4l2-common.h>
34
35#ifdef CONFIG_VIDEO_V4L1_COMPAT
36/* Include V4L1 specific functions. Should be removed soon */
37#include <linux/videodev.h>
38#endif
39
40/* ------------------------------------------------------------------ */
41
42static unsigned int video_debug   = 0;
43static unsigned int gbuffers      = 8;
44static unsigned int noninterlaced = 1;
45static unsigned int gbufsize      = 720*576*4;
46static unsigned int gbufsize_max  = 720*576*4;
47static char secam[] = "--";
48module_param(video_debug, int, 0644);
49MODULE_PARM_DESC(video_debug,"enable debug messages [video]");
50module_param(gbuffers, int, 0444);
51MODULE_PARM_DESC(gbuffers,"number of capture buffers, range 2-32");
52module_param(noninterlaced, int, 0644);
53MODULE_PARM_DESC(noninterlaced,"capture non interlaced video");
54module_param_string(secam, secam, sizeof(secam), 0644);
55MODULE_PARM_DESC(secam, "force SECAM variant, either DK,L or Lc");
56
57
58#define dprintk(fmt, arg...)	if (video_debug) \
59	printk(KERN_DEBUG "%s/video: " fmt, dev->name , ## arg)
60
61/* ------------------------------------------------------------------ */
62/* Defines for Video Output Port Register at address 0x191            */
63
64/* Bit 0: VIP code T bit polarity */
65
66#define VP_T_CODE_P_NON_INVERTED	0x00
67#define VP_T_CODE_P_INVERTED		0x01
68
69/* ------------------------------------------------------------------ */
70/* Defines for Video Output Port Register at address 0x195            */
71
72/* Bit 2: Video output clock delay control */
73
74#define VP_CLK_CTRL2_NOT_DELAYED	0x00
75#define VP_CLK_CTRL2_DELAYED		0x04
76
77/* Bit 1: Video output clock invert control */
78
79#define VP_CLK_CTRL1_NON_INVERTED	0x00
80#define VP_CLK_CTRL1_INVERTED		0x02
81
82/* ------------------------------------------------------------------ */
83/* Defines for Video Output Port Register at address 0x196            */
84
85/* Bits 2 to 0: VSYNC pin video vertical sync type */
86
87#define VP_VS_TYPE_MASK			0x07
88
89#define VP_VS_TYPE_OFF			0x00
90#define VP_VS_TYPE_V123			0x01
91#define VP_VS_TYPE_V_ITU		0x02
92#define VP_VS_TYPE_VGATE_L		0x03
93#define VP_VS_TYPE_RESERVED1		0x04
94#define VP_VS_TYPE_RESERVED2		0x05
95#define VP_VS_TYPE_F_ITU		0x06
96#define VP_VS_TYPE_SC_FID		0x07
97
98/* ------------------------------------------------------------------ */
99/* data structs for video                                             */
100
101static int video_out[][9] = {
102	[CCIR656] = { 0x00, 0xb1, 0x00, 0xa1, 0x00, 0x04, 0x06, 0x00, 0x00 },
103};
104
105static struct saa7134_format formats[] = {
106	{
107		.name     = "8 bpp gray",
108		.fourcc   = V4L2_PIX_FMT_GREY,
109		.depth    = 8,
110		.pm       = 0x06,
111	},{
112		.name     = "15 bpp RGB, le",
113		.fourcc   = V4L2_PIX_FMT_RGB555,
114		.depth    = 16,
115		.pm       = 0x13 | 0x80,
116	},{
117		.name     = "15 bpp RGB, be",
118		.fourcc   = V4L2_PIX_FMT_RGB555X,
119		.depth    = 16,
120		.pm       = 0x13 | 0x80,
121		.bswap    = 1,
122	},{
123		.name     = "16 bpp RGB, le",
124		.fourcc   = V4L2_PIX_FMT_RGB565,
125		.depth    = 16,
126		.pm       = 0x10 | 0x80,
127	},{
128		.name     = "16 bpp RGB, be",
129		.fourcc   = V4L2_PIX_FMT_RGB565X,
130		.depth    = 16,
131		.pm       = 0x10 | 0x80,
132		.bswap    = 1,
133	},{
134		.name     = "24 bpp RGB, le",
135		.fourcc   = V4L2_PIX_FMT_BGR24,
136		.depth    = 24,
137		.pm       = 0x11,
138	},{
139		.name     = "24 bpp RGB, be",
140		.fourcc   = V4L2_PIX_FMT_RGB24,
141		.depth    = 24,
142		.pm       = 0x11,
143		.bswap    = 1,
144	},{
145		.name     = "32 bpp RGB, le",
146		.fourcc   = V4L2_PIX_FMT_BGR32,
147		.depth    = 32,
148		.pm       = 0x12,
149	},{
150		.name     = "32 bpp RGB, be",
151		.fourcc   = V4L2_PIX_FMT_RGB32,
152		.depth    = 32,
153		.pm       = 0x12,
154		.bswap    = 1,
155		.wswap    = 1,
156	},{
157		.name     = "4:2:2 packed, YUYV",
158		.fourcc   = V4L2_PIX_FMT_YUYV,
159		.depth    = 16,
160		.pm       = 0x00,
161		.bswap    = 1,
162		.yuv      = 1,
163	},{
164		.name     = "4:2:2 packed, UYVY",
165		.fourcc   = V4L2_PIX_FMT_UYVY,
166		.depth    = 16,
167		.pm       = 0x00,
168		.yuv      = 1,
169	},{
170		.name     = "4:2:2 planar, Y-Cb-Cr",
171		.fourcc   = V4L2_PIX_FMT_YUV422P,
172		.depth    = 16,
173		.pm       = 0x09,
174		.yuv      = 1,
175		.planar   = 1,
176		.hshift   = 1,
177		.vshift   = 0,
178	},{
179		.name     = "4:2:0 planar, Y-Cb-Cr",
180		.fourcc   = V4L2_PIX_FMT_YUV420,
181		.depth    = 12,
182		.pm       = 0x0a,
183		.yuv      = 1,
184		.planar   = 1,
185		.hshift   = 1,
186		.vshift   = 1,
187	},{
188		.name     = "4:2:0 planar, Y-Cb-Cr",
189		.fourcc   = V4L2_PIX_FMT_YVU420,
190		.depth    = 12,
191		.pm       = 0x0a,
192		.yuv      = 1,
193		.planar   = 1,
194		.uvswap   = 1,
195		.hshift   = 1,
196		.vshift   = 1,
197	}
198};
199#define FORMATS ARRAY_SIZE(formats)
200
201#define NORM_625_50			\
202		.h_start       = 0,	\
203		.h_stop        = 719,	\
204		.video_v_start = 24,	\
205		.video_v_stop  = 311,	\
206		.vbi_v_start_0 = 7,	\
207		.vbi_v_stop_0  = 22,	\
208		.vbi_v_start_1 = 319,   \
209		.src_timing    = 4
210
211#define NORM_525_60			\
212		.h_start       = 0,	\
213		.h_stop        = 703,	\
214		.video_v_start = 23,	\
215		.video_v_stop  = 262,	\
216		.vbi_v_start_0 = 10,	\
217		.vbi_v_stop_0  = 21,	\
218		.vbi_v_start_1 = 273,	\
219		.src_timing    = 7
220
221static struct saa7134_tvnorm tvnorms[] = {
222	{
223		.name          = "PAL", /* autodetect */
224		.id            = V4L2_STD_PAL,
225		NORM_625_50,
226
227		.sync_control  = 0x18,
228		.luma_control  = 0x40,
229		.chroma_ctrl1  = 0x81,
230		.chroma_gain   = 0x2a,
231		.chroma_ctrl2  = 0x06,
232		.vgate_misc    = 0x1c,
233
234	},{
235		.name          = "PAL-BG",
236		.id            = V4L2_STD_PAL_BG,
237		NORM_625_50,
238
239		.sync_control  = 0x18,
240		.luma_control  = 0x40,
241		.chroma_ctrl1  = 0x81,
242		.chroma_gain   = 0x2a,
243		.chroma_ctrl2  = 0x06,
244		.vgate_misc    = 0x1c,
245
246	},{
247		.name          = "PAL-I",
248		.id            = V4L2_STD_PAL_I,
249		NORM_625_50,
250
251		.sync_control  = 0x18,
252		.luma_control  = 0x40,
253		.chroma_ctrl1  = 0x81,
254		.chroma_gain   = 0x2a,
255		.chroma_ctrl2  = 0x06,
256		.vgate_misc    = 0x1c,
257
258	},{
259		.name          = "PAL-DK",
260		.id            = V4L2_STD_PAL_DK,
261		NORM_625_50,
262
263		.sync_control  = 0x18,
264		.luma_control  = 0x40,
265		.chroma_ctrl1  = 0x81,
266		.chroma_gain   = 0x2a,
267		.chroma_ctrl2  = 0x06,
268		.vgate_misc    = 0x1c,
269
270	},{
271		.name          = "NTSC",
272		.id            = V4L2_STD_NTSC,
273		NORM_525_60,
274
275		.sync_control  = 0x59,
276		.luma_control  = 0x40,
277		.chroma_ctrl1  = 0x89,
278		.chroma_gain   = 0x2a,
279		.chroma_ctrl2  = 0x0e,
280		.vgate_misc    = 0x18,
281
282	},{
283		.name          = "SECAM",
284		.id            = V4L2_STD_SECAM,
285		NORM_625_50,
286
287		.sync_control  = 0x18,
288		.luma_control  = 0x1b,
289		.chroma_ctrl1  = 0xd1,
290		.chroma_gain   = 0x80,
291		.chroma_ctrl2  = 0x00,
292		.vgate_misc    = 0x1c,
293
294	},{
295		.name          = "SECAM-DK",
296		.id            = V4L2_STD_SECAM_DK,
297		NORM_625_50,
298
299		.sync_control  = 0x18,
300		.luma_control  = 0x1b,
301		.chroma_ctrl1  = 0xd1,
302		.chroma_gain   = 0x80,
303		.chroma_ctrl2  = 0x00,
304		.vgate_misc    = 0x1c,
305
306	},{
307		.name          = "SECAM-L",
308		.id            = V4L2_STD_SECAM_L,
309		NORM_625_50,
310
311		.sync_control  = 0x18,
312		.luma_control  = 0x1b,
313		.chroma_ctrl1  = 0xd1,
314		.chroma_gain   = 0x80,
315		.chroma_ctrl2  = 0x00,
316		.vgate_misc    = 0x1c,
317
318	},{
319		.name          = "SECAM-Lc",
320		.id            = V4L2_STD_SECAM_LC,
321		NORM_625_50,
322
323		.sync_control  = 0x18,
324		.luma_control  = 0x1b,
325		.chroma_ctrl1  = 0xd1,
326		.chroma_gain   = 0x80,
327		.chroma_ctrl2  = 0x00,
328		.vgate_misc    = 0x1c,
329
330	},{
331		.name          = "PAL-M",
332		.id            = V4L2_STD_PAL_M,
333		NORM_525_60,
334
335		.sync_control  = 0x59,
336		.luma_control  = 0x40,
337		.chroma_ctrl1  = 0xb9,
338		.chroma_gain   = 0x2a,
339		.chroma_ctrl2  = 0x0e,
340		.vgate_misc    = 0x18,
341
342	},{
343		.name          = "PAL-Nc",
344		.id            = V4L2_STD_PAL_Nc,
345		NORM_625_50,
346
347		.sync_control  = 0x18,
348		.luma_control  = 0x40,
349		.chroma_ctrl1  = 0xa1,
350		.chroma_gain   = 0x2a,
351		.chroma_ctrl2  = 0x06,
352		.vgate_misc    = 0x1c,
353
354	},{
355		.name          = "PAL-60",
356		.id            = V4L2_STD_PAL_60,
357
358		.h_start       = 0,
359		.h_stop        = 719,
360		.video_v_start = 23,
361		.video_v_stop  = 262,
362		.vbi_v_start_0 = 10,
363		.vbi_v_stop_0  = 21,
364		.vbi_v_start_1 = 273,
365		.src_timing    = 7,
366
367		.sync_control  = 0x18,
368		.luma_control  = 0x40,
369		.chroma_ctrl1  = 0x81,
370		.chroma_gain   = 0x2a,
371		.chroma_ctrl2  = 0x06,
372		.vgate_misc    = 0x1c,
373	}
374};
375#define TVNORMS ARRAY_SIZE(tvnorms)
376
377#define V4L2_CID_PRIVATE_INVERT      (V4L2_CID_PRIVATE_BASE + 0)
378#define V4L2_CID_PRIVATE_Y_ODD       (V4L2_CID_PRIVATE_BASE + 1)
379#define V4L2_CID_PRIVATE_Y_EVEN      (V4L2_CID_PRIVATE_BASE + 2)
380#define V4L2_CID_PRIVATE_AUTOMUTE    (V4L2_CID_PRIVATE_BASE + 3)
381#define V4L2_CID_PRIVATE_LASTP1      (V4L2_CID_PRIVATE_BASE + 4)
382
383static const struct v4l2_queryctrl no_ctrl = {
384	.name  = "42",
385	.flags = V4L2_CTRL_FLAG_DISABLED,
386};
387static const struct v4l2_queryctrl video_ctrls[] = {
388	/* --- video --- */
389	{
390		.id            = V4L2_CID_BRIGHTNESS,
391		.name          = "Brightness",
392		.minimum       = 0,
393		.maximum       = 255,
394		.step          = 1,
395		.default_value = 128,
396		.type          = V4L2_CTRL_TYPE_INTEGER,
397	},{
398		.id            = V4L2_CID_CONTRAST,
399		.name          = "Contrast",
400		.minimum       = 0,
401		.maximum       = 127,
402		.step          = 1,
403		.default_value = 68,
404		.type          = V4L2_CTRL_TYPE_INTEGER,
405	},{
406		.id            = V4L2_CID_SATURATION,
407		.name          = "Saturation",
408		.minimum       = 0,
409		.maximum       = 127,
410		.step          = 1,
411		.default_value = 64,
412		.type          = V4L2_CTRL_TYPE_INTEGER,
413	},{
414		.id            = V4L2_CID_HUE,
415		.name          = "Hue",
416		.minimum       = -128,
417		.maximum       = 127,
418		.step          = 1,
419		.default_value = 0,
420		.type          = V4L2_CTRL_TYPE_INTEGER,
421	},{
422		.id            = V4L2_CID_HFLIP,
423		.name          = "Mirror",
424		.minimum       = 0,
425		.maximum       = 1,
426		.type          = V4L2_CTRL_TYPE_BOOLEAN,
427	},
428	/* --- audio --- */
429	{
430		.id            = V4L2_CID_AUDIO_MUTE,
431		.name          = "Mute",
432		.minimum       = 0,
433		.maximum       = 1,
434		.type          = V4L2_CTRL_TYPE_BOOLEAN,
435	},{
436		.id            = V4L2_CID_AUDIO_VOLUME,
437		.name          = "Volume",
438		.minimum       = -15,
439		.maximum       = 15,
440		.step          = 1,
441		.default_value = 0,
442		.type          = V4L2_CTRL_TYPE_INTEGER,
443	},
444	/* --- private --- */
445	{
446		.id            = V4L2_CID_PRIVATE_INVERT,
447		.name          = "Invert",
448		.minimum       = 0,
449		.maximum       = 1,
450		.type          = V4L2_CTRL_TYPE_BOOLEAN,
451	},{
452		.id            = V4L2_CID_PRIVATE_Y_ODD,
453		.name          = "y offset odd field",
454		.minimum       = 0,
455		.maximum       = 128,
456		.default_value = 0,
457		.type          = V4L2_CTRL_TYPE_INTEGER,
458	},{
459		.id            = V4L2_CID_PRIVATE_Y_EVEN,
460		.name          = "y offset even field",
461		.minimum       = 0,
462		.maximum       = 128,
463		.default_value = 0,
464		.type          = V4L2_CTRL_TYPE_INTEGER,
465	},{
466		.id            = V4L2_CID_PRIVATE_AUTOMUTE,
467		.name          = "automute",
468		.minimum       = 0,
469		.maximum       = 1,
470		.default_value = 1,
471		.type          = V4L2_CTRL_TYPE_BOOLEAN,
472	}
473};
474static const unsigned int CTRLS = ARRAY_SIZE(video_ctrls);
475
476static const struct v4l2_queryctrl* ctrl_by_id(unsigned int id)
477{
478	unsigned int i;
479
480	for (i = 0; i < CTRLS; i++)
481		if (video_ctrls[i].id == id)
482			return video_ctrls+i;
483	return NULL;
484}
485
486static struct saa7134_format* format_by_fourcc(unsigned int fourcc)
487{
488	unsigned int i;
489
490	for (i = 0; i < FORMATS; i++)
491		if (formats[i].fourcc == fourcc)
492			return formats+i;
493	return NULL;
494}
495
496/* ----------------------------------------------------------------------- */
497/* resource management                                                     */
498
499static int res_get(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bit)
500{
501	if (fh->resources & bit)
502		/* have it already allocated */
503		return 1;
504
505	/* is it free? */
506	mutex_lock(&dev->lock);
507	if (dev->resources & bit) {
508		/* no, someone else uses it */
509		mutex_unlock(&dev->lock);
510		return 0;
511	}
512	/* it's free, grab it */
513	fh->resources  |= bit;
514	dev->resources |= bit;
515	dprintk("res: get %d\n",bit);
516	mutex_unlock(&dev->lock);
517	return 1;
518}
519
520static int res_check(struct saa7134_fh *fh, unsigned int bit)
521{
522	return (fh->resources & bit);
523}
524
525static int res_locked(struct saa7134_dev *dev, unsigned int bit)
526{
527	return (dev->resources & bit);
528}
529
530static
531void res_free(struct saa7134_dev *dev, struct saa7134_fh *fh, unsigned int bits)
532{
533	BUG_ON((fh->resources & bits) != bits);
534
535	mutex_lock(&dev->lock);
536	fh->resources  &= ~bits;
537	dev->resources &= ~bits;
538	dprintk("res: put %d\n",bits);
539	mutex_unlock(&dev->lock);
540}
541
542/* ------------------------------------------------------------------ */
543
544static void set_tvnorm(struct saa7134_dev *dev, struct saa7134_tvnorm *norm)
545{
546	int luma_control,sync_control,mux;
547
548	dprintk("set tv norm = %s\n",norm->name);
549	dev->tvnorm = norm;
550
551	mux = card_in(dev,dev->ctl_input).vmux;
552	luma_control = norm->luma_control;
553	sync_control = norm->sync_control;
554
555	if (mux > 5)
556		luma_control |= 0x80; /* svideo */
557	if (noninterlaced || dev->nosignal)
558		sync_control |= 0x20;
559
560	/* setup cropping */
561	dev->crop_bounds.left    = norm->h_start;
562	dev->crop_defrect.left   = norm->h_start;
563	dev->crop_bounds.width   = norm->h_stop - norm->h_start +1;
564	dev->crop_defrect.width  = norm->h_stop - norm->h_start +1;
565
566	dev->crop_bounds.top     = (norm->vbi_v_stop_0+1)*2;
567	dev->crop_defrect.top    = norm->video_v_start*2;
568	dev->crop_bounds.height  = ((norm->id & V4L2_STD_525_60) ? 524 : 624)
569		- dev->crop_bounds.top;
570	dev->crop_defrect.height = (norm->video_v_stop - norm->video_v_start +1)*2;
571
572	dev->crop_current = dev->crop_defrect;
573
574	/* setup video decoder */
575	saa_writeb(SAA7134_INCR_DELAY,            0x08);
576	saa_writeb(SAA7134_ANALOG_IN_CTRL1,       0xc0 | mux);
577	saa_writeb(SAA7134_ANALOG_IN_CTRL2,       0x00);
578
579	saa_writeb(SAA7134_ANALOG_IN_CTRL3,       0x90);
580	saa_writeb(SAA7134_ANALOG_IN_CTRL4,       0x90);
581	saa_writeb(SAA7134_HSYNC_START,           0xeb);
582	saa_writeb(SAA7134_HSYNC_STOP,            0xe0);
583	saa_writeb(SAA7134_SOURCE_TIMING1,        norm->src_timing);
584
585	saa_writeb(SAA7134_SYNC_CTRL,             sync_control);
586	saa_writeb(SAA7134_LUMA_CTRL,             luma_control);
587	saa_writeb(SAA7134_DEC_LUMA_BRIGHT,       dev->ctl_bright);
588	saa_writeb(SAA7134_DEC_LUMA_CONTRAST,     dev->ctl_contrast);
589
590	saa_writeb(SAA7134_DEC_CHROMA_SATURATION, dev->ctl_saturation);
591	saa_writeb(SAA7134_DEC_CHROMA_HUE,        dev->ctl_hue);
592	saa_writeb(SAA7134_CHROMA_CTRL1,          norm->chroma_ctrl1);
593	saa_writeb(SAA7134_CHROMA_GAIN,           norm->chroma_gain);
594
595	saa_writeb(SAA7134_CHROMA_CTRL2,          norm->chroma_ctrl2);
596	saa_writeb(SAA7134_MODE_DELAY_CTRL,       0x00);
597
598	saa_writeb(SAA7134_ANALOG_ADC,            0x01);
599	saa_writeb(SAA7134_VGATE_START,           0x11);
600	saa_writeb(SAA7134_VGATE_STOP,            0xfe);
601	saa_writeb(SAA7134_MISC_VGATE_MSB,        norm->vgate_misc);
602	saa_writeb(SAA7134_RAW_DATA_GAIN,         0x40);
603	saa_writeb(SAA7134_RAW_DATA_OFFSET,       0x80);
604
605	/* only tell the tuner if this is a tv input */
606	if (card_in(dev,dev->ctl_input).tv) {
607		if ((card(dev).tuner_type == TUNER_PHILIPS_TDA8290)
608				&& ((card(dev).tuner_config == 1)
609				||  (card(dev).tuner_config == 2)))
610			saa7134_set_gpio(dev, 22, 5);
611		saa7134_i2c_call_clients(dev,VIDIOC_S_STD,&norm->id);
612	}
613}
614
615static void video_mux(struct saa7134_dev *dev, int input)
616{
617	dprintk("video input = %d [%s]\n",input,card_in(dev,input).name);
618	dev->ctl_input = input;
619	set_tvnorm(dev,dev->tvnorm);
620	saa7134_tvaudio_setinput(dev,&card_in(dev,input));
621}
622
623static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale)
624{
625	static const struct {
626		int xpsc;
627		int xacl;
628		int xc2_1;
629		int xdcg;
630		int vpfy;
631	} vals[] = {
632		/* XPSC XACL XC2_1 XDCG VPFY */
633		{    1,   0,    0,    0,   0 },
634		{    2,   2,    1,    2,   2 },
635		{    3,   4,    1,    3,   2 },
636		{    4,   8,    1,    4,   2 },
637		{    5,   8,    1,    4,   2 },
638		{    6,   8,    1,    4,   3 },
639		{    7,   8,    1,    4,   3 },
640		{    8,  15,    0,    4,   3 },
641		{    9,  15,    0,    4,   3 },
642		{   10,  16,    1,    5,   3 },
643	};
644	static const int count = ARRAY_SIZE(vals);
645	int i;
646
647	for (i = 0; i < count; i++)
648		if (vals[i].xpsc == prescale)
649			break;
650	if (i == count)
651		return;
652
653	saa_writeb(SAA7134_H_PRESCALE(task), vals[i].xpsc);
654	saa_writeb(SAA7134_ACC_LENGTH(task), vals[i].xacl);
655	saa_writeb(SAA7134_LEVEL_CTRL(task),
656		   (vals[i].xc2_1 << 3) | (vals[i].xdcg));
657	saa_andorb(SAA7134_FIR_PREFILTER_CTRL(task), 0x0f,
658		   (vals[i].vpfy << 2) | vals[i].vpfy);
659}
660
661static void set_v_scale(struct saa7134_dev *dev, int task, int yscale)
662{
663	int val,mirror;
664
665	saa_writeb(SAA7134_V_SCALE_RATIO1(task), yscale &  0xff);
666	saa_writeb(SAA7134_V_SCALE_RATIO2(task), yscale >> 8);
667
668	mirror = (dev->ctl_mirror) ? 0x02 : 0x00;
669	if (yscale < 2048) {
670		/* LPI */
671		dprintk("yscale LPI yscale=%d\n",yscale);
672		saa_writeb(SAA7134_V_FILTER(task), 0x00 | mirror);
673		saa_writeb(SAA7134_LUMA_CONTRAST(task), 0x40);
674		saa_writeb(SAA7134_CHROMA_SATURATION(task), 0x40);
675	} else {
676		/* ACM */
677		val = 0x40 * 1024 / yscale;
678		dprintk("yscale ACM yscale=%d val=0x%x\n",yscale,val);
679		saa_writeb(SAA7134_V_FILTER(task), 0x01 | mirror);
680		saa_writeb(SAA7134_LUMA_CONTRAST(task), val);
681		saa_writeb(SAA7134_CHROMA_SATURATION(task), val);
682	}
683	saa_writeb(SAA7134_LUMA_BRIGHT(task),       0x80);
684}
685
686static void set_size(struct saa7134_dev *dev, int task,
687		     int width, int height, int interlace)
688{
689	int prescale,xscale,yscale,y_even,y_odd;
690	int h_start, h_stop, v_start, v_stop;
691	int div = interlace ? 2 : 1;
692
693	/* setup video scaler */
694	h_start = dev->crop_current.left;
695	v_start = dev->crop_current.top/2;
696	h_stop  = (dev->crop_current.left + dev->crop_current.width -1);
697	v_stop  = (dev->crop_current.top + dev->crop_current.height -1)/2;
698
699	saa_writeb(SAA7134_VIDEO_H_START1(task), h_start &  0xff);
700	saa_writeb(SAA7134_VIDEO_H_START2(task), h_start >> 8);
701	saa_writeb(SAA7134_VIDEO_H_STOP1(task),  h_stop  &  0xff);
702	saa_writeb(SAA7134_VIDEO_H_STOP2(task),  h_stop  >> 8);
703	saa_writeb(SAA7134_VIDEO_V_START1(task), v_start &  0xff);
704	saa_writeb(SAA7134_VIDEO_V_START2(task), v_start >> 8);
705	saa_writeb(SAA7134_VIDEO_V_STOP1(task),  v_stop  &  0xff);
706	saa_writeb(SAA7134_VIDEO_V_STOP2(task),  v_stop  >> 8);
707
708	prescale = dev->crop_current.width / width;
709	if (0 == prescale)
710		prescale = 1;
711	xscale = 1024 * dev->crop_current.width / prescale / width;
712	yscale = 512 * div * dev->crop_current.height / height;
713	dprintk("prescale=%d xscale=%d yscale=%d\n",prescale,xscale,yscale);
714	set_h_prescale(dev,task,prescale);
715	saa_writeb(SAA7134_H_SCALE_INC1(task),      xscale &  0xff);
716	saa_writeb(SAA7134_H_SCALE_INC2(task),      xscale >> 8);
717	set_v_scale(dev,task,yscale);
718
719	saa_writeb(SAA7134_VIDEO_PIXELS1(task),     width  & 0xff);
720	saa_writeb(SAA7134_VIDEO_PIXELS2(task),     width  >> 8);
721	saa_writeb(SAA7134_VIDEO_LINES1(task),      height/div & 0xff);
722	saa_writeb(SAA7134_VIDEO_LINES2(task),      height/div >> 8);
723
724	/* deinterlace y offsets */
725	y_odd  = dev->ctl_y_odd;
726	y_even = dev->ctl_y_even;
727	saa_writeb(SAA7134_V_PHASE_OFFSET0(task), y_odd);
728	saa_writeb(SAA7134_V_PHASE_OFFSET1(task), y_even);
729	saa_writeb(SAA7134_V_PHASE_OFFSET2(task), y_odd);
730	saa_writeb(SAA7134_V_PHASE_OFFSET3(task), y_even);
731}
732
733/* ------------------------------------------------------------------ */
734
735struct cliplist {
736	__u16 position;
737	__u8  enable;
738	__u8  disable;
739};
740
741static void set_cliplist(struct saa7134_dev *dev, int reg,
742			struct cliplist *cl, int entries, char *name)
743{
744	__u8 winbits = 0;
745	int i;
746
747	for (i = 0; i < entries; i++) {
748		winbits |= cl[i].enable;
749		winbits &= ~cl[i].disable;
750		if (i < 15 && cl[i].position == cl[i+1].position)
751			continue;
752		saa_writeb(reg + 0, winbits);
753		saa_writeb(reg + 2, cl[i].position & 0xff);
754		saa_writeb(reg + 3, cl[i].position >> 8);
755		dprintk("clip: %s winbits=%02x pos=%d\n",
756			name,winbits,cl[i].position);
757		reg += 8;
758	}
759	for (; reg < 0x400; reg += 8) {
760		saa_writeb(reg+ 0, 0);
761		saa_writeb(reg + 1, 0);
762		saa_writeb(reg + 2, 0);
763		saa_writeb(reg + 3, 0);
764	}
765}
766
767static int clip_range(int val)
768{
769	if (val < 0)
770		val = 0;
771	return val;
772}
773
774/* Sort into smallest position first order */
775static int cliplist_cmp(const void *a, const void *b)
776{
777	const struct cliplist *cla = a;
778	const struct cliplist *clb = b;
779	if (cla->position < clb->position)
780		return -1;
781	if (cla->position > clb->position)
782		return 1;
783	return 0;
784}
785
786static int setup_clipping(struct saa7134_dev *dev, struct v4l2_clip *clips,
787			  int nclips, int interlace)
788{
789	struct cliplist col[16], row[16];
790	int cols = 0, rows = 0, i;
791	int div = interlace ? 2 : 1;
792
793	memset(col, 0, sizeof(col));
794	memset(row, 0, sizeof(row));
795	for (i = 0; i < nclips && i < 8; i++) {
796		col[cols].position = clip_range(clips[i].c.left);
797		col[cols].enable   = (1 << i);
798		cols++;
799		col[cols].position = clip_range(clips[i].c.left+clips[i].c.width);
800		col[cols].disable  = (1 << i);
801		cols++;
802		row[rows].position = clip_range(clips[i].c.top / div);
803		row[rows].enable   = (1 << i);
804		rows++;
805		row[rows].position = clip_range((clips[i].c.top + clips[i].c.height)
806						/ div);
807		row[rows].disable  = (1 << i);
808		rows++;
809	}
810	sort(col, cols, sizeof col[0], cliplist_cmp, NULL);
811	sort(row, rows, sizeof row[0], cliplist_cmp, NULL);
812	set_cliplist(dev,0x380,col,cols,"cols");
813	set_cliplist(dev,0x384,row,rows,"rows");
814	return 0;
815}
816
817static int verify_preview(struct saa7134_dev *dev, struct v4l2_window *win)
818{
819	enum v4l2_field field;
820	int maxw, maxh;
821
822	if (NULL == dev->ovbuf.base)
823		return -EINVAL;
824	if (NULL == dev->ovfmt)
825		return -EINVAL;
826	if (win->w.width < 48 || win->w.height <  32)
827		return -EINVAL;
828	if (win->clipcount > 2048)
829		return -EINVAL;
830
831	field = win->field;
832	maxw  = dev->crop_current.width;
833	maxh  = dev->crop_current.height;
834
835	if (V4L2_FIELD_ANY == field) {
836		field = (win->w.height > maxh/2)
837			? V4L2_FIELD_INTERLACED
838			: V4L2_FIELD_TOP;
839	}
840	switch (field) {
841	case V4L2_FIELD_TOP:
842	case V4L2_FIELD_BOTTOM:
843		maxh = maxh / 2;
844		break;
845	case V4L2_FIELD_INTERLACED:
846		break;
847	default:
848		return -EINVAL;
849	}
850
851	win->field = field;
852	if (win->w.width > maxw)
853		win->w.width = maxw;
854	if (win->w.height > maxh)
855		win->w.height = maxh;
856	return 0;
857}
858
859static int start_preview(struct saa7134_dev *dev, struct saa7134_fh *fh)
860{
861	unsigned long base,control,bpl;
862	int err;
863
864	err = verify_preview(dev,&fh->win);
865	if (0 != err)
866		return err;
867
868	dev->ovfield = fh->win.field;
869	dprintk("start_preview %dx%d+%d+%d %s field=%s\n",
870		fh->win.w.width,fh->win.w.height,
871		fh->win.w.left,fh->win.w.top,
872		dev->ovfmt->name,v4l2_field_names[dev->ovfield]);
873
874	/* setup window + clipping */
875	set_size(dev,TASK_B,fh->win.w.width,fh->win.w.height,
876		 V4L2_FIELD_HAS_BOTH(dev->ovfield));
877	setup_clipping(dev,fh->clips,fh->nclips,
878		       V4L2_FIELD_HAS_BOTH(dev->ovfield));
879	if (dev->ovfmt->yuv)
880		saa_andorb(SAA7134_DATA_PATH(TASK_B), 0x3f, 0x03);
881	else
882		saa_andorb(SAA7134_DATA_PATH(TASK_B), 0x3f, 0x01);
883	saa_writeb(SAA7134_OFMT_VIDEO_B, dev->ovfmt->pm | 0x20);
884
885	/* dma: setup channel 1 (= Video Task B) */
886	base  = (unsigned long)dev->ovbuf.base;
887	base += dev->ovbuf.fmt.bytesperline * fh->win.w.top;
888	base += dev->ovfmt->depth/8         * fh->win.w.left;
889	bpl   = dev->ovbuf.fmt.bytesperline;
890	control = SAA7134_RS_CONTROL_BURST_16;
891	if (dev->ovfmt->bswap)
892		control |= SAA7134_RS_CONTROL_BSWAP;
893	if (dev->ovfmt->wswap)
894		control |= SAA7134_RS_CONTROL_WSWAP;
895	if (V4L2_FIELD_HAS_BOTH(dev->ovfield)) {
896		saa_writel(SAA7134_RS_BA1(1),base);
897		saa_writel(SAA7134_RS_BA2(1),base+bpl);
898		saa_writel(SAA7134_RS_PITCH(1),bpl*2);
899		saa_writel(SAA7134_RS_CONTROL(1),control);
900	} else {
901		saa_writel(SAA7134_RS_BA1(1),base);
902		saa_writel(SAA7134_RS_BA2(1),base);
903		saa_writel(SAA7134_RS_PITCH(1),bpl);
904		saa_writel(SAA7134_RS_CONTROL(1),control);
905	}
906
907	/* start dma */
908	dev->ovenable = 1;
909	saa7134_set_dmabits(dev);
910
911	return 0;
912}
913
914static int stop_preview(struct saa7134_dev *dev, struct saa7134_fh *fh)
915{
916	dev->ovenable = 0;
917	saa7134_set_dmabits(dev);
918	return 0;
919}
920
921/* ------------------------------------------------------------------ */
922
923static int buffer_activate(struct saa7134_dev *dev,
924			   struct saa7134_buf *buf,
925			   struct saa7134_buf *next)
926{
927	unsigned long base,control,bpl;
928	unsigned long bpl_uv,lines_uv,base2,base3,tmp; /* planar */
929
930	dprintk("buffer_activate buf=%p\n",buf);
931	buf->vb.state = STATE_ACTIVE;
932	buf->top_seen = 0;
933
934	set_size(dev,TASK_A,buf->vb.width,buf->vb.height,
935		 V4L2_FIELD_HAS_BOTH(buf->vb.field));
936	if (buf->fmt->yuv)
937		saa_andorb(SAA7134_DATA_PATH(TASK_A), 0x3f, 0x03);
938	else
939		saa_andorb(SAA7134_DATA_PATH(TASK_A), 0x3f, 0x01);
940	saa_writeb(SAA7134_OFMT_VIDEO_A, buf->fmt->pm);
941
942	/* DMA: setup channel 0 (= Video Task A0) */
943	base  = saa7134_buffer_base(buf);
944	if (buf->fmt->planar)
945		bpl = buf->vb.width;
946	else
947		bpl = (buf->vb.width * buf->fmt->depth) / 8;
948	control = SAA7134_RS_CONTROL_BURST_16 |
949		SAA7134_RS_CONTROL_ME |
950		(buf->pt->dma >> 12);
951	if (buf->fmt->bswap)
952		control |= SAA7134_RS_CONTROL_BSWAP;
953	if (buf->fmt->wswap)
954		control |= SAA7134_RS_CONTROL_WSWAP;
955	if (V4L2_FIELD_HAS_BOTH(buf->vb.field)) {
956		/* interlaced */
957		saa_writel(SAA7134_RS_BA1(0),base);
958		saa_writel(SAA7134_RS_BA2(0),base+bpl);
959		saa_writel(SAA7134_RS_PITCH(0),bpl*2);
960	} else {
961		/* non-interlaced */
962		saa_writel(SAA7134_RS_BA1(0),base);
963		saa_writel(SAA7134_RS_BA2(0),base);
964		saa_writel(SAA7134_RS_PITCH(0),bpl);
965	}
966	saa_writel(SAA7134_RS_CONTROL(0),control);
967
968	if (buf->fmt->planar) {
969		/* DMA: setup channel 4+5 (= planar task A) */
970		bpl_uv   = bpl >> buf->fmt->hshift;
971		lines_uv = buf->vb.height >> buf->fmt->vshift;
972		base2    = base + bpl * buf->vb.height;
973		base3    = base2 + bpl_uv * lines_uv;
974		if (buf->fmt->uvswap)
975			tmp = base2, base2 = base3, base3 = tmp;
976		dprintk("uv: bpl=%ld lines=%ld base2/3=%ld/%ld\n",
977			bpl_uv,lines_uv,base2,base3);
978		if (V4L2_FIELD_HAS_BOTH(buf->vb.field)) {
979			/* interlaced */
980			saa_writel(SAA7134_RS_BA1(4),base2);
981			saa_writel(SAA7134_RS_BA2(4),base2+bpl_uv);
982			saa_writel(SAA7134_RS_PITCH(4),bpl_uv*2);
983			saa_writel(SAA7134_RS_BA1(5),base3);
984			saa_writel(SAA7134_RS_BA2(5),base3+bpl_uv);
985			saa_writel(SAA7134_RS_PITCH(5),bpl_uv*2);
986		} else {
987			/* non-interlaced */
988			saa_writel(SAA7134_RS_BA1(4),base2);
989			saa_writel(SAA7134_RS_BA2(4),base2);
990			saa_writel(SAA7134_RS_PITCH(4),bpl_uv);
991			saa_writel(SAA7134_RS_BA1(5),base3);
992			saa_writel(SAA7134_RS_BA2(5),base3);
993			saa_writel(SAA7134_RS_PITCH(5),bpl_uv);
994		}
995		saa_writel(SAA7134_RS_CONTROL(4),control);
996		saa_writel(SAA7134_RS_CONTROL(5),control);
997	}
998
999	/* start DMA */
1000	saa7134_set_dmabits(dev);
1001	mod_timer(&dev->video_q.timeout, jiffies+BUFFER_TIMEOUT);
1002	return 0;
1003}
1004
1005static int buffer_prepare(struct videobuf_queue *q,
1006			  struct videobuf_buffer *vb,
1007			  enum v4l2_field field)
1008{
1009	struct saa7134_fh *fh = q->priv_data;
1010	struct saa7134_dev *dev = fh->dev;
1011	struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
1012	unsigned int size;
1013	int err;
1014
1015	/* sanity checks */
1016	if (NULL == fh->fmt)
1017		return -EINVAL;
1018	if (fh->width    < 48 ||
1019	    fh->height   < 32 ||
1020	    fh->width/4  > dev->crop_current.width  ||
1021	    fh->height/4 > dev->crop_current.height ||
1022	    fh->width    > dev->crop_bounds.width  ||
1023	    fh->height   > dev->crop_bounds.height)
1024		return -EINVAL;
1025	size = (fh->width * fh->height * fh->fmt->depth) >> 3;
1026	if (0 != buf->vb.baddr  &&  buf->vb.bsize < size)
1027		return -EINVAL;
1028
1029	dprintk("buffer_prepare [%d,size=%dx%d,bytes=%d,fields=%s,%s]\n",
1030		vb->i,fh->width,fh->height,size,v4l2_field_names[field],
1031		fh->fmt->name);
1032	if (buf->vb.width  != fh->width  ||
1033	    buf->vb.height != fh->height ||
1034	    buf->vb.size   != size       ||
1035	    buf->vb.field  != field      ||
1036	    buf->fmt       != fh->fmt) {
1037		saa7134_dma_free(q,buf);
1038	}
1039
1040	if (STATE_NEEDS_INIT == buf->vb.state) {
1041		buf->vb.width  = fh->width;
1042		buf->vb.height = fh->height;
1043		buf->vb.size   = size;
1044		buf->vb.field  = field;
1045		buf->fmt       = fh->fmt;
1046		buf->pt        = &fh->pt_cap;
1047
1048		err = videobuf_iolock(q,&buf->vb,&dev->ovbuf);
1049		if (err)
1050			goto oops;
1051		err = saa7134_pgtable_build(dev->pci,buf->pt,
1052					    buf->vb.dma.sglist,
1053					    buf->vb.dma.sglen,
1054					    saa7134_buffer_startpage(buf));
1055		if (err)
1056			goto oops;
1057	}
1058	buf->vb.state = STATE_PREPARED;
1059	buf->activate = buffer_activate;
1060	return 0;
1061
1062 oops:
1063	saa7134_dma_free(q,buf);
1064	return err;
1065}
1066
1067static int
1068buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
1069{
1070	struct saa7134_fh *fh = q->priv_data;
1071
1072	*size = fh->fmt->depth * fh->width * fh->height >> 3;
1073	if (0 == *count)
1074		*count = gbuffers;
1075	*count = saa7134_buffer_count(*size,*count);
1076	return 0;
1077}
1078
1079static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
1080{
1081	struct saa7134_fh *fh = q->priv_data;
1082	struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
1083
1084	saa7134_buffer_queue(fh->dev,&fh->dev->video_q,buf);
1085}
1086
1087static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
1088{
1089	struct saa7134_buf *buf = container_of(vb,struct saa7134_buf,vb);
1090
1091	saa7134_dma_free(q,buf);
1092}
1093
1094static struct videobuf_queue_ops video_qops = {
1095	.buf_setup    = buffer_setup,
1096	.buf_prepare  = buffer_prepare,
1097	.buf_queue    = buffer_queue,
1098	.buf_release  = buffer_release,
1099};
1100
1101/* ------------------------------------------------------------------ */
1102
1103static int get_control(struct saa7134_dev *dev, struct v4l2_control *c)
1104{
1105	const struct v4l2_queryctrl* ctrl;
1106
1107	ctrl = ctrl_by_id(c->id);
1108	if (NULL == ctrl)
1109		return -EINVAL;
1110	switch (c->id) {
1111	case V4L2_CID_BRIGHTNESS:
1112		c->value = dev->ctl_bright;
1113		break;
1114	case V4L2_CID_HUE:
1115		c->value = dev->ctl_hue;
1116		break;
1117	case V4L2_CID_CONTRAST:
1118		c->value = dev->ctl_contrast;
1119		break;
1120	case V4L2_CID_SATURATION:
1121		c->value = dev->ctl_saturation;
1122		break;
1123	case V4L2_CID_AUDIO_MUTE:
1124		c->value = dev->ctl_mute;
1125		break;
1126	case V4L2_CID_AUDIO_VOLUME:
1127		c->value = dev->ctl_volume;
1128		break;
1129	case V4L2_CID_PRIVATE_INVERT:
1130		c->value = dev->ctl_invert;
1131		break;
1132	case V4L2_CID_HFLIP:
1133		c->value = dev->ctl_mirror;
1134		break;
1135	case V4L2_CID_PRIVATE_Y_EVEN:
1136		c->value = dev->ctl_y_even;
1137		break;
1138	case V4L2_CID_PRIVATE_Y_ODD:
1139		c->value = dev->ctl_y_odd;
1140		break;
1141	case V4L2_CID_PRIVATE_AUTOMUTE:
1142		c->value = dev->ctl_automute;
1143		break;
1144	default:
1145		return -EINVAL;
1146	}
1147	return 0;
1148}
1149
1150static int set_control(struct saa7134_dev *dev, struct saa7134_fh *fh,
1151		       struct v4l2_control *c)
1152{
1153	const struct v4l2_queryctrl* ctrl;
1154	unsigned long flags;
1155	int restart_overlay = 0;
1156
1157	ctrl = ctrl_by_id(c->id);
1158	if (NULL == ctrl)
1159		return -EINVAL;
1160	dprintk("set_control name=%s val=%d\n",ctrl->name,c->value);
1161	switch (ctrl->type) {
1162	case V4L2_CTRL_TYPE_BOOLEAN:
1163	case V4L2_CTRL_TYPE_MENU:
1164	case V4L2_CTRL_TYPE_INTEGER:
1165		if (c->value < ctrl->minimum)
1166			c->value = ctrl->minimum;
1167		if (c->value > ctrl->maximum)
1168			c->value = ctrl->maximum;
1169		break;
1170	default:
1171		/* nothing */;
1172	};
1173	switch (c->id) {
1174	case V4L2_CID_BRIGHTNESS:
1175		dev->ctl_bright = c->value;
1176		saa_writeb(SAA7134_DEC_LUMA_BRIGHT, dev->ctl_bright);
1177		break;
1178	case V4L2_CID_HUE:
1179		dev->ctl_hue = c->value;
1180		saa_writeb(SAA7134_DEC_CHROMA_HUE, dev->ctl_hue);
1181		break;
1182	case V4L2_CID_CONTRAST:
1183		dev->ctl_contrast = c->value;
1184		saa_writeb(SAA7134_DEC_LUMA_CONTRAST,
1185			   dev->ctl_invert ? -dev->ctl_contrast : dev->ctl_contrast);
1186		break;
1187	case V4L2_CID_SATURATION:
1188		dev->ctl_saturation = c->value;
1189		saa_writeb(SAA7134_DEC_CHROMA_SATURATION,
1190			   dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation);
1191		break;
1192	case V4L2_CID_AUDIO_MUTE:
1193		dev->ctl_mute = c->value;
1194		saa7134_tvaudio_setmute(dev);
1195		break;
1196	case V4L2_CID_AUDIO_VOLUME:
1197		dev->ctl_volume = c->value;
1198		saa7134_tvaudio_setvolume(dev,dev->ctl_volume);
1199		break;
1200	case V4L2_CID_PRIVATE_INVERT:
1201		dev->ctl_invert = c->value;
1202		saa_writeb(SAA7134_DEC_LUMA_CONTRAST,
1203			   dev->ctl_invert ? -dev->ctl_contrast : dev->ctl_contrast);
1204		saa_writeb(SAA7134_DEC_CHROMA_SATURATION,
1205			   dev->ctl_invert ? -dev->ctl_saturation : dev->ctl_saturation);
1206		break;
1207	case V4L2_CID_HFLIP:
1208		dev->ctl_mirror = c->value;
1209		restart_overlay = 1;
1210		break;
1211	case V4L2_CID_PRIVATE_Y_EVEN:
1212		dev->ctl_y_even = c->value;
1213		restart_overlay = 1;
1214		break;
1215	case V4L2_CID_PRIVATE_Y_ODD:
1216		dev->ctl_y_odd = c->value;
1217		restart_overlay = 1;
1218		break;
1219	case V4L2_CID_PRIVATE_AUTOMUTE:
1220		dev->ctl_automute = c->value;
1221		if (dev->tda9887_conf) {
1222			if (dev->ctl_automute)
1223				dev->tda9887_conf |= TDA9887_AUTOMUTE;
1224			else
1225				dev->tda9887_conf &= ~TDA9887_AUTOMUTE;
1226			saa7134_i2c_call_clients(dev, TDA9887_SET_CONFIG,
1227						 &dev->tda9887_conf);
1228		}
1229		break;
1230	default:
1231		return -EINVAL;
1232	}
1233	if (restart_overlay && fh && res_check(fh, RESOURCE_OVERLAY)) {
1234		spin_lock_irqsave(&dev->slock,flags);
1235		stop_preview(dev,fh);
1236		start_preview(dev,fh);
1237		spin_unlock_irqrestore(&dev->slock,flags);
1238	}
1239	return 0;
1240}
1241
1242/* ------------------------------------------------------------------ */
1243
1244static struct videobuf_queue* saa7134_queue(struct saa7134_fh *fh)
1245{
1246	struct videobuf_queue* q = NULL;
1247
1248	switch (fh->type) {
1249	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1250		q = &fh->cap;
1251		break;
1252	case V4L2_BUF_TYPE_VBI_CAPTURE:
1253		q = &fh->vbi;
1254		break;
1255	default:
1256		BUG();
1257	}
1258	return q;
1259}
1260
1261static int saa7134_resource(struct saa7134_fh *fh)
1262{
1263	if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1264		return RESOURCE_VIDEO;
1265
1266	if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
1267		return RESOURCE_VBI;
1268
1269	BUG();
1270	return 0;
1271}
1272
1273static int video_open(struct inode *inode, struct file *file)
1274{
1275	int minor = iminor(inode);
1276	struct saa7134_dev *h,*dev = NULL;
1277	struct saa7134_fh *fh;
1278	struct list_head *list;
1279	enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1280	int radio = 0;
1281	list_for_each(list,&saa7134_devlist) {
1282		h = list_entry(list, struct saa7134_dev, devlist);
1283		if (h->video_dev && (h->video_dev->minor == minor))
1284			dev = h;
1285		if (h->radio_dev && (h->radio_dev->minor == minor)) {
1286			radio = 1;
1287			dev = h;
1288		}
1289		if (h->vbi_dev && (h->vbi_dev->minor == minor)) {
1290			type = V4L2_BUF_TYPE_VBI_CAPTURE;
1291			dev = h;
1292		}
1293	}
1294	if (NULL == dev)
1295		return -ENODEV;
1296
1297	dprintk("open minor=%d radio=%d type=%s\n",minor,radio,
1298		v4l2_type_names[type]);
1299
1300	/* allocate + initialize per filehandle data */
1301	fh = kzalloc(sizeof(*fh),GFP_KERNEL);
1302	if (NULL == fh)
1303		return -ENOMEM;
1304	file->private_data = fh;
1305	fh->dev      = dev;
1306	fh->radio    = radio;
1307	fh->type     = type;
1308	fh->fmt      = format_by_fourcc(V4L2_PIX_FMT_BGR24);
1309	fh->width    = 720;
1310	fh->height   = 576;
1311	v4l2_prio_open(&dev->prio,&fh->prio);
1312
1313	videobuf_queue_init(&fh->cap, &video_qops,
1314			    dev->pci, &dev->slock,
1315			    V4L2_BUF_TYPE_VIDEO_CAPTURE,
1316			    V4L2_FIELD_INTERLACED,
1317			    sizeof(struct saa7134_buf),
1318			    fh);
1319	videobuf_queue_init(&fh->vbi, &saa7134_vbi_qops,
1320			    dev->pci, &dev->slock,
1321			    V4L2_BUF_TYPE_VBI_CAPTURE,
1322			    V4L2_FIELD_SEQ_TB,
1323			    sizeof(struct saa7134_buf),
1324			    fh);
1325	saa7134_pgtable_alloc(dev->pci,&fh->pt_cap);
1326	saa7134_pgtable_alloc(dev->pci,&fh->pt_vbi);
1327
1328	if (fh->radio) {
1329		/* switch to radio mode */
1330		saa7134_tvaudio_setinput(dev,&card(dev).radio);
1331		saa7134_i2c_call_clients(dev,AUDC_SET_RADIO, NULL);
1332	} else {
1333		/* switch to video/vbi mode */
1334		video_mux(dev,dev->ctl_input);
1335	}
1336	return 0;
1337}
1338
1339static ssize_t
1340video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
1341{
1342	struct saa7134_fh *fh = file->private_data;
1343
1344	switch (fh->type) {
1345	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1346		if (res_locked(fh->dev,RESOURCE_VIDEO))
1347			return -EBUSY;
1348		return videobuf_read_one(saa7134_queue(fh),
1349					 data, count, ppos,
1350					 file->f_flags & O_NONBLOCK);
1351	case V4L2_BUF_TYPE_VBI_CAPTURE:
1352		if (!res_get(fh->dev,fh,RESOURCE_VBI))
1353			return -EBUSY;
1354		return videobuf_read_stream(saa7134_queue(fh),
1355					    data, count, ppos, 1,
1356					    file->f_flags & O_NONBLOCK);
1357		break;
1358	default:
1359		BUG();
1360		return 0;
1361	}
1362}
1363
1364static unsigned int
1365video_poll(struct file *file, struct poll_table_struct *wait)
1366{
1367	struct saa7134_fh *fh = file->private_data;
1368	struct videobuf_buffer *buf = NULL;
1369
1370	if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)
1371		return videobuf_poll_stream(file, &fh->vbi, wait);
1372
1373	if (res_check(fh,RESOURCE_VIDEO)) {
1374		if (!list_empty(&fh->cap.stream))
1375			buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream);
1376	} else {
1377		mutex_lock(&fh->cap.lock);
1378		if (UNSET == fh->cap.read_off) {
1379			/* need to capture a new frame */
1380			if (res_locked(fh->dev,RESOURCE_VIDEO)) {
1381				mutex_unlock(&fh->cap.lock);
1382				return POLLERR;
1383			}
1384			if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,fh->cap.field)) {
1385				mutex_unlock(&fh->cap.lock);
1386				return POLLERR;
1387			}
1388			fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
1389			fh->cap.read_off = 0;
1390		}
1391		mutex_unlock(&fh->cap.lock);
1392		buf = fh->cap.read_buf;
1393	}
1394
1395	if (!buf)
1396		return POLLERR;
1397
1398	poll_wait(file, &buf->done, wait);
1399	if (buf->state == STATE_DONE ||
1400	    buf->state == STATE_ERROR)
1401		return POLLIN|POLLRDNORM;
1402	return 0;
1403}
1404
1405static int video_release(struct inode *inode, struct file *file)
1406{
1407	struct saa7134_fh  *fh  = file->private_data;
1408	struct saa7134_dev *dev = fh->dev;
1409	unsigned long flags;
1410
1411	/* turn off overlay */
1412	if (res_check(fh, RESOURCE_OVERLAY)) {
1413		spin_lock_irqsave(&dev->slock,flags);
1414		stop_preview(dev,fh);
1415		spin_unlock_irqrestore(&dev->slock,flags);
1416		res_free(dev,fh,RESOURCE_OVERLAY);
1417	}
1418
1419	/* stop video capture */
1420	if (res_check(fh, RESOURCE_VIDEO)) {
1421		videobuf_streamoff(&fh->cap);
1422		res_free(dev,fh,RESOURCE_VIDEO);
1423	}
1424	if (fh->cap.read_buf) {
1425		buffer_release(&fh->cap,fh->cap.read_buf);
1426		kfree(fh->cap.read_buf);
1427	}
1428
1429	/* stop vbi capture */
1430	if (res_check(fh, RESOURCE_VBI)) {
1431		if (fh->vbi.streaming)
1432			videobuf_streamoff(&fh->vbi);
1433		if (fh->vbi.reading)
1434			videobuf_read_stop(&fh->vbi);
1435		res_free(dev,fh,RESOURCE_VBI);
1436	}
1437
1438	/* ts-capture will not work in planar mode, so turn it off Hac: 04.05*/
1439	saa_andorb(SAA7134_OFMT_VIDEO_A, 0x1f, 0);
1440	saa_andorb(SAA7134_OFMT_VIDEO_B, 0x1f, 0);
1441	saa_andorb(SAA7134_OFMT_DATA_A, 0x1f, 0);
1442	saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0);
1443
1444	saa7134_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
1445
1446	/* free stuff */
1447	videobuf_mmap_free(&fh->cap);
1448	videobuf_mmap_free(&fh->vbi);
1449	saa7134_pgtable_free(dev->pci,&fh->pt_cap);
1450	saa7134_pgtable_free(dev->pci,&fh->pt_vbi);
1451
1452	v4l2_prio_close(&dev->prio,&fh->prio);
1453	file->private_data = NULL;
1454	kfree(fh);
1455	return 0;
1456}
1457
1458static int video_mmap(struct file *file, struct vm_area_struct * vma)
1459{
1460	struct saa7134_fh *fh = file->private_data;
1461
1462	return videobuf_mmap_mapper(saa7134_queue(fh), vma);
1463}
1464
1465/* ------------------------------------------------------------------ */
1466
1467static void saa7134_vbi_fmt(struct saa7134_dev *dev, struct v4l2_format *f)
1468{
1469	struct saa7134_tvnorm *norm = dev->tvnorm;
1470
1471	f->fmt.vbi.sampling_rate = 6750000 * 4;
1472	f->fmt.vbi.samples_per_line = 2048 /* VBI_LINE_LENGTH */;
1473	f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
1474	f->fmt.vbi.offset = 64 * 4;
1475	f->fmt.vbi.start[0] = norm->vbi_v_start_0;
1476	f->fmt.vbi.count[0] = norm->vbi_v_stop_0 - norm->vbi_v_start_0 +1;
1477	f->fmt.vbi.start[1] = norm->vbi_v_start_1;
1478	f->fmt.vbi.count[1] = f->fmt.vbi.count[0];
1479	f->fmt.vbi.flags = 0; /* VBI_UNSYNC VBI_INTERLACED */
1480
1481}
1482
1483static int saa7134_g_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
1484			 struct v4l2_format *f)
1485{
1486	switch (f->type) {
1487	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1488		memset(&f->fmt.pix,0,sizeof(f->fmt.pix));
1489		f->fmt.pix.width        = fh->width;
1490		f->fmt.pix.height       = fh->height;
1491		f->fmt.pix.field        = fh->cap.field;
1492		f->fmt.pix.pixelformat  = fh->fmt->fourcc;
1493		f->fmt.pix.bytesperline =
1494			(f->fmt.pix.width * fh->fmt->depth) >> 3;
1495		f->fmt.pix.sizeimage =
1496			f->fmt.pix.height * f->fmt.pix.bytesperline;
1497		return 0;
1498	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1499		if (saa7134_no_overlay > 0) {
1500			printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
1501			return -EINVAL;
1502		}
1503		f->fmt.win = fh->win;
1504		return 0;
1505	case V4L2_BUF_TYPE_VBI_CAPTURE:
1506		saa7134_vbi_fmt(dev,f);
1507		return 0;
1508	default:
1509		return -EINVAL;
1510	}
1511}
1512
1513static int saa7134_try_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
1514			   struct v4l2_format *f)
1515{
1516	int err;
1517
1518	switch (f->type) {
1519	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1520	{
1521		struct saa7134_format *fmt;
1522		enum v4l2_field field;
1523		unsigned int maxw, maxh;
1524
1525		fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1526		if (NULL == fmt)
1527			return -EINVAL;
1528
1529		field = f->fmt.pix.field;
1530		maxw  = min(dev->crop_current.width*4,  dev->crop_bounds.width);
1531		maxh  = min(dev->crop_current.height*4, dev->crop_bounds.height);
1532
1533		if (V4L2_FIELD_ANY == field) {
1534			field = (f->fmt.pix.height > maxh/2)
1535				? V4L2_FIELD_INTERLACED
1536				: V4L2_FIELD_BOTTOM;
1537		}
1538		switch (field) {
1539		case V4L2_FIELD_TOP:
1540		case V4L2_FIELD_BOTTOM:
1541			maxh = maxh / 2;
1542			break;
1543		case V4L2_FIELD_INTERLACED:
1544			break;
1545		default:
1546			return -EINVAL;
1547		}
1548
1549		f->fmt.pix.field = field;
1550		if (f->fmt.pix.width  < 48)
1551			f->fmt.pix.width  = 48;
1552		if (f->fmt.pix.height < 32)
1553			f->fmt.pix.height = 32;
1554		if (f->fmt.pix.width > maxw)
1555			f->fmt.pix.width = maxw;
1556		if (f->fmt.pix.height > maxh)
1557			f->fmt.pix.height = maxh;
1558		f->fmt.pix.width &= ~0x03;
1559		f->fmt.pix.bytesperline =
1560			(f->fmt.pix.width * fmt->depth) >> 3;
1561		f->fmt.pix.sizeimage =
1562			f->fmt.pix.height * f->fmt.pix.bytesperline;
1563
1564		return 0;
1565	}
1566	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1567		if (saa7134_no_overlay > 0) {
1568			printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
1569			return -EINVAL;
1570		}
1571		err = verify_preview(dev,&f->fmt.win);
1572		if (0 != err)
1573			return err;
1574		return 0;
1575	case V4L2_BUF_TYPE_VBI_CAPTURE:
1576		saa7134_vbi_fmt(dev,f);
1577		return 0;
1578	default:
1579		return -EINVAL;
1580	}
1581}
1582
1583static int saa7134_s_fmt(struct saa7134_dev *dev, struct saa7134_fh *fh,
1584			 struct v4l2_format *f)
1585{
1586	unsigned long flags;
1587	int err;
1588
1589	switch (f->type) {
1590	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1591		err = saa7134_try_fmt(dev,fh,f);
1592		if (0 != err)
1593			return err;
1594
1595		fh->fmt       = format_by_fourcc(f->fmt.pix.pixelformat);
1596		fh->width     = f->fmt.pix.width;
1597		fh->height    = f->fmt.pix.height;
1598		fh->cap.field = f->fmt.pix.field;
1599		return 0;
1600	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
1601		if (saa7134_no_overlay > 0) {
1602			printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
1603			return -EINVAL;
1604		}
1605		err = verify_preview(dev,&f->fmt.win);
1606		if (0 != err)
1607			return err;
1608
1609		mutex_lock(&dev->lock);
1610		fh->win    = f->fmt.win;
1611		fh->nclips = f->fmt.win.clipcount;
1612		if (fh->nclips > 8)
1613			fh->nclips = 8;
1614		if (copy_from_user(fh->clips,f->fmt.win.clips,
1615				   sizeof(struct v4l2_clip)*fh->nclips)) {
1616			mutex_unlock(&dev->lock);
1617			return -EFAULT;
1618		}
1619
1620		if (res_check(fh, RESOURCE_OVERLAY)) {
1621			spin_lock_irqsave(&dev->slock,flags);
1622			stop_preview(dev,fh);
1623			start_preview(dev,fh);
1624			spin_unlock_irqrestore(&dev->slock,flags);
1625		}
1626		mutex_unlock(&dev->lock);
1627		return 0;
1628	case V4L2_BUF_TYPE_VBI_CAPTURE:
1629		saa7134_vbi_fmt(dev,f);
1630		return 0;
1631	default:
1632		return -EINVAL;
1633	}
1634}
1635
1636int saa7134_common_ioctl(struct saa7134_dev *dev,
1637			 unsigned int cmd, void *arg)
1638{
1639	int err;
1640
1641	switch (cmd) {
1642	case VIDIOC_QUERYCTRL:
1643	{
1644		const struct v4l2_queryctrl *ctrl;
1645		struct v4l2_queryctrl *c = arg;
1646
1647		if ((c->id <  V4L2_CID_BASE ||
1648		     c->id >= V4L2_CID_LASTP1) &&
1649		    (c->id <  V4L2_CID_PRIVATE_BASE ||
1650		     c->id >= V4L2_CID_PRIVATE_LASTP1))
1651			return -EINVAL;
1652		ctrl = ctrl_by_id(c->id);
1653		*c = (NULL != ctrl) ? *ctrl : no_ctrl;
1654		return 0;
1655	}
1656	case VIDIOC_G_CTRL:
1657		return get_control(dev,arg);
1658	case VIDIOC_S_CTRL:
1659	{
1660		mutex_lock(&dev->lock);
1661		err = set_control(dev,NULL,arg);
1662		mutex_unlock(&dev->lock);
1663		return err;
1664	}
1665	/* --- input switching --------------------------------------- */
1666	case VIDIOC_ENUMINPUT:
1667	{
1668		struct v4l2_input *i = arg;
1669		unsigned int n;
1670
1671		n = i->index;
1672		if (n >= SAA7134_INPUT_MAX)
1673			return -EINVAL;
1674		if (NULL == card_in(dev,i->index).name)
1675			return -EINVAL;
1676		memset(i,0,sizeof(*i));
1677		i->index = n;
1678		i->type  = V4L2_INPUT_TYPE_CAMERA;
1679		strcpy(i->name,card_in(dev,n).name);
1680		if (card_in(dev,n).tv)
1681			i->type = V4L2_INPUT_TYPE_TUNER;
1682		i->audioset = 1;
1683		if (n == dev->ctl_input) {
1684			int v1 = saa_readb(SAA7134_STATUS_VIDEO1);
1685			int v2 = saa_readb(SAA7134_STATUS_VIDEO2);
1686
1687			if (0 != (v1 & 0x40))
1688				i->status |= V4L2_IN_ST_NO_H_LOCK;
1689			if (0 != (v2 & 0x40))
1690				i->status |= V4L2_IN_ST_NO_SYNC;
1691			if (0 != (v2 & 0x0e))
1692				i->status |= V4L2_IN_ST_MACROVISION;
1693		}
1694		for (n = 0; n < TVNORMS; n++)
1695			i->std |= tvnorms[n].id;
1696		return 0;
1697	}
1698	case VIDIOC_G_INPUT:
1699	{
1700		int *i = arg;
1701		*i = dev->ctl_input;
1702		return 0;
1703	}
1704	case VIDIOC_S_INPUT:
1705	{
1706		int *i = arg;
1707
1708		if (*i < 0  ||  *i >= SAA7134_INPUT_MAX)
1709			return -EINVAL;
1710		if (NULL == card_in(dev,*i).name)
1711			return -EINVAL;
1712		mutex_lock(&dev->lock);
1713		video_mux(dev,*i);
1714		mutex_unlock(&dev->lock);
1715		return 0;
1716	}
1717
1718	}
1719	return 0;
1720}
1721EXPORT_SYMBOL(saa7134_common_ioctl);
1722
1723/*
1724 * This function is _not_ called directly, but from
1725 * video_generic_ioctl (and maybe others).  userspace
1726 * copying is done already, arg is a kernel pointer.
1727 */
1728static int video_do_ioctl(struct inode *inode, struct file *file,
1729			  unsigned int cmd, void *arg)
1730{
1731	struct saa7134_fh *fh = file->private_data;
1732	struct saa7134_dev *dev = fh->dev;
1733	unsigned long flags;
1734	int err;
1735
1736	if (video_debug > 1)
1737		v4l_print_ioctl(dev->name,cmd);
1738
1739	switch (cmd) {
1740	case VIDIOC_S_CTRL:
1741	case VIDIOC_S_STD:
1742	case VIDIOC_S_INPUT:
1743	case VIDIOC_S_TUNER:
1744	case VIDIOC_S_FREQUENCY:
1745		err = v4l2_prio_check(&dev->prio,&fh->prio);
1746		if (0 != err)
1747			return err;
1748	}
1749
1750	switch (cmd) {
1751	case VIDIOC_QUERYCAP:
1752	{
1753		struct v4l2_capability *cap = arg;
1754		unsigned int tuner_type = dev->tuner_type;
1755
1756		memset(cap,0,sizeof(*cap));
1757		strcpy(cap->driver, "saa7134");
1758		strlcpy(cap->card, saa7134_boards[dev->board].name,
1759			sizeof(cap->card));
1760		sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
1761		cap->version = SAA7134_VERSION_CODE;
1762		cap->capabilities =
1763			V4L2_CAP_VIDEO_CAPTURE |
1764			V4L2_CAP_VBI_CAPTURE |
1765			V4L2_CAP_READWRITE |
1766			V4L2_CAP_STREAMING |
1767			V4L2_CAP_TUNER;
1768		if (saa7134_no_overlay <= 0) {
1769			cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY;
1770		}
1771
1772		if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET))
1773			cap->capabilities &= ~V4L2_CAP_TUNER;
1774
1775		return 0;
1776	}
1777
1778	/* --- tv standards ------------------------------------------ */
1779	case VIDIOC_ENUMSTD:
1780	{
1781		struct v4l2_standard *e = arg;
1782		unsigned int i;
1783
1784		i = e->index;
1785		if (i >= TVNORMS)
1786			return -EINVAL;
1787		err = v4l2_video_std_construct(e, tvnorms[e->index].id,
1788					       tvnorms[e->index].name);
1789		e->index = i;
1790		if (err < 0)
1791			return err;
1792		return 0;
1793	}
1794	case VIDIOC_G_STD:
1795	{
1796		v4l2_std_id *id = arg;
1797
1798		*id = dev->tvnorm->id;
1799		return 0;
1800	}
1801	case VIDIOC_S_STD:
1802	{
1803		v4l2_std_id *id = arg;
1804		unsigned int i;
1805		v4l2_std_id fixup;
1806
1807		for (i = 0; i < TVNORMS; i++)
1808			if (*id == tvnorms[i].id)
1809				break;
1810		if (i == TVNORMS)
1811			for (i = 0; i < TVNORMS; i++)
1812				if (*id & tvnorms[i].id)
1813					break;
1814		if (i == TVNORMS)
1815			return -EINVAL;
1816		if ((*id & V4L2_STD_SECAM) && (secam[0] != '-')) {
1817			if (secam[0] == 'L' || secam[0] == 'l') {
1818				if (secam[1] == 'C' || secam[1] == 'c')
1819					fixup = V4L2_STD_SECAM_LC;
1820				else
1821					fixup = V4L2_STD_SECAM_L;
1822			} else {
1823				if (secam[0] == 'D' || secam[0] == 'd')
1824					fixup = V4L2_STD_SECAM_DK;
1825				else
1826					fixup = V4L2_STD_SECAM;
1827			}
1828			for (i = 0; i < TVNORMS; i++)
1829				if (fixup == tvnorms[i].id)
1830					break;
1831		}
1832		mutex_lock(&dev->lock);
1833		if (res_check(fh, RESOURCE_OVERLAY)) {
1834			spin_lock_irqsave(&dev->slock,flags);
1835			stop_preview(dev,fh);
1836			set_tvnorm(dev,&tvnorms[i]);
1837			start_preview(dev,fh);
1838			spin_unlock_irqrestore(&dev->slock,flags);
1839		} else
1840			set_tvnorm(dev,&tvnorms[i]);
1841		saa7134_tvaudio_do_scan(dev);
1842		mutex_unlock(&dev->lock);
1843		return 0;
1844	}
1845
1846	case VIDIOC_CROPCAP:
1847	{
1848		struct v4l2_cropcap *cap = arg;
1849
1850		if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1851		    cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
1852			return -EINVAL;
1853		cap->bounds  = dev->crop_bounds;
1854		cap->defrect = dev->crop_defrect;
1855		cap->pixelaspect.numerator   = 1;
1856		cap->pixelaspect.denominator = 1;
1857		if (dev->tvnorm->id & V4L2_STD_525_60) {
1858			cap->pixelaspect.numerator   = 11;
1859			cap->pixelaspect.denominator = 10;
1860		}
1861		if (dev->tvnorm->id & V4L2_STD_625_50) {
1862			cap->pixelaspect.numerator   = 54;
1863			cap->pixelaspect.denominator = 59;
1864		}
1865		return 0;
1866	}
1867
1868	case VIDIOC_G_CROP:
1869	{
1870		struct v4l2_crop * crop = arg;
1871
1872		if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1873		    crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
1874			return -EINVAL;
1875		crop->c = dev->crop_current;
1876		return 0;
1877	}
1878	case VIDIOC_S_CROP:
1879	{
1880		struct v4l2_crop *crop = arg;
1881		struct v4l2_rect *b = &dev->crop_bounds;
1882
1883		if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1884		    crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY)
1885			return -EINVAL;
1886		if (crop->c.height < 0)
1887			return -EINVAL;
1888		if (crop->c.width < 0)
1889			return -EINVAL;
1890
1891		if (res_locked(fh->dev,RESOURCE_OVERLAY))
1892			return -EBUSY;
1893		if (res_locked(fh->dev,RESOURCE_VIDEO))
1894			return -EBUSY;
1895
1896		if (crop->c.top < b->top)
1897			crop->c.top = b->top;
1898		if (crop->c.top > b->top + b->height)
1899			crop->c.top = b->top + b->height;
1900		if (crop->c.height > b->top - crop->c.top + b->height)
1901			crop->c.height = b->top - crop->c.top + b->height;
1902
1903		if (crop->c.left < b->left)
1904			crop->c.left = b->left;
1905		if (crop->c.left > b->left + b->width)
1906			crop->c.left = b->left + b->width;
1907		if (crop->c.width > b->left - crop->c.left + b->width)
1908			crop->c.width = b->left - crop->c.left + b->width;
1909
1910		dev->crop_current = crop->c;
1911		return 0;
1912	}
1913
1914	/* --- tuner ioctls ------------------------------------------ */
1915	case VIDIOC_G_TUNER:
1916	{
1917		struct v4l2_tuner *t = arg;
1918		int n;
1919
1920		if (0 != t->index)
1921			return -EINVAL;
1922		memset(t,0,sizeof(*t));
1923		for (n = 0; n < SAA7134_INPUT_MAX; n++)
1924			if (card_in(dev,n).tv)
1925				break;
1926		if (NULL != card_in(dev,n).name) {
1927			strcpy(t->name, "Television");
1928			t->type = V4L2_TUNER_ANALOG_TV;
1929			t->capability = V4L2_TUNER_CAP_NORM |
1930				V4L2_TUNER_CAP_STEREO |
1931				V4L2_TUNER_CAP_LANG1 |
1932				V4L2_TUNER_CAP_LANG2;
1933			t->rangehigh = 0xffffffffUL;
1934			t->rxsubchans = saa7134_tvaudio_getstereo(dev);
1935			t->audmode = saa7134_tvaudio_rx2mode(t->rxsubchans);
1936		}
1937		if (0 != (saa_readb(SAA7134_STATUS_VIDEO1) & 0x03))
1938			t->signal = 0xffff;
1939		return 0;
1940	}
1941	case VIDIOC_S_TUNER:
1942	{
1943		struct v4l2_tuner *t = arg;
1944		int rx,mode;
1945
1946		mode = dev->thread.mode;
1947		if (UNSET == mode) {
1948			rx   = saa7134_tvaudio_getstereo(dev);
1949			mode = saa7134_tvaudio_rx2mode(t->rxsubchans);
1950		}
1951		if (mode != t->audmode) {
1952			dev->thread.mode = t->audmode;
1953		}
1954		return 0;
1955	}
1956	case VIDIOC_G_FREQUENCY:
1957	{
1958		struct v4l2_frequency *f = arg;
1959
1960		memset(f,0,sizeof(*f));
1961		f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1962		f->frequency = dev->ctl_freq;
1963		return 0;
1964	}
1965	case VIDIOC_S_FREQUENCY:
1966	{
1967		struct v4l2_frequency *f = arg;
1968
1969		if (0 != f->tuner)
1970			return -EINVAL;
1971		if (0 == fh->radio && V4L2_TUNER_ANALOG_TV != f->type)
1972			return -EINVAL;
1973		if (1 == fh->radio && V4L2_TUNER_RADIO != f->type)
1974			return -EINVAL;
1975		mutex_lock(&dev->lock);
1976		dev->ctl_freq = f->frequency;
1977
1978		saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,f);
1979
1980		saa7134_tvaudio_do_scan(dev);
1981		mutex_unlock(&dev->lock);
1982		return 0;
1983	}
1984
1985	/* --- control ioctls ---------------------------------------- */
1986	case VIDIOC_ENUMINPUT:
1987	case VIDIOC_G_INPUT:
1988	case VIDIOC_S_INPUT:
1989	case VIDIOC_QUERYCTRL:
1990	case VIDIOC_G_CTRL:
1991	case VIDIOC_S_CTRL:
1992		return saa7134_common_ioctl(dev, cmd, arg);
1993
1994	case VIDIOC_G_AUDIO:
1995	{
1996		struct v4l2_audio *a = arg;
1997
1998		memset(a,0,sizeof(*a));
1999		strcpy(a->name,"audio");
2000		return 0;
2001	}
2002	case VIDIOC_S_AUDIO:
2003		return 0;
2004	case VIDIOC_G_PARM:
2005	{
2006		struct v4l2_captureparm *parm = arg;
2007		memset(parm,0,sizeof(*parm));
2008		return 0;
2009	}
2010
2011	case VIDIOC_G_PRIORITY:
2012	{
2013		enum v4l2_priority *p = arg;
2014
2015		*p = v4l2_prio_max(&dev->prio);
2016		return 0;
2017	}
2018	case VIDIOC_S_PRIORITY:
2019	{
2020		enum v4l2_priority *prio = arg;
2021
2022		return v4l2_prio_change(&dev->prio, &fh->prio, *prio);
2023	}
2024
2025	/* --- preview ioctls ---------------------------------------- */
2026	case VIDIOC_ENUM_FMT:
2027	{
2028		struct v4l2_fmtdesc *f = arg;
2029		enum v4l2_buf_type type;
2030		unsigned int index;
2031
2032		index = f->index;
2033		type  = f->type;
2034		switch (type) {
2035		case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2036		case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2037			if (saa7134_no_overlay > 0) {
2038				printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
2039				return -EINVAL;
2040			}
2041			if (index >= FORMATS)
2042				return -EINVAL;
2043			if (f->type == V4L2_BUF_TYPE_VIDEO_OVERLAY &&
2044			    formats[index].planar)
2045				return -EINVAL;
2046			memset(f,0,sizeof(*f));
2047			f->index = index;
2048			f->type  = type;
2049			strlcpy(f->description,formats[index].name,sizeof(f->description));
2050			f->pixelformat = formats[index].fourcc;
2051			break;
2052		case V4L2_BUF_TYPE_VBI_CAPTURE:
2053			if (0 != index)
2054				return -EINVAL;
2055			memset(f,0,sizeof(*f));
2056			f->index = index;
2057			f->type  = type;
2058			f->pixelformat = V4L2_PIX_FMT_GREY;
2059			strcpy(f->description,"vbi data");
2060			break;
2061		default:
2062			return -EINVAL;
2063		}
2064		return 0;
2065	}
2066	case VIDIOC_G_FBUF:
2067	{
2068		struct v4l2_framebuffer *fb = arg;
2069
2070		*fb = dev->ovbuf;
2071		fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
2072		return 0;
2073	}
2074	case VIDIOC_S_FBUF:
2075	{
2076		struct v4l2_framebuffer *fb = arg;
2077		struct saa7134_format *fmt;
2078
2079		if(!capable(CAP_SYS_ADMIN) &&
2080		   !capable(CAP_SYS_RAWIO))
2081			return -EPERM;
2082
2083		/* check args */
2084		fmt = format_by_fourcc(fb->fmt.pixelformat);
2085		if (NULL == fmt)
2086			return -EINVAL;
2087
2088		/* ok, accept it */
2089		dev->ovbuf = *fb;
2090		dev->ovfmt = fmt;
2091		if (0 == dev->ovbuf.fmt.bytesperline)
2092			dev->ovbuf.fmt.bytesperline =
2093				dev->ovbuf.fmt.width*fmt->depth/8;
2094		return 0;
2095	}
2096	case VIDIOC_OVERLAY:
2097	{
2098		int *on = arg;
2099
2100		if (*on) {
2101			if (saa7134_no_overlay > 0) {
2102				printk ("no_overlay\n");
2103				return -EINVAL;
2104			}
2105
2106			if (!res_get(dev,fh,RESOURCE_OVERLAY))
2107				return -EBUSY;
2108			spin_lock_irqsave(&dev->slock,flags);
2109			start_preview(dev,fh);
2110			spin_unlock_irqrestore(&dev->slock,flags);
2111		}
2112		if (!*on) {
2113			if (!res_check(fh, RESOURCE_OVERLAY))
2114				return -EINVAL;
2115			spin_lock_irqsave(&dev->slock,flags);
2116			stop_preview(dev,fh);
2117			spin_unlock_irqrestore(&dev->slock,flags);
2118			res_free(dev,fh,RESOURCE_OVERLAY);
2119		}
2120		return 0;
2121	}
2122
2123	/* --- capture ioctls ---------------------------------------- */
2124	case VIDIOC_G_FMT:
2125	{
2126		struct v4l2_format *f = arg;
2127		return saa7134_g_fmt(dev,fh,f);
2128	}
2129	case VIDIOC_S_FMT:
2130	{
2131		struct v4l2_format *f = arg;
2132		return saa7134_s_fmt(dev,fh,f);
2133	}
2134	case VIDIOC_TRY_FMT:
2135	{
2136		struct v4l2_format *f = arg;
2137		return saa7134_try_fmt(dev,fh,f);
2138	}
2139#ifdef CONFIG_VIDEO_V4L1_COMPAT
2140	case VIDIOCGMBUF:
2141	{
2142		struct video_mbuf *mbuf = arg;
2143		struct videobuf_queue *q;
2144		struct v4l2_requestbuffers req;
2145		unsigned int i;
2146
2147		q = saa7134_queue(fh);
2148		memset(&req,0,sizeof(req));
2149		req.type   = q->type;
2150		req.count  = gbuffers;
2151		req.memory = V4L2_MEMORY_MMAP;
2152		err = videobuf_reqbufs(q,&req);
2153		if (err < 0)
2154			return err;
2155		memset(mbuf,0,sizeof(*mbuf));
2156		mbuf->frames = req.count;
2157		mbuf->size   = 0;
2158		for (i = 0; i < mbuf->frames; i++) {
2159			mbuf->offsets[i]  = q->bufs[i]->boff;
2160			mbuf->size       += q->bufs[i]->bsize;
2161		}
2162		return 0;
2163	}
2164#endif
2165	case VIDIOC_REQBUFS:
2166		return videobuf_reqbufs(saa7134_queue(fh),arg);
2167
2168	case VIDIOC_QUERYBUF:
2169		return videobuf_querybuf(saa7134_queue(fh),arg);
2170
2171	case VIDIOC_QBUF:
2172		return videobuf_qbuf(saa7134_queue(fh),arg);
2173
2174	case VIDIOC_DQBUF:
2175		return videobuf_dqbuf(saa7134_queue(fh),arg,
2176				      file->f_flags & O_NONBLOCK);
2177
2178	case VIDIOC_STREAMON:
2179	{
2180		int res = saa7134_resource(fh);
2181
2182		if (!res_get(dev,fh,res))
2183			return -EBUSY;
2184		return videobuf_streamon(saa7134_queue(fh));
2185	}
2186	case VIDIOC_STREAMOFF:
2187	{
2188		int res = saa7134_resource(fh);
2189
2190		err = videobuf_streamoff(saa7134_queue(fh));
2191		if (err < 0)
2192			return err;
2193		res_free(dev,fh,res);
2194		return 0;
2195	}
2196
2197	default:
2198		return v4l_compat_translate_ioctl(inode,file,cmd,arg,
2199						  video_do_ioctl);
2200	}
2201	return 0;
2202}
2203
2204static int video_ioctl(struct inode *inode, struct file *file,
2205		       unsigned int cmd, unsigned long arg)
2206{
2207	return video_usercopy(inode, file, cmd, arg, video_do_ioctl);
2208}
2209
2210static int radio_do_ioctl(struct inode *inode, struct file *file,
2211			  unsigned int cmd, void *arg)
2212{
2213	struct saa7134_fh *fh = file->private_data;
2214	struct saa7134_dev *dev = fh->dev;
2215
2216	if (video_debug > 1)
2217		v4l_print_ioctl(dev->name,cmd);
2218	switch (cmd) {
2219	case VIDIOC_QUERYCAP:
2220	{
2221		struct v4l2_capability *cap = arg;
2222
2223		memset(cap,0,sizeof(*cap));
2224		strcpy(cap->driver, "saa7134");
2225		strlcpy(cap->card, saa7134_boards[dev->board].name,
2226			sizeof(cap->card));
2227		sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
2228		cap->version = SAA7134_VERSION_CODE;
2229		cap->capabilities = V4L2_CAP_TUNER;
2230		return 0;
2231	}
2232	case VIDIOC_G_TUNER:
2233	{
2234		struct v4l2_tuner *t = arg;
2235
2236		if (0 != t->index)
2237			return -EINVAL;
2238
2239		memset(t,0,sizeof(*t));
2240		strcpy(t->name, "Radio");
2241		t->type = V4L2_TUNER_RADIO;
2242
2243		saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
2244		if (dev->input->amux == TV) {
2245			t->signal = 0xf800 - ((saa_readb(0x581) & 0x1f) << 11);
2246			t->rxsubchans = (saa_readb(0x529) & 0x08) ?
2247					V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO;
2248		}
2249		return 0;
2250	}
2251	case VIDIOC_S_TUNER:
2252	{
2253		struct v4l2_tuner *t = arg;
2254
2255		if (0 != t->index)
2256			return -EINVAL;
2257
2258		saa7134_i2c_call_clients(dev,VIDIOC_S_TUNER,t);
2259
2260		return 0;
2261	}
2262	case VIDIOC_ENUMINPUT:
2263	{
2264		struct v4l2_input *i = arg;
2265
2266		if (i->index != 0)
2267			return -EINVAL;
2268		strcpy(i->name,"Radio");
2269		i->type = V4L2_INPUT_TYPE_TUNER;
2270		return 0;
2271	}
2272	case VIDIOC_G_INPUT:
2273	{
2274		int *i = arg;
2275		*i = 0;
2276		return 0;
2277	}
2278	case VIDIOC_G_AUDIO:
2279	{
2280		struct v4l2_audio *a = arg;
2281
2282		memset(a,0,sizeof(*a));
2283		strcpy(a->name,"Radio");
2284		return 0;
2285	}
2286	case VIDIOC_G_STD:
2287	{
2288		v4l2_std_id *id = arg;
2289		*id = 0;
2290		return 0;
2291	}
2292	case VIDIOC_S_AUDIO:
2293	case VIDIOC_S_INPUT:
2294	case VIDIOC_S_STD:
2295		return 0;
2296
2297	case VIDIOC_QUERYCTRL:
2298	{
2299		const struct v4l2_queryctrl *ctrl;
2300		struct v4l2_queryctrl *c = arg;
2301
2302		if (c->id <  V4L2_CID_BASE ||
2303		    c->id >= V4L2_CID_LASTP1)
2304			return -EINVAL;
2305		if (c->id == V4L2_CID_AUDIO_MUTE) {
2306			ctrl = ctrl_by_id(c->id);
2307			*c = *ctrl;
2308		} else
2309			*c = no_ctrl;
2310		return 0;
2311	}
2312
2313	case VIDIOC_G_CTRL:
2314	case VIDIOC_S_CTRL:
2315	case VIDIOC_G_FREQUENCY:
2316	case VIDIOC_S_FREQUENCY:
2317		return video_do_ioctl(inode,file,cmd,arg);
2318
2319	default:
2320		return v4l_compat_translate_ioctl(inode,file,cmd,arg,
2321						  radio_do_ioctl);
2322	}
2323	return 0;
2324}
2325
2326static int radio_ioctl(struct inode *inode, struct file *file,
2327		       unsigned int cmd, unsigned long arg)
2328{
2329	return video_usercopy(inode, file, cmd, arg, radio_do_ioctl);
2330}
2331
2332static const struct file_operations video_fops =
2333{
2334	.owner	  = THIS_MODULE,
2335	.open	  = video_open,
2336	.release  = video_release,
2337	.read	  = video_read,
2338	.poll     = video_poll,
2339	.mmap	  = video_mmap,
2340	.ioctl	  = video_ioctl,
2341	.compat_ioctl	= v4l_compat_ioctl32,
2342	.llseek   = no_llseek,
2343};
2344
2345static const struct file_operations radio_fops =
2346{
2347	.owner	  = THIS_MODULE,
2348	.open	  = video_open,
2349	.release  = video_release,
2350	.ioctl	  = radio_ioctl,
2351	.compat_ioctl	= v4l_compat_ioctl32,
2352	.llseek   = no_llseek,
2353};
2354
2355/* ----------------------------------------------------------- */
2356/* exported stuff                                              */
2357
2358struct video_device saa7134_video_template =
2359{
2360	.name          = "saa7134-video",
2361	.type          = VID_TYPE_CAPTURE|VID_TYPE_TUNER|
2362			 VID_TYPE_CLIPPING|VID_TYPE_SCALES,
2363	.hardware      = 0,
2364	.fops          = &video_fops,
2365	.minor         = -1,
2366};
2367
2368struct video_device saa7134_vbi_template =
2369{
2370	.name          = "saa7134-vbi",
2371	.type          = VID_TYPE_TUNER|VID_TYPE_TELETEXT,
2372	.hardware      = 0,
2373	.fops          = &video_fops,
2374	.minor         = -1,
2375};
2376
2377struct video_device saa7134_radio_template =
2378{
2379	.name          = "saa7134-radio",
2380	.type          = VID_TYPE_TUNER,
2381	.hardware      = 0,
2382	.fops          = &radio_fops,
2383	.minor         = -1,
2384};
2385
2386int saa7134_video_init1(struct saa7134_dev *dev)
2387{
2388	/* sanitycheck insmod options */
2389	if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME)
2390		gbuffers = 2;
2391	if (gbufsize < 0 || gbufsize > gbufsize_max)
2392		gbufsize = gbufsize_max;
2393	gbufsize = (gbufsize + PAGE_SIZE - 1) & PAGE_MASK;
2394
2395	/* put some sensible defaults into the data structures ... */
2396	dev->ctl_bright     = ctrl_by_id(V4L2_CID_BRIGHTNESS)->default_value;
2397	dev->ctl_contrast   = ctrl_by_id(V4L2_CID_CONTRAST)->default_value;
2398	dev->ctl_hue        = ctrl_by_id(V4L2_CID_HUE)->default_value;
2399	dev->ctl_saturation = ctrl_by_id(V4L2_CID_SATURATION)->default_value;
2400	dev->ctl_volume     = ctrl_by_id(V4L2_CID_AUDIO_VOLUME)->default_value;
2401	dev->ctl_mute       = 1; // ctrl_by_id(V4L2_CID_AUDIO_MUTE)->default_value;
2402	dev->ctl_invert     = ctrl_by_id(V4L2_CID_PRIVATE_INVERT)->default_value;
2403	dev->ctl_automute   = ctrl_by_id(V4L2_CID_PRIVATE_AUTOMUTE)->default_value;
2404
2405	if (dev->tda9887_conf && dev->ctl_automute)
2406		dev->tda9887_conf |= TDA9887_AUTOMUTE;
2407	dev->automute       = 0;
2408
2409	INIT_LIST_HEAD(&dev->video_q.queue);
2410	init_timer(&dev->video_q.timeout);
2411	dev->video_q.timeout.function = saa7134_buffer_timeout;
2412	dev->video_q.timeout.data     = (unsigned long)(&dev->video_q);
2413	dev->video_q.dev              = dev;
2414
2415	if (saa7134_boards[dev->board].video_out) {
2416		/* enable video output */
2417		int vo = saa7134_boards[dev->board].video_out;
2418		int video_reg;
2419		unsigned int vid_port_opts = saa7134_boards[dev->board].vid_port_opts;
2420		saa_writeb(SAA7134_VIDEO_PORT_CTRL0, video_out[vo][0]);
2421		video_reg = video_out[vo][1];
2422		if (vid_port_opts & SET_T_CODE_POLARITY_NON_INVERTED)
2423			video_reg &= ~VP_T_CODE_P_INVERTED;
2424		saa_writeb(SAA7134_VIDEO_PORT_CTRL1, video_reg);
2425		saa_writeb(SAA7134_VIDEO_PORT_CTRL2, video_out[vo][2]);
2426		saa_writeb(SAA7134_VIDEO_PORT_CTRL3, video_out[vo][3]);
2427		saa_writeb(SAA7134_VIDEO_PORT_CTRL4, video_out[vo][4]);
2428		video_reg = video_out[vo][5];
2429		if (vid_port_opts & SET_CLOCK_NOT_DELAYED)
2430			video_reg &= ~VP_CLK_CTRL2_DELAYED;
2431		if (vid_port_opts & SET_CLOCK_INVERTED)
2432			video_reg |= VP_CLK_CTRL1_INVERTED;
2433		saa_writeb(SAA7134_VIDEO_PORT_CTRL5, video_reg);
2434		video_reg = video_out[vo][6];
2435		if (vid_port_opts & SET_VSYNC_OFF) {
2436			video_reg &= ~VP_VS_TYPE_MASK;
2437			video_reg |= VP_VS_TYPE_OFF;
2438		}
2439		saa_writeb(SAA7134_VIDEO_PORT_CTRL6, video_reg);
2440		saa_writeb(SAA7134_VIDEO_PORT_CTRL7, video_out[vo][7]);
2441		saa_writeb(SAA7134_VIDEO_PORT_CTRL8, video_out[vo][8]);
2442	}
2443
2444	return 0;
2445}
2446
2447int saa7134_video_init2(struct saa7134_dev *dev)
2448{
2449	/* init video hw */
2450	set_tvnorm(dev,&tvnorms[0]);
2451	video_mux(dev,0);
2452	saa7134_tvaudio_setmute(dev);
2453	saa7134_tvaudio_setvolume(dev,dev->ctl_volume);
2454	return 0;
2455}
2456
2457void saa7134_irq_video_intl(struct saa7134_dev *dev)
2458{
2459	static const char *st[] = {
2460		"(no signal)", "NTSC", "PAL", "SECAM" };
2461	u32 st1,st2;
2462
2463	st1 = saa_readb(SAA7134_STATUS_VIDEO1);
2464	st2 = saa_readb(SAA7134_STATUS_VIDEO2);
2465	dprintk("DCSDT: pll: %s, sync: %s, norm: %s\n",
2466		(st1 & 0x40) ? "not locked" : "locked",
2467		(st2 & 0x40) ? "no"         : "yes",
2468		st[st1 & 0x03]);
2469	dev->nosignal = (st1 & 0x40) || (st2 & 0x40);
2470
2471	if (dev->nosignal) {
2472		/* no video signal -> mute audio */
2473		if (dev->ctl_automute)
2474			dev->automute = 1;
2475		saa7134_tvaudio_setmute(dev);
2476		saa_setb(SAA7134_SYNC_CTRL, 0x20);
2477	} else {
2478		/* wake up tvaudio audio carrier scan thread */
2479		saa7134_tvaudio_do_scan(dev);
2480		if (!noninterlaced)
2481			saa_clearb(SAA7134_SYNC_CTRL, 0x20);
2482	}
2483	if (dev->mops && dev->mops->signal_change)
2484		dev->mops->signal_change(dev);
2485}
2486
2487void saa7134_irq_video_done(struct saa7134_dev *dev, unsigned long status)
2488{
2489	enum v4l2_field field;
2490
2491	spin_lock(&dev->slock);
2492	if (dev->video_q.curr) {
2493		dev->video_fieldcount++;
2494		field = dev->video_q.curr->vb.field;
2495		if (V4L2_FIELD_HAS_BOTH(field)) {
2496			/* make sure we have seen both fields */
2497			if ((status & 0x10) == 0x00) {
2498				dev->video_q.curr->top_seen = 1;
2499				goto done;
2500			}
2501			if (!dev->video_q.curr->top_seen)
2502				goto done;
2503		} else if (field == V4L2_FIELD_TOP) {
2504			if ((status & 0x10) != 0x10)
2505				goto done;
2506		} else if (field == V4L2_FIELD_BOTTOM) {
2507			if ((status & 0x10) != 0x00)
2508				goto done;
2509		}
2510		dev->video_q.curr->vb.field_count = dev->video_fieldcount;
2511		saa7134_buffer_finish(dev,&dev->video_q,STATE_DONE);
2512	}
2513	saa7134_buffer_next(dev,&dev->video_q);
2514
2515 done:
2516	spin_unlock(&dev->slock);
2517}
2518
2519/* ----------------------------------------------------------- */
2520/*
2521 * Local variables:
2522 * c-basic-offset: 8
2523 * End:
2524 */
2525