Add missing header
[tw68:tw68-v2.git] / tw68-video.c
1 /*
2  *  tw68 functions to handle video data
3  *
4  *  Much of this code is derived from the cx88 and sa7134 drivers, which
5  *  were in turn derived from the bt87x driver.  The original work was by
6  *  Gerd Knorr; more recently the code was enhanced by Mauro Carvalho Chehab,
7  *  Hans Verkuil, Andy Walls and many others.  Their work is gratefully
8  *  acknowledged.  Full credit goes to them - any problems within this code
9  *  are mine.
10  *
11  *  Copyright (C) 2009  William M. Brack <wbrack@mmm.com.hk>
12  *
13  *  This program is free software; you can redistribute it and/or modify
14  *  it under the terms of the GNU General Public License as published by
15  *  the Free Software Foundation; either version 2 of the License, or
16  *  (at your option) any later version.
17  *
18  *  This program is distributed in the hope that it will be useful,
19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  *  GNU General Public License for more details.
22  *
23  *  You should have received a copy of the GNU General Public License along
24  *  with this program; if not, write to the Free Software Foundation, Inc.,
25  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26  */
27
28 #include <linux/module.h>
29 #include <media/v4l2-common.h>
30 #include <linux/sort.h>
31
32 #include "tw68.h"
33 #include "tw68-reg.h"
34
35 unsigned int video_debug;
36
37 static unsigned int gbuffers    = 8;
38 static unsigned int noninterlaced; /* 0 */
39 static unsigned int gbufsz      = 768*576*4;
40 static unsigned int gbufsz_max  = 768*576*4;
41 static char secam[]             = "--";
42
43 module_param(video_debug, int, 0644);
44 MODULE_PARM_DESC(video_debug, "enable debug messages [video]");
45 module_param(gbuffers, int, 0444);
46 MODULE_PARM_DESC(gbuffers, "number of capture buffers, range 2-32");
47 module_param(noninterlaced, int, 0644);
48 MODULE_PARM_DESC(noninterlaced, "capture non interlaced video");
49 module_param_string(secam, secam, sizeof(secam), 0644);
50 MODULE_PARM_DESC(secam, "force SECAM variant, either DK,L or Lc");
51
52 #define dprintk(level, fmt, arg...)     if (video_debug & (level)) \
53         printk(KERN_DEBUG "%s/0: " fmt, dev->name , ## arg)
54
55 /* ------------------------------------------------------------------ */
56 /* data structs for video                                             */
57 /*
58  * FIXME -
59  * Note that the saa7134 has formats, e.g. YUV420, which are classified
60  * as "planar".  These affect overlay mode, and are flagged with a field
61  * ".planar" in the format.  Do we need to implement this in this driver?
62  */
63 static struct tw68_format formats[] = {
64         {
65                 .name           = "15 bpp RGB, le",
66                 .fourcc         = V4L2_PIX_FMT_RGB555,
67                 .depth          = 16,
68                 .twformat       = ColorFormatRGB15,
69         }, {
70                 .name           = "15 bpp RGB, be",
71                 .fourcc         = V4L2_PIX_FMT_RGB555X,
72                 .depth          = 16,
73                 .twformat       = ColorFormatRGB15 | ColorFormatBSWAP,
74         }, {
75                 .name           = "16 bpp RGB, le",
76                 .fourcc         = V4L2_PIX_FMT_RGB565,
77                 .depth          = 16,
78                 .twformat       = ColorFormatRGB16,
79         }, {
80                 .name           = "16 bpp RGB, be",
81                 .fourcc         = V4L2_PIX_FMT_RGB565X,
82                 .depth          = 16,
83                 .twformat       = ColorFormatRGB16 | ColorFormatBSWAP,
84         }, {
85                 .name           = "24 bpp RGB, le",
86                 .fourcc         = V4L2_PIX_FMT_BGR24,
87                 .depth          = 24,
88                 .twformat       = ColorFormatRGB24,
89         }, {
90                 .name           = "24 bpp RGB, be",
91                 .fourcc         = V4L2_PIX_FMT_RGB24,
92                 .depth          = 24,
93                 .twformat       = ColorFormatRGB24 | ColorFormatBSWAP,
94         }, {
95                 .name           = "32 bpp RGB, le",
96                 .fourcc         = V4L2_PIX_FMT_BGR32,
97                 .depth          = 32,
98                 .twformat       = ColorFormatRGB32,
99         }, {
100                 .name           = "32 bpp RGB, be",
101                 .fourcc         = V4L2_PIX_FMT_RGB32,
102                 .depth          = 32,
103                 .twformat       = ColorFormatRGB32 | ColorFormatBSWAP |
104                                   ColorFormatWSWAP,
105         }, {
106                 .name           = "4:2:2 packed, YUYV",
107                 .fourcc         = V4L2_PIX_FMT_YUYV,
108                 .depth          = 16,
109                 .twformat       = ColorFormatYUY2,
110         }, {
111                 .name           = "4:2:2 packed, UYVY",
112                 .fourcc         = V4L2_PIX_FMT_UYVY,
113                 .depth          = 16,
114                 .twformat       = ColorFormatYUY2 | ColorFormatBSWAP,
115         }
116 };
117 #define FORMATS ARRAY_SIZE(formats)
118
119 #define NORM_625_50                     \
120                 .h_delay        = 3,    \
121                 .h_delay0       = 133,  \
122                 .h_start        = 0,    \
123                 .h_stop         = 719,  \
124                 .v_delay        = 24,   \
125                 .vbi_v_start_0  = 7,    \
126                 .vbi_v_stop_0   = 22,   \
127                 .video_v_start  = 24,   \
128                 .video_v_stop   = 311,  \
129                 .vbi_v_start_1  = 319
130
131 #define NORM_525_60                     \
132                 .h_delay        = 8,    \
133                 .h_delay0       = 138,  \
134                 .h_start        = 0,    \
135                 .h_stop         = 719,  \
136                 .v_delay        = 22,   \
137                 .vbi_v_start_0  = 10,   \
138                 .vbi_v_stop_0   = 21,   \
139                 .video_v_start  = 22,   \
140                 .video_v_stop   = 262,  \
141                 .vbi_v_start_1  = 273
142
143 /*
144  * The following table is searched by tw68_s_std, first for a specific
145  * match, then for an entry which contains the desired id.  The table
146  * entries should therefore be ordered in ascending order of specificity.
147  */
148 static struct tw68_tvnorm tvnorms[]             = {
149         {
150                 .name           = "PAL-BG",
151                 .id             = V4L2_STD_PAL_BG,
152                 NORM_625_50,
153
154                 .sync_control   = 0x18,
155                 .luma_control   = 0x40,
156                 .chroma_ctrl1   = 0x81,
157                 .chroma_gain    = 0x2a,
158                 .chroma_ctrl2   = 0x06,
159                 .vgate_misc     = 0x1c,
160                 .format         = VideoFormatPALBDGHI,
161
162         }, {
163                 .name           = "PAL-I",
164                 .id             = V4L2_STD_PAL_I,
165                 NORM_625_50,
166
167                 .sync_control   = 0x18,
168                 .luma_control   = 0x40,
169                 .chroma_ctrl1   = 0x81,
170                 .chroma_gain    = 0x2a,
171                 .chroma_ctrl2   = 0x06,
172                 .vgate_misc     = 0x1c,
173                 .format         = VideoFormatPALBDGHI,
174
175         }, {
176                 .name           = "PAL-DK",
177                 .id             = V4L2_STD_PAL_DK,
178                 NORM_625_50,
179
180                 .sync_control   = 0x18,
181                 .luma_control   = 0x40,
182                 .chroma_ctrl1   = 0x81,
183                 .chroma_gain    = 0x2a,
184                 .chroma_ctrl2   = 0x06,
185                 .vgate_misc     = 0x1c,
186                 .format         = VideoFormatPALBDGHI,
187
188         }, {
189                 .name           = "PAL", /* autodetect */
190                 .id             = V4L2_STD_PAL,
191                 NORM_625_50,
192
193                 .sync_control   = 0x18,
194                 .luma_control   = 0x40,
195                 .chroma_ctrl1   = 0x81,
196                 .chroma_gain    = 0x2a,
197                 .chroma_ctrl2   = 0x06,
198                 .vgate_misc     = 0x1c,
199                 .format         = VideoFormatPALBDGHI,
200
201         }, {
202                 .name           = "NTSC",
203                 .id             = V4L2_STD_NTSC,
204                 NORM_525_60,
205
206                 .sync_control   = 0x59,
207                 .luma_control   = 0x40,
208                 .chroma_ctrl1   = 0x89,
209                 .chroma_gain    = 0x2a,
210                 .chroma_ctrl2   = 0x0e,
211                 .vgate_misc     = 0x18,
212                 .format         = VideoFormatNTSC,
213
214         }, {
215                 .name           = "SECAM-DK",
216                 .id             = V4L2_STD_SECAM_DK,
217                 NORM_625_50,
218
219                 .sync_control   = 0x18,
220                 .luma_control   = 0x1b,
221                 .chroma_ctrl1   = 0xd1,
222                 .chroma_gain    = 0x80,
223                 .chroma_ctrl2   = 0x00,
224                 .vgate_misc     = 0x1c,
225                 .format         = VideoFormatSECAM,
226
227         }, {
228                 .name           = "SECAM-L",
229                 .id             = V4L2_STD_SECAM_L,
230                 NORM_625_50,
231
232                 .sync_control   = 0x18,
233                 .luma_control   = 0x1b,
234                 .chroma_ctrl1   = 0xd1,
235                 .chroma_gain    = 0x80,
236                 .chroma_ctrl2   = 0x00,
237                 .vgate_misc     = 0x1c,
238                 .format         = VideoFormatSECAM,
239
240         }, {
241                 .name           = "SECAM-LC",
242                 .id             = V4L2_STD_SECAM_LC,
243                 NORM_625_50,
244
245                 .sync_control   = 0x18,
246                 .luma_control   = 0x1b,
247                 .chroma_ctrl1   = 0xd1,
248                 .chroma_gain    = 0x80,
249                 .chroma_ctrl2   = 0x00,
250                 .vgate_misc     = 0x1c,
251                 .format         = VideoFormatSECAM,
252
253         }, {
254                 .name           = "SECAM",
255                 .id             = V4L2_STD_SECAM,
256                 NORM_625_50,
257
258                 .sync_control   = 0x18,
259                 .luma_control   = 0x1b,
260                 .chroma_ctrl1   = 0xd1,
261                 .chroma_gain    = 0x80,
262                 .chroma_ctrl2   = 0x00,
263                 .vgate_misc     = 0x1c,
264                 .format         = VideoFormatSECAM,
265
266         }, {
267                 .name           = "PAL-M",
268                 .id             = V4L2_STD_PAL_M,
269                 NORM_525_60,
270
271                 .sync_control   = 0x59,
272                 .luma_control   = 0x40,
273                 .chroma_ctrl1   = 0xb9,
274                 .chroma_gain    = 0x2a,
275                 .chroma_ctrl2   = 0x0e,
276                 .vgate_misc     = 0x18,
277                 .format         = VideoFormatPALM,
278
279         }, {
280                 .name           = "PAL-Nc",
281                 .id             = V4L2_STD_PAL_Nc,
282                 NORM_625_50,
283
284                 .sync_control   = 0x18,
285                 .luma_control   = 0x40,
286                 .chroma_ctrl1   = 0xa1,
287                 .chroma_gain    = 0x2a,
288                 .chroma_ctrl2   = 0x06,
289                 .vgate_misc     = 0x1c,
290                 .format         = VideoFormatPALNC,
291
292         }, {
293                 .name           = "PAL-60",
294                 .id             = V4L2_STD_PAL_60,
295                 .h_delay        = 186,
296                 .h_start        = 0,
297                 .h_stop         = 719,
298                 .v_delay        = 26,
299                 .video_v_start  = 23,
300                 .video_v_stop   = 262,
301                 .vbi_v_start_0  = 10,
302                 .vbi_v_stop_0   = 21,
303                 .vbi_v_start_1  = 273,
304
305                 .sync_control   = 0x18,
306                 .luma_control   = 0x40,
307                 .chroma_ctrl1   = 0x81,
308                 .chroma_gain    = 0x2a,
309                 .chroma_ctrl2   = 0x06,
310                 .vgate_misc     = 0x1c,
311                 .format         = VideoFormatPAL60,
312
313         }, {
314 /*
315  *      FIXME:  The following are meant to be "catch-all", and need
316  *              to be further thought out!
317  */
318                 .name           = "STD-525-60",
319                 .id             = V4L2_STD_525_60,
320                 NORM_525_60,
321
322                 .sync_control   = 0x59,
323                 .luma_control   = 0x40,
324                 .chroma_ctrl1   = 0x89,
325                 .chroma_gain    = 0x2a,
326                 .chroma_ctrl2   = 0x0e,
327                 .vgate_misc     = 0x18,
328                 .format         = VideoFormatNTSC,
329
330         }, {
331                 .name           = "STD-625-50",
332                 .id             = V4L2_STD_625_50,
333                 NORM_625_50,
334
335                 .sync_control   = 0x18,
336                 .luma_control   = 0x40,
337                 .chroma_ctrl1   = 0x81,
338                 .chroma_gain    = 0x2a,
339                 .chroma_ctrl2   = 0x06,
340                 .vgate_misc     = 0x1c,
341                 .format         = VideoFormatPALBDGHI,
342         }
343 };
344 #define TVNORMS ARRAY_SIZE(tvnorms)
345
346 static const struct v4l2_queryctrl no_ctrl              = {
347         .name           = "42",
348         .flags          = V4L2_CTRL_FLAG_DISABLED,
349 };
350 static const struct v4l2_queryctrl video_ctrls[]                = {
351         /* --- video --- */
352         {
353                 .id             = V4L2_CID_BRIGHTNESS,
354                 .name           = "Brightness",
355                 .minimum        = -128,
356                 .maximum        = 127,
357                 .step           = 1,
358                 .default_value  = 20,
359                 .type           = V4L2_CTRL_TYPE_INTEGER,
360         }, {
361                 .id             = V4L2_CID_CONTRAST,
362                 .name           = "Contrast",
363                 .minimum        = 0,
364                 .maximum        = 255,
365                 .step           = 1,
366                 .default_value  = 100,
367                 .type           = V4L2_CTRL_TYPE_INTEGER,
368         }, {
369                 .id             = V4L2_CID_SATURATION,
370                 .name           = "Saturation",
371                 .minimum        = 0,
372                 .maximum        = 255,
373                 .step           = 1,
374                 .default_value  = 128,
375                 .type           = V4L2_CTRL_TYPE_INTEGER,
376         }, {
377                 .id             = V4L2_CID_HUE,
378                 .name           = "Hue",
379                 .minimum        = -128,
380                 .maximum        = 127,
381                 .step           = 1,
382                 .default_value  = 0,
383                 .type           = V4L2_CTRL_TYPE_INTEGER,
384         }, {
385                 .id             = V4L2_CID_COLOR_KILLER,
386                 .name           = "Color Killer",
387                 .minimum        = 0,
388                 .maximum        = 1,
389                 .default_value  = 1,
390                 .type           = V4L2_CTRL_TYPE_BOOLEAN,
391         }, {
392                 .id             = V4L2_CID_CHROMA_AGC,
393                 .name           = "Chroma AGC",
394                 .minimum        = 0,
395                 .maximum        = 1,
396                 .default_value  = 1,
397                 .type           = V4L2_CTRL_TYPE_BOOLEAN,
398         },
399         /* --- audio --- */
400         {
401                 .id             = V4L2_CID_AUDIO_MUTE,
402                 .name           = "Mute",
403                 .minimum        = 0,
404                 .maximum        = 1,
405                 .type           = V4L2_CTRL_TYPE_BOOLEAN,
406         }, {
407                 .id             = V4L2_CID_AUDIO_VOLUME,
408                 .name           = "Volume",
409                 .minimum        = -15,
410                 .maximum        = 15,
411                 .step           = 1,
412                 .default_value  = 0,
413                 .type           = V4L2_CTRL_TYPE_INTEGER,
414         }
415 };
416 static const unsigned int CTRLS = ARRAY_SIZE(video_ctrls);
417
418 /*
419  * Routine to lookup a control by its ID, and return a pointer
420  * to the entry in the video_ctrls array for that control.
421  */
422 static const struct v4l2_queryctrl *ctrl_by_id(unsigned int id)
423 {
424         unsigned int i;
425
426         for (i = 0; i < CTRLS; i++)
427                 if (video_ctrls[i].id == id)
428                         return video_ctrls+i;
429         return NULL;
430 }
431
432 static struct tw68_format *format_by_fourcc(unsigned int fourcc)
433 {
434         unsigned int i;
435
436         for (i = 0; i < FORMATS; i++)
437                 if (formats[i].fourcc == fourcc)
438                         return formats+i;
439         return NULL;
440 }
441
442 /* ----------------------------------------------------------------------- */
443 /* resource management                                                     */
444
445 static int res_get(struct tw68_fh *fh, unsigned int bit)
446 {
447         struct tw68_dev *dev = fh->dev;
448
449         if (fh->resources & bit)
450                 /* have it already allocated */
451                 return 1;
452
453         /* is it free? */
454         mutex_lock(&dev->lock);
455         if (dev->resources & bit) {
456                 /* no, someone else uses it */
457                 mutex_unlock(&fh->dev->lock);
458                 return 0;
459         }
460         /* it's free, grab it */
461         fh->resources  |= bit;
462         dev->resources |= bit;
463         dprintk(DBG_FLOW, "%s: %d\n", __func__, bit);
464         mutex_unlock(&dev->lock);
465         return 1;
466 }
467
468 static int res_check(struct tw68_fh *fh, unsigned int bit)
469 {
470         return fh->resources & bit;
471 }
472
473 static int res_locked(struct tw68_dev *dev, unsigned int bit)
474 {
475         return dev->resources & bit;
476 }
477
478 static void res_free(struct tw68_fh *fh,
479                      unsigned int bits)
480 {
481         struct tw68_dev *dev = fh->dev;
482
483         BUG_ON((fh->resources & bits) != bits);
484
485         mutex_lock(&fh->dev->lock);
486         fh->resources  &= ~bits;
487         fh->dev->resources &= ~bits;
488         dprintk(DBG_FLOW, "%s: %d\n", __func__, bits);
489         mutex_unlock(&fh->dev->lock);
490 }
491
492 /* ------------------------------------------------------------------ */
493 /*
494  * Note that the cropping rectangles are described in terms of a single
495  * frame, i.e. line positions are only 1/2 the interlaced equivalent
496  */
497 static void set_tvnorm(struct tw68_dev *dev, struct tw68_tvnorm *norm)
498 {
499         dprintk(DBG_FLOW, "%s: %s\n", __func__, norm->name);
500         dev->tvnorm = norm;
501
502         /* setup cropping */
503         dev->crop_bounds.left    = norm->h_start;
504         dev->crop_defrect.left   = norm->h_start;
505         dev->crop_bounds.width   = norm->h_stop - norm->h_start + 1;
506         dev->crop_defrect.width  = norm->h_stop - norm->h_start + 1;
507
508         dev->crop_bounds.top     = norm->video_v_start;
509         dev->crop_defrect.top    = norm->video_v_start;
510         dev->crop_bounds.height  = (((norm->id & V4L2_STD_525_60) ?
511                                     524 : 624)) / 2 - dev->crop_bounds.top;
512         dev->crop_defrect.height = (norm->video_v_stop -
513                                     norm->video_v_start + 1);
514
515         dev->crop_current = dev->crop_defrect;
516
517         if (norm != dev->tvnorm) {
518                 dev->tvnorm = norm;
519                 tw68_set_tvnorm_hw(dev);
520         }
521 }
522
523 static void video_mux(struct tw68_dev *dev, int input)
524 {
525         dprintk(DBG_FLOW, "%s: input = %d [%s]\n", __func__, input,
526                 card_in(dev, input).name);
527         /*
528          * dev->input shows current application request,
529          * dev->hw_input shows current hardware setting
530          */
531         dev->input = &card_in(dev, input);
532         tw68_tvaudio_setinput(dev, &card_in(dev, input));
533 }
534
535 /*
536  * tw68_set_scale
537  *
538  * Scaling and Cropping for video decoding
539  *
540  * We are working with 3 values for horizontal and vertical - scale,
541  * delay and active.
542  *
543  * HACTIVE represent the actual number of pixels in the "usable" image,
544  * before scaling.  HDELAY represents the number of pixels skipped
545  * between the start of the horizontal sync and the start of the image.
546  * HSCALE is calculated using the formula
547  *      HSCALE = (HACTIVE / (#pixels desired)) * 256
548  *
549  * The vertical registers are similar, except based upon the total number
550  * of lines in the image, and the first line of the image (i.e. ignoring
551  * vertical sync and VBI).
552  *
553  * Note that the number of bytes reaching the FIFO (and hence needing
554  * to be processed by the DMAP program) is completely dependent upon
555  * these values, especially HSCALE.
556  *
557  * Parameters:
558  *      @dev            pointer to the device structure, needed for
559  *                      getting current norm (as well as debug print)
560  *      @width          actual image width (from user buffer)
561  *      @height         actual image height
562  *      @field          indicates Top, Bottom or Interlaced
563  */
564 static int tw68_set_scale(struct tw68_dev *dev, unsigned int width,
565                           unsigned int height, enum v4l2_field field)
566 {
567
568         /* set individually for debugging clarity */
569         int hactive, hdelay, hscale;
570         int vactive, vdelay, vscale;
571         int comb;
572
573         if (V4L2_FIELD_HAS_BOTH(field)) /* if field is interlaced */
574                 height /= 2;            /* we must set for 1-frame */
575
576         dprintk(DBG_FLOW, "%s: width=%d, height=%d, both=%d\n  Crop rect: "
577                     "top=%d, left=%d, width=%d height=%d\n"
578                     "  tvnorm h_delay=%d, h_start=%d, h_stop=%d, "
579                     "v_delay=%d, v_start=%d, v_stop=%d\n" , __func__,
580                 width, height, V4L2_FIELD_HAS_BOTH(field),
581                 dev->crop_bounds.top, dev->crop_bounds.left,
582                 dev->crop_bounds.width, dev->crop_bounds.height,
583                 dev->tvnorm->h_delay, dev->tvnorm->h_start, dev->tvnorm->h_stop,
584                 dev->tvnorm->v_delay, dev->tvnorm->video_v_start,
585                 dev->tvnorm->video_v_stop);
586
587         switch (dev->vdecoder) {
588         case TW6800:
589                 hdelay = dev->tvnorm->h_delay0;
590                 break;
591         default:
592                 hdelay = dev->tvnorm->h_delay;
593                 break;
594         }
595         hdelay += dev->crop_bounds.left;
596         hactive = dev->crop_bounds.width;
597
598         hscale = (hactive * 256) / (width);
599
600         vdelay = dev->tvnorm->v_delay + dev->crop_bounds.top -
601                  dev->crop_defrect.top;
602         vactive = dev->crop_bounds.height;
603         vscale = (vactive * 256) / height;
604
605         dprintk(DBG_FLOW, "%s: %dx%d [%s%s,%s]\n", __func__,
606                 width, height,
607                 V4L2_FIELD_HAS_TOP(field)    ? "T" : "",
608                 V4L2_FIELD_HAS_BOTTOM(field) ? "B" : "",
609                 v4l2_norm_to_name(dev->tvnorm->id));
610         dprintk(DBG_FLOW, "%s: hactive=%d, hdelay=%d, hscale=%d; "
611                 "vactive=%d, vdelay=%d, vscale=%d\n", __func__,
612                 hactive, hdelay, hscale, vactive, vdelay, vscale);
613
614         comb =  ((vdelay & 0x300)  >> 2) |
615                 ((vactive & 0x300) >> 4) |
616                 ((hdelay & 0x300)  >> 6) |
617                 ((hactive & 0x300) >> 8);
618         dprintk(DBG_FLOW, "%s: setting CROP_HI=%02x, VDELAY_LO=%02x, "
619                 "VACTIVE_LO=%02x, HDELAY_LO=%02x, HACTIVE_LO=%02x\n",
620                 __func__, comb, vdelay, vactive, hdelay, hactive);
621         tw_writeb(TW68_CROP_HI, comb);
622         tw_writeb(TW68_VDELAY_LO, vdelay & 0xff);
623         tw_writeb(TW68_VACTIVE_LO, vactive & 0xff);
624         tw_writeb(TW68_HDELAY_LO, hdelay & 0xff);
625         tw_writeb(TW68_HACTIVE_LO, hactive & 0xff);
626
627         comb = ((vscale & 0xf00) >> 4) | ((hscale & 0xf00) >> 8);
628         dprintk(DBG_FLOW, "%s: setting SCALE_HI=%02x, VSCALE_LO=%02x, "
629                 "HSCALE_LO=%02x\n", __func__, comb, vscale, hscale);
630         tw_writeb(TW68_SCALE_HI, comb);
631         tw_writeb(TW68_VSCALE_LO, vscale);
632         tw_writeb(TW68_HSCALE_LO, hscale);
633
634         return 0;
635 }
636
637 /* ------------------------------------------------------------------ */
638
639 static int tw68_video_start_dma(struct tw68_dev *dev, struct tw68_dmaqueue *q,
640                                 struct tw68_buf *buf) {
641
642         dprintk(DBG_FLOW, "%s: Starting risc program\n", __func__);
643         /* Assure correct input */
644         if (dev->hw_input != dev->input) {
645                 dev->hw_input = dev->input;
646                 tw_andorb(TW68_INFORM, 0x03 << 2, dev->input->vmux << 2);
647         }
648         /* Set cropping and scaling */
649         tw68_set_scale(dev, buf->vb.width, buf->vb.height, buf->vb.field);
650         /*
651          *  Set start address for RISC program.  Note that if the DMAP
652          *  processor is currently running, it must be stopped before
653          *  a new address can be set.
654          */
655         tw_clearl(TW68_DMAC, TW68_DMAP_EN);
656         tw_writel(TW68_DMAP_SA, cpu_to_le32(buf->risc.dma));
657         /* Clear any pending interrupts */
658         tw_writel(TW68_INTSTAT, dev->board_virqmask);
659         /* Enable the risc engine and the fifo */
660         tw_andorl(TW68_DMAC, 0xff, buf->fmt->twformat |
661                 ColorFormatGamma | TW68_DMAP_EN | TW68_FIFO_EN);
662         dev->pci_irqmask |= dev->board_virqmask;
663         tw_setl(TW68_INTMASK, dev->pci_irqmask);
664         return 0;
665 }
666
667 /* ------------------------------------------------------------------ */
668 /* videobuf queue operations                                          */
669
670 /*
671  * check_buf_fmt
672  *
673  * callback from tw68-core buffer_queue to determine whether the
674  * current buffer and the previous one are "compatible" (i.e. the
675  * risc programs can be chained without requiring a format change)
676  */
677 static int tw68_check_video_fmt(struct tw68_buf *prev, struct tw68_buf *buf)
678 {
679         return (prev->vb.width  == buf->vb.width  &&
680                 prev->vb.height == buf->vb.height &&
681                 prev->fmt       == buf->fmt);
682 }
683
684 /*
685  * buffer_setup
686  *
687  * Calculate required size of buffer and maximum number allowed
688  */
689 static int
690 buffer_setup(struct videobuf_queue *q, unsigned int *count,
691              unsigned int *size)
692 {
693         struct tw68_fh *fh = q->priv_data;
694
695         *size = fh->fmt->depth * fh->width * fh->height >> 3;
696         if (0 == *count)
697                 *count = gbuffers;
698         *count = tw68_buffer_count(*size, *count);
699         return 0;
700 }
701
702 static int buffer_activate(struct tw68_dev *dev, struct tw68_buf *buf,
703                            struct tw68_buf *next)
704 {
705         dprintk(DBG_BUFF, "%s: dev=%p, buf=%p, next=%p\n",
706                 __func__, dev, buf, next);
707         if (dev->hw_input != dev->input) {
708                 dev->hw_input = dev->input;
709                 tw_andorb(TW68_INFORM, 0x03 << 2,
710                           dev->hw_input->vmux << 2);
711         }
712         buf->vb.state = VIDEOBUF_ACTIVE;
713         /* TODO - need to assure scaling/cropping are set correctly */
714         mod_timer(&dev->video_q.timeout, jiffies+BUFFER_TIMEOUT);
715         return 0;
716 }
717
718 /*
719 * buffer_prepare
720 *
721 * Set the ancilliary information into the buffer structure.  This
722 * includes generating the necessary risc program if it hasn't already
723 * been done for the current buffer format.
724 * The structure fh contains the details of the format requested by the
725 * user - type, width, height and #fields.  This is compared with the
726 * last format set for the current buffer.  If they differ, the risc
727 * code (which controls the filling of the buffer) is (re-)generated.
728 */
729 static int
730 buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
731                enum v4l2_field field)
732 {
733         struct tw68_fh   *fh  = q->priv_data;
734         struct tw68_dev  *dev = fh->dev;
735         struct tw68_buf *buf = container_of(vb, struct tw68_buf, vb);
736         struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
737         int rc, init_buffer = 0;
738         unsigned int maxw, maxh;
739
740         BUG_ON(NULL == fh->fmt);
741         maxw = dev->tvnorm->h_stop - dev->tvnorm->h_start + 1;
742         maxh = 2*(dev->tvnorm->video_v_stop - dev->tvnorm->video_v_start + 1);
743         if (fh->width  < 48 || fh->width  > maxw || fh->height > maxh
744                 || fh->height < 16) {
745                 dprintk(DBG_UNEXPECTED, "%s: invalid dimensions - "
746                         "fh->width=%d, fh->height=%d, maxw=%d, maxh=%d\n",
747                         __func__, fh->width, fh->height, maxw, maxh);
748                 return -EINVAL;
749         }
750         buf->vb.size = (fh->width * fh->height * (fh->fmt->depth)) >> 3;
751         if (0 != buf->vb.baddr  &&  buf->vb.bsize < buf->vb.size)
752                 return -EINVAL;
753
754         if (buf->fmt       != fh->fmt    ||
755             buf->vb.width  != fh->width  ||
756             buf->vb.height != fh->height ||
757             buf->vb.field  != field) {
758                 dprintk(DBG_BUFF, "%s: buf - fmt=%p, width=%3d, height=%3d, "
759                         "field=%d\n%s: fh  - fmt=%p, width=%3d, height=%3d, "
760                         "field=%d\n", __func__, buf->fmt, buf->vb.width,
761                         buf->vb.height, buf->vb.field, __func__, fh->fmt,
762                         fh->width, fh->height, field);
763                 buf->fmt       = fh->fmt;
764                 buf->vb.width  = fh->width;
765                 buf->vb.height = fh->height;
766                 buf->vb.field  = field;
767                 init_buffer = 1;        /* force risc code re-generation */
768         }
769         buf->input = dev->input;
770
771         if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
772                 rc = videobuf_iolock(q, &buf->vb, NULL);
773                 if (0 != rc)
774                         goto fail;
775                 init_buffer = 1;        /* force risc code re-generation */
776         }
777         dprintk(DBG_BUFF, "%s: q=%p, vb=%p, init_buffer=%d\n",
778                 __func__, q, vb, init_buffer);
779
780         if (init_buffer) {
781                 buf->bpl = buf->vb.width * (buf->fmt->depth) >> 3;
782                 dprintk(DBG_TESTING, "%s: Generating new risc code "
783                         "[%dx%dx%d](%d)\n", __func__, buf->vb.width,
784                         buf->vb.height, buf->fmt->depth, buf->bpl);
785                 switch (buf->vb.field) {
786                 case V4L2_FIELD_TOP:
787                         tw68_risc_buffer(dev->pci, &buf->risc,
788                                          dma->sglist,
789                                          0, UNSET,
790                                          buf->bpl, 0,
791                                          buf->vb.height);
792                         break;
793                 case V4L2_FIELD_BOTTOM:
794                         tw68_risc_buffer(dev->pci, &buf->risc,
795                                          dma->sglist,
796                                          UNSET, 0,
797                                          buf->bpl, 0,
798                                          buf->vb.height);
799                         break;
800                 case V4L2_FIELD_INTERLACED:
801                         tw68_risc_buffer(dev->pci, &buf->risc,
802                                          dma->sglist,
803                                          0, buf->bpl,
804                                          buf->bpl, buf->bpl,
805                                          buf->vb.height >> 1);
806                         break;
807                 case V4L2_FIELD_SEQ_TB:
808                         tw68_risc_buffer(dev->pci, &buf->risc,
809                                          dma->sglist,
810                                          0, buf->bpl * (buf->vb.height >> 1),
811                                          buf->bpl, 0,
812                                          buf->vb.height >> 1);
813                         break;
814                 case V4L2_FIELD_SEQ_BT:
815                         tw68_risc_buffer(dev->pci, &buf->risc,
816                                          dma->sglist,
817                                          buf->bpl * (buf->vb.height >> 1), 0,
818                                          buf->bpl, 0,
819                                          buf->vb.height >> 1);
820                         break;
821                 default:
822                         BUG();
823                 }
824         }
825         dprintk(DBG_BUFF, "%s: [%p/%d] - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
826                 __func__, buf, buf->vb.i, fh->width, fh->height,
827                 fh->fmt->depth, fh->fmt->name, (unsigned long)buf->risc.dma);
828
829         buf->vb.state = VIDEOBUF_PREPARED;
830         buf->activate = buffer_activate;
831         return 0;
832
833  fail:
834         tw68_dma_free(q, buf);
835         return rc;
836 }
837
838 /*
839  * buffer_queue
840  *
841  * Callback whenever a buffer has been requested (by read() or QBUF)
842  */
843 static void
844 buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
845 {
846         struct tw68_fh  *fh = q->priv_data;
847         struct tw68_buf *buf = container_of(vb, struct tw68_buf, vb);
848
849         tw68_buffer_queue(fh->dev, &fh->dev->video_q, buf);
850 }
851
852 /*
853  * buffer_release
854  *
855  * Free a buffer previously allocated.
856  */
857 static void buffer_release(struct videobuf_queue *q,
858                            struct videobuf_buffer *vb)
859 {
860         struct tw68_buf *buf = container_of(vb, struct tw68_buf, vb);
861
862         tw68_dma_free(q, buf);
863 }
864
865 static struct videobuf_queue_ops video_qops = {
866         .buf_setup    = buffer_setup,
867         .buf_prepare  = buffer_prepare,
868         .buf_queue    = buffer_queue,
869         .buf_release  = buffer_release,
870 };
871
872 /* ------------------------------------------------------------------ */
873
874 static int tw68_g_ctrl_internal(struct tw68_dev *dev, struct tw68_fh *fh,
875                                 struct v4l2_control *c)
876 {
877         const struct v4l2_queryctrl *ctrl;
878
879         dprintk(DBG_FLOW, "%s\n", __func__);
880         ctrl = ctrl_by_id(c->id);
881         if (NULL == ctrl)
882                 return -EINVAL;
883         switch (c->id) {
884         case V4L2_CID_BRIGHTNESS:
885                 c->value = (char)tw_readb(TW68_BRIGHT);
886                 break;
887         case V4L2_CID_HUE:
888                 c->value = (char)tw_readb(TW68_HUE);
889                 break;
890         case V4L2_CID_CONTRAST:
891                 c->value = tw_readb(TW68_CONTRAST);
892                 break;
893         case V4L2_CID_SATURATION:
894                 c->value = tw_readb(TW68_SAT_U);
895                 break;
896         case V4L2_CID_COLOR_KILLER:
897                 c->value = 0 != (tw_readb(TW68_MISC2) & 0xe0);
898                 break;
899         case V4L2_CID_CHROMA_AGC:
900                 c->value = 0 != (tw_readb(TW68_LOOP) & 0x30);
901                 break;
902         case V4L2_CID_AUDIO_MUTE:
903                 /*hack to suppresss tvtime complaint */
904                 c->value = 0;
905                 break;
906 #if 0
907         case V4L2_CID_AUDIO_VOLUME:
908                 c->value = dev->ctl_volume;
909                 break;
910 #endif
911         default:
912                 return -EINVAL;
913         }
914         return 0;
915 }
916
917 static int tw68_g_ctrl(struct file *file, void *priv, struct v4l2_control *c)
918 {
919         struct tw68_fh *fh = priv;
920
921         return tw68_g_ctrl_internal(fh->dev, fh, c);
922 }
923
924 static int tw68_s_ctrl_value(struct tw68_dev *dev, __u32 id, int val)
925 {
926         int err = 0;
927
928         dprintk(DBG_FLOW, "%s\n", __func__);
929         switch (id) {
930         case V4L2_CID_BRIGHTNESS:
931                 tw_writeb(TW68_BRIGHT, val);
932                 break;
933         case V4L2_CID_HUE:
934                 tw_writeb(TW68_HUE, val);
935                 break;
936         case V4L2_CID_CONTRAST:
937                 tw_writeb(TW68_CONTRAST, val);
938                 break;
939         case V4L2_CID_SATURATION:
940                 tw_writeb(TW68_SAT_U, val);
941                 tw_writeb(TW68_SAT_V, val);
942                 break;
943         case V4L2_CID_COLOR_KILLER:
944                 if (val)
945                         tw_andorb(TW68_MISC2, 0xe0, 0xe0);
946                 else
947                         tw_andorb(TW68_MISC2, 0xe0, 0x00);
948                 break;
949         case V4L2_CID_CHROMA_AGC:
950                 if (val)
951                         tw_andorb(TW68_LOOP, 0x30, 0x20);
952                 else
953                         tw_andorb(TW68_LOOP, 0x30, 0x00);
954                 break;
955         case V4L2_CID_AUDIO_MUTE:
956                 /* hack to suppress tvtime complaint */
957                 break;
958 #if 0
959         case V4L2_CID_AUDIO_VOLUME:
960                 dev->ctl_volume = val;
961                 tw68_tvaudio_setvolume(dev, dev->ctl_volume);
962                 break;
963         case V4L2_CID_HFLIP:
964                 dev->ctl_mirror = val;
965                 break;
966         case V4L2_CID_PRIVATE_AUTOMUTE:
967         {
968                 struct v4l2_priv_tun_config tda9887_cfg;
969
970                 tda9887_cfg.tuner = TUNER_TDA9887;
971                 tda9887_cfg.priv = &dev->tda9887_conf;
972
973                 dev->ctl_automute = val;
974                 if (dev->tda9887_conf) {
975                         if (dev->ctl_automute)
976                                 dev->tda9887_conf |= TDA9887_AUTOMUTE;
977                         else
978                                 dev->tda9887_conf &= ~TDA9887_AUTOMUTE;
979
980                         tw_call_all(dev, tuner, s_config, &tda9887_cfg);
981                 }
982                 break;
983         }
984 #endif
985         default:
986                 err = -EINVAL;
987         }
988         return err;
989 }
990
991 static int tw68_s_ctrl_internal(struct tw68_dev *dev,  struct tw68_fh *fh,
992                          struct v4l2_control *c)
993 {
994         const struct v4l2_queryctrl *ctrl;
995         int err;
996
997         dprintk(DBG_FLOW, "%s\n", __func__);
998         if (fh) {
999 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,34)
1000                 err = v4l2_prio_check(&dev->prio, &fh->prio);
1001 #else
1002                 err = v4l2_prio_check(&dev->prio, fh->prio);
1003 #endif
1004                 if (0 != err)
1005                         return err;
1006         }
1007
1008         mutex_lock(&dev->lock);
1009
1010         ctrl = ctrl_by_id(c->id);
1011         if (NULL == ctrl) {
1012                 err = -EINVAL;
1013                 goto error;
1014         }
1015
1016         dprintk(DBG_BUFF, "%s: name=%s val=%d\n", __func__,
1017                 ctrl->name, c->value);
1018         switch (ctrl->type) {
1019         case V4L2_CTRL_TYPE_BOOLEAN:
1020         case V4L2_CTRL_TYPE_MENU:
1021         case V4L2_CTRL_TYPE_INTEGER:
1022                 if (c->value < ctrl->minimum)
1023                         c->value = ctrl->minimum;
1024                 if (c->value > ctrl->maximum)
1025                         c->value = ctrl->maximum;
1026                 break;
1027         default:
1028                 /* nothing */;
1029         };
1030         err = tw68_s_ctrl_value(dev, c->id, c->value);
1031
1032 error:
1033         mutex_unlock(&dev->lock);
1034         return err;
1035 }
1036
1037 static int tw68_s_ctrl(struct file *file, void *f, struct v4l2_control *c)
1038 {
1039         struct tw68_fh *fh = f;
1040
1041         return tw68_s_ctrl_internal(fh->dev, fh, c);
1042 }
1043
1044 /* ------------------------------------------------------------------ */
1045
1046 /*
1047  * Returns a pointer to the currently used queue (e.g. video, vbi, etc.)
1048  */
1049 static struct videobuf_queue *tw68_queue(struct tw68_fh *fh)
1050 {
1051         struct videobuf_queue *q = NULL;
1052
1053         switch (fh->type) {
1054         case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1055                 q = &fh->cap;
1056                 break;
1057         case V4L2_BUF_TYPE_VBI_CAPTURE:
1058                 q = &fh->vbi;
1059                 break;
1060         default:
1061                 BUG();
1062         }
1063         return q;
1064 }
1065
1066 static int tw68_resource(struct tw68_fh *fh)
1067 {
1068         if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1069                 return RESOURCE_VIDEO;
1070
1071         if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
1072                 return RESOURCE_VBI;
1073
1074         BUG();
1075         return 0;
1076 }
1077
1078 static int video_open(struct file *file)
1079 {
1080         int minor = video_devdata(file)->minor;
1081         struct tw68_dev *dev;
1082         struct tw68_fh *fh;
1083         enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1084         int radio = 0;
1085
1086         mutex_lock(&tw68_devlist_lock);
1087         list_for_each_entry(dev, &tw68_devlist, devlist) {
1088                 if (dev->video_dev && (dev->video_dev->minor == minor))
1089                         goto found;
1090                 if (dev->radio_dev && (dev->radio_dev->minor == minor)) {
1091                         radio = 1;
1092                         goto found;
1093                 }
1094                 if (dev->vbi_dev && (dev->vbi_dev->minor == minor)) {
1095                         type = V4L2_BUF_TYPE_VBI_CAPTURE;
1096                         goto found;
1097                 }
1098         }
1099         mutex_unlock(&tw68_devlist_lock);
1100         return -ENODEV;
1101
1102 found:
1103         mutex_unlock(&tw68_devlist_lock);
1104
1105         dprintk(DBG_FLOW, "%s: minor=%d radio=%d type=%s\n", __func__, minor,
1106                 radio, v4l2_type_names[type]);
1107
1108         /* allocate + initialize per filehandle data */
1109         fh = kzalloc(sizeof(*fh), GFP_KERNEL);
1110         if (NULL == fh)
1111                 return -ENOMEM;
1112
1113         file->private_data = fh;
1114         fh->dev      = dev;
1115         fh->radio    = radio;
1116         fh->type     = type;
1117         fh->fmt      = format_by_fourcc(V4L2_PIX_FMT_BGR24);
1118         fh->width    = 720;
1119         fh->height   = 576;
1120         v4l2_prio_open(&dev->prio, &fh->prio);
1121
1122         videobuf_queue_sg_init(&fh->cap, &video_qops,
1123                             &dev->pci->dev, &dev->slock,
1124                             V4L2_BUF_TYPE_VIDEO_CAPTURE,
1125                             V4L2_FIELD_INTERLACED,
1126                             sizeof(struct tw68_buf),
1127 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,37)
1128                             fh
1129 #else
1130                             fh, &dev->lock
1131 #endif
1132              );
1133         videobuf_queue_sg_init(&fh->vbi, &tw68_vbi_qops,
1134                             &dev->pci->dev, &dev->slock,
1135                             V4L2_BUF_TYPE_VBI_CAPTURE,
1136                             V4L2_FIELD_SEQ_TB,
1137                             sizeof(struct tw68_buf),
1138 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,37)
1139                             fh
1140 #else
1141                             fh, &dev->lock
1142 #endif
1143              );
1144         if (fh->radio) {
1145                 /* switch to radio mode */
1146                 tw68_tvaudio_setinput(dev, &card(dev).radio);
1147                 tw_call_all(dev, tuner, s_radio);
1148         } else {
1149                 /* switch to video/vbi mode */
1150                 tw68_tvaudio_setinput(dev, dev->input);
1151         }
1152         return 0;
1153 }
1154
1155 static ssize_t
1156 video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
1157 {
1158         struct tw68_fh *fh = file->private_data;
1159
1160         switch (fh->type) {
1161         case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1162                 if (res_locked(fh->dev, RESOURCE_VIDEO))
1163                         return -EBUSY;
1164                 return videobuf_read_one(tw68_queue(fh),
1165                                          data, count, ppos,
1166                                          file->f_flags & O_NONBLOCK);
1167         case V4L2_BUF_TYPE_VBI_CAPTURE:
1168                 if (!res_get(fh, RESOURCE_VBI))
1169                         return -EBUSY;
1170                 return videobuf_read_stream(tw68_queue(fh),
1171                                             data, count, ppos, 1,
1172                                             file->f_flags & O_NONBLOCK);
1173                 break;
1174         default:
1175                 BUG();
1176                 return 0;
1177         }
1178 }
1179
1180 static unsigned int
1181 video_poll(struct file *file, struct poll_table_struct *wait)
1182 {
1183         struct tw68_fh *fh = file->private_data;
1184         struct videobuf_buffer *buf = NULL;
1185
1186         if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)
1187                 return videobuf_poll_stream(file, &fh->vbi, wait);
1188
1189         if (res_check(fh, RESOURCE_VIDEO)) {
1190                 if (!list_empty(&fh->cap.stream))
1191                         buf = list_entry(fh->cap.stream.next,
1192                                 struct videobuf_buffer, stream);
1193         } else {
1194                 mutex_lock(&fh->cap.vb_lock);
1195                 if (UNSET == fh->cap.read_off) {
1196                         /* need to capture a new frame */
1197                         if (res_locked(fh->dev, RESOURCE_VIDEO))
1198                                 goto err;
1199                         if (0 != fh->cap.ops->buf_prepare(&fh->cap,
1200                                         fh->cap.read_buf, fh->cap.field))
1201                                 goto err;
1202                         fh->cap.ops->buf_queue(&fh->cap, fh->cap.read_buf);
1203                         fh->cap.read_off = 0;
1204                 }
1205                 mutex_unlock(&fh->cap.vb_lock);
1206                 buf = fh->cap.read_buf;
1207         }
1208
1209         if (!buf)
1210                 return POLLERR;
1211
1212         poll_wait(file, &buf->done, wait);
1213         if (buf->state == VIDEOBUF_DONE ||
1214             buf->state == VIDEOBUF_ERROR)
1215                 return POLLIN | POLLRDNORM;
1216         return 0;
1217
1218 err:
1219         mutex_unlock(&fh->cap.vb_lock);
1220         return POLLERR;
1221 }
1222
1223 static int video_release(struct file *file)
1224 {
1225         struct tw68_fh  *fh  = file->private_data;
1226         struct tw68_dev *dev = fh->dev;
1227
1228         /* stop video capture */
1229         if (res_check(fh, RESOURCE_VIDEO)) {
1230                 videobuf_streamoff(&fh->cap);
1231                 res_free(fh , RESOURCE_VIDEO);
1232         }
1233         if (fh->cap.read_buf) {
1234                 buffer_release(&fh->cap, fh->cap.read_buf);
1235                 kfree(fh->cap.read_buf);
1236         }
1237
1238         /* stop vbi capture */
1239         if (res_check(fh, RESOURCE_VBI)) {
1240                 videobuf_stop(&fh->vbi);
1241                 res_free(fh, RESOURCE_VBI);
1242         }
1243
1244 #if 0
1245         tw_call_all(dev, core, s_standby, 0);
1246 #endif
1247
1248         /* free stuff */
1249         videobuf_mmap_free(&fh->cap);
1250         videobuf_mmap_free(&fh->vbi);
1251
1252 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,34)
1253         v4l2_prio_close(&dev->prio, &fh->prio);
1254 #else
1255         v4l2_prio_close(&dev->prio, fh->prio);
1256 #endif
1257         file->private_data = NULL;
1258         kfree(fh);
1259         return 0;
1260 }
1261
1262 static int video_mmap(struct file *file, struct vm_area_struct * vma)
1263 {
1264         struct tw68_fh *fh = file->private_data;
1265
1266         return videobuf_mmap_mapper(tw68_queue(fh), vma);
1267 }
1268
1269 /* ------------------------------------------------------------------ */
1270
1271 #if 0
1272 static int tw68_try_get_set_fmt_vbi_cap(struct file *file, void *priv,
1273                                                 struct v4l2_format *f)
1274 {
1275         struct tw68_fh *fh = priv;
1276         struct tw68_dev *dev = fh->dev;
1277         struct tw68_tvnorm *norm = dev->tvnorm;
1278
1279         f->fmt.vbi.sampling_rate = 6750000 * 4;
1280         f->fmt.vbi.samples_per_line = 2048 /* VBI_LINE_LENGTH */;
1281         f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
1282         f->fmt.vbi.offset = 64 * 4;
1283         f->fmt.vbi.start[0] = norm->vbi_v_start_0;
1284         f->fmt.vbi.count[0] = norm->vbi_v_stop_0 - norm->vbi_v_start_0 + 1;
1285         f->fmt.vbi.start[1] = norm->vbi_v_start_1;
1286         f->fmt.vbi.count[1] = f->fmt.vbi.count[0];
1287         f->fmt.vbi.flags = 0; /* VBI_UNSYNC VBI_INTERLACED */
1288
1289 #if 0
1290         if (V4L2_STD_PAL == norm->id) {
1291                 /* FIXME */
1292                 f->fmt.vbi.start[0] += 3;
1293                 f->fmt.vbi.start[1] += 3*2;
1294         }
1295 #endif
1296         return 0;
1297 }
1298 #endif
1299
1300 /*
1301  * Note that this routine returns what is stored in the fh structure, and
1302  * does not interrogate any of the device registers.
1303  */
1304 static int tw68_g_fmt_vid_cap(struct file *file, void *priv,
1305                                 struct v4l2_format *f)
1306 {
1307         struct tw68_fh *fh = priv;
1308         struct tw68_dev *dev = fh->dev;
1309
1310         dprintk(DBG_FLOW, "%s\n", __func__);
1311         f->fmt.pix.width        = fh->width;
1312         f->fmt.pix.height       = fh->height;
1313         f->fmt.pix.field        = fh->cap.field;
1314         f->fmt.pix.pixelformat  = fh->fmt->fourcc;
1315         f->fmt.pix.bytesperline =
1316                 (f->fmt.pix.width * (fh->fmt->depth)) >> 3;
1317         f->fmt.pix.sizeimage =
1318                 f->fmt.pix.height * f->fmt.pix.bytesperline;
1319         f->fmt.pix.colorspace   = V4L2_COLORSPACE_SMPTE170M;
1320         return 0;
1321 }
1322
1323 static int tw68_try_fmt_vid_cap(struct file *file, void *priv,
1324                                                 struct v4l2_format *f)
1325 {
1326         struct tw68_fh *fh = priv;
1327         struct tw68_dev *dev = fh->dev;
1328         struct tw68_format *fmt;
1329         enum v4l2_field field;
1330         unsigned int maxw, maxh;
1331
1332         dprintk(DBG_FLOW, "%s\n", __func__);
1333         fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1334         if (NULL == fmt)
1335                 return -EINVAL;
1336
1337         field = f->fmt.pix.field;
1338         maxw  = min(dev->crop_current.width*4,  dev->crop_bounds.width);
1339         maxh  = min(dev->crop_current.height*4, dev->crop_bounds.height);
1340
1341         if (V4L2_FIELD_ANY == field) {
1342                 field = (f->fmt.pix.height > maxh/2)
1343                         ? V4L2_FIELD_INTERLACED
1344                         : V4L2_FIELD_BOTTOM;
1345         }
1346         switch (field) {
1347         case V4L2_FIELD_TOP:
1348         case V4L2_FIELD_BOTTOM:
1349                 break;
1350         case V4L2_FIELD_INTERLACED:
1351                 maxh = maxh * 2;
1352                 break;
1353         default:
1354                 return -EINVAL;
1355         }
1356
1357         f->fmt.pix.field = field;
1358         if (f->fmt.pix.width  < 48)
1359                 f->fmt.pix.width  = 48;
1360         if (f->fmt.pix.height < 32)
1361                 f->fmt.pix.height = 32;
1362         if (f->fmt.pix.width > maxw)
1363                 f->fmt.pix.width = maxw;
1364         if (f->fmt.pix.height > maxh)
1365                 f->fmt.pix.height = maxh;
1366         f->fmt.pix.width &= ~0x03;
1367         f->fmt.pix.bytesperline =
1368                 (f->fmt.pix.width * (fmt->depth)) >> 3;
1369         f->fmt.pix.sizeimage =
1370                 f->fmt.pix.height * f->fmt.pix.bytesperline;
1371
1372         return 0;
1373 }
1374
1375 /*
1376  * Note that tw68_s_fmt_vid_cap sets the information into the fh structure,
1377  * and it will be used for all future new buffers.  However, there could be
1378  * some number of buffers on the "active" chain which will be filled before
1379  * the change takes place.
1380  */
1381 static int tw68_s_fmt_vid_cap(struct file *file, void *priv,
1382                                         struct v4l2_format *f)
1383 {
1384         struct tw68_fh *fh = priv;
1385         struct tw68_dev *dev = fh->dev;
1386         int err;
1387
1388         dprintk(DBG_FLOW, "%s\n", __func__);
1389         err = tw68_try_fmt_vid_cap(file, priv, f);
1390         if (0 != err)
1391                 return err;
1392
1393         fh->fmt       = format_by_fourcc(f->fmt.pix.pixelformat);
1394         fh->width     = f->fmt.pix.width;
1395         fh->height    = f->fmt.pix.height;
1396         fh->cap.field = f->fmt.pix.field;
1397         /*
1398          * The following lines are to make v4l2-test program happy.
1399          * The docs should be checked to assure they make sense.
1400          */
1401         f->fmt.pix.colorspace   = V4L2_COLORSPACE_SMPTE170M;
1402         f->fmt.pix.priv = 0;
1403         return 0;
1404 }
1405
1406 static int tw68_queryctrl(struct file *file, void *priv,
1407                           struct v4l2_queryctrl *c)
1408 {
1409         const struct v4l2_queryctrl *ctrl;
1410         struct tw68_fh *fh = priv;
1411         struct tw68_dev *dev = fh->dev;
1412
1413         dprintk(DBG_FLOW, "%s\n", __func__);
1414         if ((c->id <  V4L2_CID_BASE || c->id >= V4L2_CID_LASTP1)
1415 #if 0
1416              && (c->id <  V4L2_CID_PRIVATE_BASE ||
1417              c->id >= V4L2_CID_PRIVATE_LASTP1)
1418 #endif
1419         )
1420                 return -EINVAL;
1421         ctrl = ctrl_by_id(c->id);
1422         if (NULL == ctrl)
1423                 return -EINVAL;
1424         *c = *ctrl;
1425         return 0;
1426 }
1427
1428 static int tw68_enum_input(struct file *file, void *priv,
1429                                         struct v4l2_input *i)
1430 {
1431         struct tw68_fh *fh = priv;
1432         struct tw68_dev *dev = fh->dev;
1433         unsigned int n;
1434
1435         n = i->index;
1436         dprintk(DBG_FLOW, "%s: index is %d\n", __func__, n);
1437         if (n >= TW68_INPUT_MAX) {
1438                 dprintk(DBG_FLOW, "%s: INPUT_MAX reached\n", __func__);
1439                 return -EINVAL;
1440         }
1441         if (NULL == card_in(dev, n).name) {
1442                 dprintk(DBG_FLOW, "%s: End of list\n", __func__);
1443                 return -EINVAL;
1444         }
1445         memset(i, 0, sizeof(*i));
1446         i->index = n;
1447         i->type  = V4L2_INPUT_TYPE_CAMERA;
1448         strcpy(i->name, card_in(dev, n).name);
1449         if (card_in(dev, n).tv)
1450                 i->type = V4L2_INPUT_TYPE_TUNER;
1451         i->audioset = 1;
1452         /* If the query is for the current input, get live data */
1453         if (n == dev->hw_input->vmux) {
1454                 int v1 = tw_readb(TW68_STATUS1);
1455                 int v2 = tw_readb(TW68_MVSN);
1456
1457                 if (0 != (v1 & (1 << 7)))
1458                         i->status |= V4L2_IN_ST_NO_SYNC;
1459                 if (0 != (v1 & (1 << 6)))
1460                         i->status |= V4L2_IN_ST_NO_H_LOCK;
1461                 if (0 != (v1 & (1 << 2)))
1462                         i->status |= V4L2_IN_ST_NO_SIGNAL;
1463                 if (0 != (v1 & 1 << 1))
1464                         i->status |= V4L2_IN_ST_NO_COLOR;
1465                 if (0 != (v2 & (1 << 2)))
1466                         i->status |= V4L2_IN_ST_MACROVISION;
1467         }
1468         i->std = TW68_NORMS;
1469         return 0;
1470 }
1471
1472 static int tw68_g_input(struct file *file, void *priv, unsigned int *i)
1473 {
1474         struct tw68_fh *fh = priv;
1475         struct tw68_dev *dev = fh->dev;
1476
1477         dprintk(DBG_FLOW, "%s\n", __func__);
1478         *i = dev->input->vmux;
1479         return 0;
1480 }
1481
1482 static int tw68_s_input(struct file *file, void *priv, unsigned int i)
1483 {
1484         struct tw68_fh *fh = priv;
1485         struct tw68_dev *dev = fh->dev;
1486         int err;
1487
1488         dprintk(DBG_FLOW, "%s\n", __func__);
1489 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,34)
1490                 err = v4l2_prio_check(&dev->prio, &fh->prio);
1491 #else
1492                 err = v4l2_prio_check(&dev->prio, fh->prio);
1493 #endif
1494                 if (0 != err)
1495         if (0 != err)
1496                 return err;
1497
1498         if (i < 0  ||  i >= TW68_INPUT_MAX)
1499                 return -EINVAL;
1500         if (NULL == card_in(dev, i).name)
1501                 return -EINVAL;
1502         mutex_lock(&dev->lock);
1503         video_mux(dev, i);
1504         mutex_unlock(&dev->lock);
1505         return 0;
1506 }
1507
1508 static int tw68_querycap(struct file *file, void  *priv,
1509                                         struct v4l2_capability *cap)
1510 {
1511         struct tw68_fh *fh = priv;
1512         struct tw68_dev *dev = fh->dev;
1513
1514         unsigned int tuner_type = dev->tuner_type;
1515
1516         dprintk(DBG_FLOW, "%s\n", __func__);
1517         strcpy(cap->driver, "tw68");
1518         strlcpy(cap->card, tw68_boards[dev->board].name,
1519                 sizeof(cap->card));
1520         sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
1521         cap->version = TW68_VERSION_CODE;
1522         cap->capabilities =
1523                 V4L2_CAP_VIDEO_CAPTURE |
1524                 V4L2_CAP_VBI_CAPTURE |
1525                 V4L2_CAP_READWRITE |
1526                 V4L2_CAP_STREAMING |
1527                 V4L2_CAP_TUNER;
1528
1529         if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET))
1530                 cap->capabilities &= ~V4L2_CAP_TUNER;
1531         return 0;
1532 }
1533
1534 static int tw68_s_std_internal(struct tw68_dev *dev, struct tw68_fh *fh,
1535                         v4l2_std_id *id)
1536 {
1537 /*      unsigned long flags; */
1538         unsigned int i;
1539         v4l2_std_id fixup;
1540         int err;
1541
1542         dprintk(DBG_FLOW, "%s\n", __func__);
1543         if (fh) {
1544 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,34)
1545                 err = v4l2_prio_check(&dev->prio, &fh->prio);
1546 #else
1547                 err = v4l2_prio_check(&dev->prio, fh->prio);
1548 #endif
1549                 if (0 != err)
1550                 if (0 != err)
1551                         return err;
1552         }
1553
1554         /* Look for match on complete norm id (may have mult bits) */
1555         for (i = 0; i < TVNORMS; i++) {
1556                 if (*id == tvnorms[i].id)
1557                         break;
1558         }
1559
1560         /* If no exact match, look for norm which contains this one */
1561         if (i == TVNORMS)
1562                 for (i = 0; i < TVNORMS; i++) {
1563                         if (*id & tvnorms[i].id)
1564                                 break;
1565                 }
1566         /* If still not matched, give up */
1567         if (i == TVNORMS)
1568                 return -EINVAL;
1569
1570         /* TODO - verify this additional work with SECAM applies to TW */
1571         if ((*id & V4L2_STD_SECAM) && (secam[0] != '-')) {
1572                 if (secam[0] == 'L' || secam[0] == 'l') {
1573                         if (secam[1] == 'C' || secam[1] == 'c')
1574                                 fixup = V4L2_STD_SECAM_LC;
1575                         else
1576                                 fixup = V4L2_STD_SECAM_L;
1577                 } else {
1578                         if (secam[0] == 'D' || secam[0] == 'd')
1579                                 fixup = V4L2_STD_SECAM_DK;
1580                         else
1581                                 fixup = V4L2_STD_SECAM;
1582                 }
1583                 for (i = 0; i < TVNORMS; i++)
1584                         if (fixup == tvnorms[i].id)
1585                                 break;
1586         }
1587
1588         *id = tvnorms[i].id;
1589         mutex_lock(&dev->lock);
1590         set_tvnorm(dev, &tvnorms[i]);   /* do the actual setting */
1591         tw68_tvaudio_do_scan(dev);
1592         mutex_unlock(&dev->lock);
1593         return 0;
1594 }
1595
1596 static int tw68_s_std(struct file *file, void *priv, v4l2_std_id *id)
1597 {
1598         struct tw68_fh *fh = priv;
1599         struct tw68_dev *dev = fh->dev;
1600
1601         dprintk(DBG_FLOW, "%s\n", __func__);
1602         return tw68_s_std_internal(fh->dev, fh, id);
1603 }
1604
1605 static int tw68_g_std(struct file *file, void *priv, v4l2_std_id *id)
1606 {
1607         struct tw68_fh *fh = priv;
1608         struct tw68_dev *dev = fh->dev;
1609
1610         dprintk(DBG_FLOW, "%s\n", __func__);
1611         *id = dev->tvnorm->id;
1612         return 0;
1613 }
1614
1615 static int tw68_g_tuner(struct file *file, void *priv,
1616                                         struct v4l2_tuner *t)
1617 {
1618         struct tw68_fh *fh = priv;
1619         struct tw68_dev *dev = fh->dev;
1620         int n;
1621
1622         if (unlikely(UNSET == dev->tuner_type))
1623                 return -EINVAL;
1624         if (0 != t->index)
1625                 return -EINVAL;
1626         memset(t, 0, sizeof(*t));
1627         for (n = 0; n < TW68_INPUT_MAX; n++)
1628                 if (card_in(dev, n).tv)
1629                         break;
1630         if (n == TW68_INPUT_MAX)
1631                 return -EINVAL;
1632 #if 0
1633         if (NULL != card_in(dev, n).name) {
1634                 strcpy(t->name, "Television");
1635                 t->type = V4L2_TUNER_ANALOG_TV;
1636                 t->capability = V4L2_TUNER_CAP_NORM |
1637                         V4L2_TUNER_CAP_STEREO |
1638                         V4L2_TUNER_CAP_LANG1 |
1639                         V4L2_TUNER_CAP_LANG2;
1640                 t->rangehigh = 0xffffffffUL;
1641                 t->rxsubchans = tw68_tvaudio_getstereo(dev);
1642                 t->audmode = tw68_tvaudio_rx2mode(t->rxsubchans);
1643         }
1644         if (0 != (saa_readb(TW68_STATUS_VIDEO1) & 0x03))
1645                 t->signal = 0xffff;
1646 #endif
1647         return 0;
1648 }
1649
1650 static int tw68_s_tuner(struct file *file, void *priv,
1651                                         struct v4l2_tuner *t)
1652 {
1653         struct tw68_fh *fh = priv;
1654         struct tw68_dev *dev = fh->dev;
1655         int err;
1656 #if 0
1657         int rx, mode
1658 #endif
1659
1660 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,34)
1661                 err = v4l2_prio_check(&dev->prio, &fh->prio);
1662 #else
1663                 err = v4l2_prio_check(&dev->prio, fh->prio);
1664 #endif
1665                 if (0 != err)
1666         if (0 != err)
1667                 return err;
1668
1669 #if 0
1670         mode = dev->thread.mode;
1671         if (UNSET == mode) {
1672                 rx   = tw68_tvaudio_getstereo(dev);
1673                 mode = tw68_tvaudio_rx2mode(t->rxsubchans);
1674         }
1675         if (mode != t->audmode)
1676                 dev->thread.mode = t->audmode;
1677 #endif
1678         return 0;
1679 }
1680
1681 static int tw68_g_frequency(struct file *file, void *priv,
1682                                         struct v4l2_frequency *f)
1683 {
1684         struct tw68_fh *fh = priv;
1685         struct tw68_dev *dev = fh->dev;
1686
1687         if (unlikely(dev->tuner_type))
1688                 return -EINVAL;
1689         f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1690 /*      f->frequency = dev->ctl_freq; */
1691
1692         return 0;
1693 }
1694
1695 static int tw68_s_frequency(struct file *file, void *priv,
1696                                         struct v4l2_frequency *f)
1697 {
1698         struct tw68_fh *fh = priv;
1699         struct tw68_dev *dev = fh->dev;
1700         int err;
1701
1702         if (unlikely(UNSET == dev->tuner_type))
1703                 return -EINVAL;
1704 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,34)
1705                 err = v4l2_prio_check(&dev->prio, &fh->prio);
1706 #else
1707                 err = v4l2_prio_check(&dev->prio, fh->prio);
1708 #endif
1709                 if (0 != err)
1710         if (0 != err)
1711                 return err;
1712
1713         if (0 != f->tuner)
1714                 return -EINVAL;
1715         if (0 == fh->radio && V4L2_TUNER_ANALOG_TV != f->type)
1716                 return -EINVAL;
1717         if (1 == fh->radio && V4L2_TUNER_RADIO != f->type)
1718                 return -EINVAL;
1719         mutex_lock(&dev->lock);
1720 /*      dev->ctl_freq = f->frequency; */
1721
1722         tw_call_all(dev, tuner, s_frequency, f);
1723
1724         tw68_tvaudio_do_scan(dev);
1725         mutex_unlock(&dev->lock);
1726         return 0;
1727 }
1728
1729 static int tw68_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
1730 {
1731         strcpy(a->name, "audio");
1732         return 0;
1733 }
1734
1735 static int tw68_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
1736 {
1737         return 0;
1738 }
1739
1740 static int tw68_g_priority(struct file *file, void *f, enum v4l2_priority *p)
1741 {
1742         struct tw68_fh *fh = f;
1743         struct tw68_dev *dev = fh->dev;
1744
1745         dprintk(DBG_FLOW, "%s\n", __func__);
1746         *p = v4l2_prio_max(&dev->prio);
1747         return 0;
1748 }
1749
1750 static int tw68_s_priority(struct file *file, void *f,
1751                                         enum v4l2_priority prio)
1752 {
1753         struct tw68_fh *fh = f;
1754         struct tw68_dev *dev = fh->dev;
1755
1756         dprintk(DBG_FLOW, "%s\n", __func__);
1757         return v4l2_prio_change(&dev->prio, &fh->prio, prio);
1758 }
1759
1760 static int tw68_enum_fmt_vid_cap(struct file *file, void  *priv,
1761                                         struct v4l2_fmtdesc *f)
1762 {
1763         struct tw68_fh *fh = priv;
1764         struct tw68_dev *dev = fh->dev;
1765
1766         dprintk(DBG_FLOW, "%s\n", __func__);
1767         if (f->index >= FORMATS)
1768                 return -EINVAL;
1769
1770         strlcpy(f->description, formats[f->index].name,
1771                 sizeof(f->description));
1772
1773         f->pixelformat = formats[f->index].fourcc;
1774
1775         return 0;
1776 }
1777
1778 static int tw68_cropcap(struct file *file, void *priv,
1779                                         struct v4l2_cropcap *cap)
1780 {
1781         struct tw68_fh *fh = priv;
1782         struct tw68_dev *dev = fh->dev;
1783
1784         dprintk(DBG_FLOW, "%s\n", __func__);
1785         if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1786                 return -EINVAL;
1787         cap->bounds  = dev->crop_bounds;
1788         cap->defrect = dev->crop_defrect;
1789         cap->pixelaspect.numerator   = 1;
1790         cap->pixelaspect.denominator = 1;
1791         if (dev->tvnorm->id & V4L2_STD_525_60) {
1792                 cap->pixelaspect.numerator   = 11;
1793                 cap->pixelaspect.denominator = 10;
1794         }
1795         if (dev->tvnorm->id & V4L2_STD_625_50) {
1796                 cap->pixelaspect.numerator   = 54;
1797                 cap->pixelaspect.denominator = 59;
1798         }
1799         return 0;
1800 }
1801
1802 static int tw68_g_crop(struct file *file, void *f, struct v4l2_crop *crop)
1803 {
1804         struct tw68_fh *fh = f;
1805         struct tw68_dev *dev = fh->dev;
1806
1807         dprintk(DBG_FLOW, "%s\n", __func__);
1808         if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1809                 return -EINVAL;
1810         crop->c = dev->crop_current;
1811         return 0;
1812 }
1813
1814 static int tw68_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
1815 {
1816         struct tw68_fh *fh = f;
1817         struct tw68_dev *dev = fh->dev;
1818         struct v4l2_rect *b = &dev->crop_bounds;
1819
1820         dprintk(DBG_FLOW, "%s\n", __func__);
1821         if (res_locked(fh->dev, RESOURCE_VIDEO))
1822                 return -EBUSY;
1823
1824         if ((crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) ||
1825             (crop->c.height < 0) || (crop->c.width < 0)) {
1826                 dprintk(DBG_UNEXPECTED, "%s: invalid request\n", __func__);
1827                 return -EINVAL;
1828         }
1829
1830         if (crop->c.top < b->top)
1831                 crop->c.top = b->top;
1832         if (crop->c.top > b->top + b->height)
1833                 crop->c.top = b->top + b->height;
1834         if (crop->c.height > b->top - crop->c.top + b->height)
1835                 crop->c.height = b->top - crop->c.top + b->height;
1836
1837         if (crop->c.left < b->left)
1838                 crop->c.left = b->left;
1839         if (crop->c.left > b->left + b->width)
1840                 crop->c.left = b->left + b->width;
1841         if (crop->c.width > b->left - crop->c.left + b->width)
1842                 crop->c.width = b->left - crop->c.left + b->width;
1843
1844         dprintk(DBG_FLOW, "%s: setting cropping rectangle: top=%d, left=%d, "
1845                     "width=%d, height=%d\n", __func__, crop->c.top,
1846                     crop->c.left, crop->c.width, crop->c.height);
1847         dev->crop_current = crop->c;
1848         return 0;
1849 }
1850
1851 /*
1852  * Wrappers for the v4l2_ioctl_ops functions
1853  */
1854 #ifdef CONFIG_VIDEO_V4L1_COMPAT
1855 static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
1856 {
1857         struct tw68_fh *fh = file->private_data;
1858         return videobuf_cgmbuf(tw68_queue(fh), mbuf, 8);
1859 }
1860 #endif
1861
1862 static int tw68_reqbufs(struct file *file, void *priv,
1863                                         struct v4l2_requestbuffers *p)
1864 {
1865         struct tw68_fh *fh = priv;
1866         return videobuf_reqbufs(tw68_queue(fh), p);
1867 }
1868
1869 static int tw68_querybuf(struct file *file, void *priv,
1870                                         struct v4l2_buffer *b)
1871 {
1872         struct tw68_fh *fh = priv;
1873         return videobuf_querybuf(tw68_queue(fh), b);
1874 }
1875
1876 static int tw68_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
1877 {
1878         struct tw68_fh *fh = priv;
1879         return videobuf_qbuf(tw68_queue(fh), b);
1880 }
1881
1882 static int tw68_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
1883 {
1884         struct tw68_fh *fh = priv;
1885         return videobuf_dqbuf(tw68_queue(fh), b,
1886                                 file->f_flags & O_NONBLOCK);
1887 }
1888
1889 static int tw68_streamon(struct file *file, void *priv,
1890                                         enum v4l2_buf_type type)
1891 {
1892         struct tw68_fh *fh = priv;
1893         struct tw68_dev *dev = fh->dev;
1894         int res = tw68_resource(fh);
1895
1896         dprintk(DBG_FLOW, "%s\n", __func__);
1897         if (!res_get(fh, res))
1898                 return -EBUSY;
1899
1900         tw68_buffer_requeue(dev, &dev->video_q);
1901         return videobuf_streamon(tw68_queue(fh));
1902 }
1903
1904 static int tw68_streamoff(struct file *file, void *priv,
1905                                         enum v4l2_buf_type type)
1906 {
1907         int err;
1908         struct tw68_fh *fh = priv;
1909         struct tw68_dev *dev = fh->dev;
1910         int res = tw68_resource(fh);
1911
1912         dprintk(DBG_FLOW, "%s\n", __func__);
1913         err = videobuf_streamoff(tw68_queue(fh));
1914         if (err < 0)
1915                 return err;
1916         res_free(fh, res);
1917         return 0;
1918 }
1919
1920 #ifdef CONFIG_VIDEO_ADV_DEBUG
1921 /*
1922  * Used strictly for internal development and debugging, this routine
1923  * prints out the current register contents for the tw68xx device.
1924  */
1925 static void tw68_dump_regs(struct tw68_dev *dev)
1926 {
1927         unsigned char line[80];
1928         int i, j, k;
1929         unsigned char *cptr;
1930
1931         printk(KERN_DEBUG "Full dump of TW68 registers:\n");
1932         /* First we do the PCI regs, 8 4-byte regs per line */
1933         for (i = 0; i < 0x100; i += 32) {
1934                 cptr = line;
1935                 cptr += sprintf(cptr, "%03x  ", i);
1936                 /* j steps through the next 4 words */
1937                 for (j = i; j < i + 16; j += 4)
1938                         cptr += sprintf(cptr, "%08x ", tw_readl(j));
1939                 *cptr++ = ' ';
1940                 for (; j < i + 32; j += 4)
1941                         cptr += sprintf(cptr, "%08x ", tw_readl(j));
1942                 *cptr++ = '\n';
1943                 *cptr = 0;
1944                 printk(KERN_DEBUG "%s", line);
1945         }
1946         /* Next the control regs, which are single-byte, address mod 4 */
1947         while (i < 0x400) {
1948                 cptr = line;
1949                 cptr += sprintf(cptr, "%03x ", i);
1950                 /* Print out 4 groups of 4 bytes */
1951                 for (j = 0; j < 4; j++) {
1952                         for (k = 0; k < 4; k++) {
1953                                 cptr += sprintf(cptr, "%02x ",
1954                                         tw_readb(i));
1955                                 i += 4;
1956                         }
1957                         *cptr++ = ' ';
1958                 }
1959                 *cptr++ = '\n';
1960                 *cptr = 0;
1961                 printk(KERN_DEBUG "%s", line);
1962         }
1963 }
1964
1965 static int vidioc_log_status(struct file *file, void *priv)
1966 {
1967         struct tw68_fh *fh = priv;
1968         struct tw68_dev *dev = fh->dev;
1969
1970         tw68_dump_regs(dev);
1971         return 0;
1972 }
1973
1974 static int vidioc_g_register(struct file *file, void *priv,
1975                               struct v4l2_dbg_register *reg)
1976 {
1977         struct tw68_fh *fh = priv;
1978         struct tw68_dev *dev = fh->dev; /* needed for tw_readb */
1979
1980         dprintk(DBG_FLOW, "%s\n", __func__);
1981         if (!v4l2_chip_match_host(&reg->match))
1982                 dprintk(DBG_UNEXPECTED, "%s: match failed\n", __func__);
1983                 return -EINVAL;
1984         if (reg->size == 1)
1985                 reg->val = tw_readb(reg->reg);
1986         else
1987                 reg->val = tw_readl(reg->reg);
1988         return 0;
1989 }
1990
1991 static int vidioc_s_register(struct file *file, void *priv,
1992                                 struct v4l2_dbg_register *reg)
1993 {
1994         struct tw68_fh *fh = priv;
1995         struct tw68_dev *dev = fh->dev; /* needed for tw_writeb */
1996
1997         dprintk(DBG_FLOW, "%s: request to set reg 0x%04x to 0x%02x\n",
1998                 __func__, (unsigned int)reg->reg, (unsigned int)reg->val);
1999         if (!v4l2_chip_match_host(&reg->match)) {
2000                 dprintk(DBG_UNEXPECTED, "%s: match failed\n", __func__);
2001                 return -EINVAL;
2002         }
2003         if (reg->size == 1)
2004                 tw_writeb(reg->reg, reg->val);
2005         else
2006                 tw_writel(reg->reg & 0xffff, reg->val);
2007         return 0;
2008 }
2009 #endif
2010
2011 static const struct v4l2_file_operations video_fops = {
2012         .owner                  = THIS_MODULE,
2013         .open                   = video_open,
2014         .release                = video_release,
2015         .read                   = video_read,
2016         .poll                   = video_poll,
2017         .mmap                   = video_mmap,
2018         .ioctl                  = video_ioctl2,
2019 };
2020
2021 static const struct v4l2_ioctl_ops video_ioctl_ops = {
2022         .vidioc_querycap                = tw68_querycap,
2023         .vidioc_enum_fmt_vid_cap        = tw68_enum_fmt_vid_cap,
2024         .vidioc_reqbufs                 = tw68_reqbufs,
2025         .vidioc_querybuf                = tw68_querybuf,
2026         .vidioc_qbuf                    = tw68_qbuf,
2027         .vidioc_dqbuf                   = tw68_dqbuf,
2028         .vidioc_s_std                   = tw68_s_std,
2029         .vidioc_g_std                   = tw68_g_std,
2030         .vidioc_enum_input              = tw68_enum_input,
2031         .vidioc_g_input                 = tw68_g_input,
2032         .vidioc_s_input                 = tw68_s_input,
2033         .vidioc_queryctrl               = tw68_queryctrl,
2034         .vidioc_g_ctrl                  = tw68_g_ctrl,
2035         .vidioc_s_ctrl                  = tw68_s_ctrl,
2036         .vidioc_streamon                = tw68_streamon,
2037         .vidioc_streamoff               = tw68_streamoff,
2038         .vidioc_g_priority              = tw68_g_priority,
2039         .vidioc_s_priority              = tw68_s_priority,
2040         .vidioc_g_fmt_vid_cap           = tw68_g_fmt_vid_cap,
2041         .vidioc_try_fmt_vid_cap         = tw68_try_fmt_vid_cap,
2042         .vidioc_s_fmt_vid_cap           = tw68_s_fmt_vid_cap,
2043         .vidioc_cropcap                 = tw68_cropcap,
2044         .vidioc_g_crop                  = tw68_g_crop,
2045         .vidioc_s_crop                  = tw68_s_crop,
2046 /*
2047  * Functions not yet implemented / not yet passing tests.
2048  */
2049
2050 #if 0
2051         .vidioc_g_fmt_vbi_cap           = tw68_try_get_set_fmt_vbi_cap,
2052         .vidioc_try_fmt_vbi_cap         = tw68_try_get_set_fmt_vbi_cap,
2053         .vidioc_s_fmt_vbi_cap           = tw68_try_get_set_fmt_vbi_cap,
2054 #endif
2055         .vidioc_g_audio                 = tw68_g_audio,
2056         .vidioc_s_audio                 = tw68_s_audio,
2057         .vidioc_g_tuner                 = tw68_g_tuner,
2058         .vidioc_s_tuner                 = tw68_s_tuner,
2059         .vidioc_g_frequency             = tw68_g_frequency,
2060         .vidioc_s_frequency             = tw68_s_frequency,
2061 #ifdef CONFIG_VIDEO_V4L1_COMPAT
2062         .vidiocgmbuf                    = vidiocgmbuf,
2063 #endif
2064 #ifdef CONFIG_VIDEO_ADV_DEBUG
2065         .vidioc_log_status              = vidioc_log_status,
2066         .vidioc_g_register              = vidioc_g_register,
2067         .vidioc_s_register              = vidioc_s_register,
2068 #endif
2069 };
2070
2071 /* ------------------------------------------------------------------ */
2072 /* exported stuff                                                     */
2073 struct video_device tw68_video_template = {
2074         .name                   = "tw68_video",
2075         .fops                   = &video_fops,
2076         .ioctl_ops              = &video_ioctl_ops,
2077         .minor                  = -1,
2078         .tvnorms                = TW68_NORMS,
2079         .current_norm           = V4L2_STD_PAL,
2080 };
2081
2082 struct video_device tw68_radio_template = {
2083         .name                   = "tw68_radio",
2084 };
2085
2086 int tw68_videoport_init(struct tw68_dev *dev)
2087 {
2088         return 0;
2089 }
2090
2091 void tw68_set_tvnorm_hw(struct tw68_dev *dev)
2092 {
2093         tw_andorb(TW68_SDT, 0x07, dev->tvnorm->format);
2094         return;
2095 }
2096
2097 int tw68_video_init1(struct tw68_dev *dev)
2098 {
2099         int i;
2100
2101         dprintk(DBG_FLOW, "%s\n", __func__);
2102         /* sanitycheck insmod options */
2103         if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME)
2104                 gbuffers = 2;
2105         if (gbufsz < 0 || gbufsz > gbufsz_max)
2106                 gbufsz = gbufsz_max;
2107         gbufsz = (gbufsz + PAGE_SIZE - 1) & PAGE_MASK;
2108
2109         /* put some sensible defaults into the data structures ... */
2110         for (i = 0; i < CTRLS; i++)
2111                 tw68_s_ctrl_value(dev, video_ctrls[i].id,
2112                                   video_ctrls[i].default_value);
2113 #if 0
2114         if (dev->tda9887_conf && dev->ctl_automute)
2115                 dev->tda9887_conf |= TDA9887_AUTOMUTE;
2116         dev->automute       = 0;
2117 #endif
2118         INIT_LIST_HEAD(&dev->video_q.queued);
2119         INIT_LIST_HEAD(&dev->video_q.active);
2120         init_timer(&dev->video_q.timeout);
2121         dev->video_q.timeout.function   = tw68_buffer_timeout;
2122         dev->video_q.timeout.data       = (unsigned long)(&dev->video_q);
2123         dev->video_q.dev                = dev;
2124         dev->video_q.buf_compat         = tw68_check_video_fmt;
2125         dev->video_q.start_dma          = tw68_video_start_dma;
2126         tw68_risc_stopper(dev->pci, &dev->video_q.stopper);
2127
2128         if (tw68_boards[dev->board].video_out)
2129                 tw68_videoport_init(dev);
2130
2131         return 0;
2132 }
2133
2134 int tw68_video_init2(struct tw68_dev *dev)
2135 {
2136         dprintk(DBG_FLOW, "%s\n", __func__);
2137         set_tvnorm(dev, &tvnorms[0]);
2138         video_mux(dev, 0);
2139 /*
2140         tw68_tvaudio_setmut(dev);
2141         tw68_tvaudio_setvolume(dev, dev->ctl_volume);
2142 */
2143         return 0;
2144 }
2145
2146 /*
2147  * tw68_irq_video_signalchange
2148  *
2149  * TODO:
2150  * Check for presence of video signal.  If not present, mute audio.
2151  * If present, log type of signal present.
2152  */
2153 void tw68_irq_video_signalchange(struct tw68_dev *dev)
2154 {
2155         return;
2156 }
2157
2158 /*
2159  * tw68_irq_video_done
2160  */
2161 void tw68_irq_video_done(struct tw68_dev *dev, unsigned long status)
2162 {
2163         __u32 reg;
2164
2165         /* reset interrupts handled by this routine */
2166         tw_writel(TW68_INTSTAT, status);
2167         /*
2168          * Check most likely first
2169          *
2170          * DMAPI shows we have reached the end of the risc code
2171          * for the current buffer.
2172          */
2173         if (status & TW68_DMAPI) {
2174                 struct tw68_dmaqueue *q = &dev->video_q;
2175                 dprintk(DBG_FLOW | DBG_TESTING, "DMAPI interrupt\n");
2176                 spin_lock(&dev->slock);
2177                 /*
2178                  * tw68_wakeup will take care of the buffer handling,
2179                  * plus any non-video requirements.
2180                  */
2181                 tw68_wakeup(q, &dev->video_fieldcount);
2182                 spin_unlock(&dev->slock);
2183                 /* Check whether we have gotten into 'stopper' code */
2184                 reg = tw_readl(TW68_DMAP_PP);
2185                 if ((reg >= q->stopper.dma) &&
2186                     (reg < q->stopper.dma + q->stopper.size)) {
2187                         /* Yes - log the information */
2188                         dprintk(DBG_FLOW | DBG_TESTING,
2189                                 "%s: stopper risc code entered\n", __func__);
2190                 }
2191                 status &= ~(TW68_DMAPI);
2192                 if (0 == status)
2193                         return;
2194         }
2195         if (status & (TW68_VLOCK | TW68_HLOCK)) { /* lost sync */
2196                 dprintk(DBG_UNUSUAL, "Lost sync\n");
2197         }
2198         if (status & TW68_PABORT) {     /* TODO - what should we do? */
2199                 dprintk(DBG_UNEXPECTED, "PABORT interrupt\n");
2200         }
2201         if (status & TW68_DMAPERR) {
2202                 dprintk(DBG_UNEXPECTED, "DMAPERR interrupt\n");
2203 #if 0
2204                 /* Stop risc & fifo */
2205                 tw_clearl(TW68_DMAC, TW68_DMAP_EN | TW68_FIFO_EN);
2206                 tw_clearl(TW68_INTMASK, dev->board_virqmask);
2207                 dev->pci_irqmask &= ~dev->board_virqmask;
2208 #endif
2209         }
2210         /*
2211          * On TW6800, FDMIS is apparently generated if video input is switched
2212          * during operation.  Therefore, it is not enabled for that chip.
2213          */
2214         if (status & TW68_FDMIS) {      /* logic error somewhere */
2215                 dprintk(DBG_UNEXPECTED, "FDMIS interrupt\n");
2216                 /* Stop risc & fifo */
2217 //              tw_clearl(TW68_DMAC, TW68_DMAP_EN | TW68_FIFO_EN);
2218 //              tw_clearl(TW68_INTMASK, dev->board_virqmask);
2219 //              dev->pci_irqmask &= ~dev->board_virqmask;
2220         }
2221         if (status & TW68_FFOF) {       /* probably a logic error */
2222                 reg = tw_readl(TW68_DMAC) & TW68_FIFO_EN;
2223                 tw_clearl(TW68_DMAC, TW68_FIFO_EN);
2224                 dprintk(DBG_UNUSUAL, "FFOF interrupt\n");
2225                 tw_setl(TW68_DMAC, reg);
2226         }
2227         if (status & TW68_FFERR)
2228                 dprintk(DBG_UNEXPECTED, "FFERR interrupt\n");
2229         return;
2230 }