[media] saa7164: Don't use typedefs
[firefly-linux-kernel-4.4.55.git] / drivers / media / video / saa7164 / saa7164-vbi.c
1 /*
2  *  Driver for the NXP SAA7164 PCIe bridge
3  *
4  *  Copyright (c) 2010 Steven Toth <stoth@kernellabs.com>
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21
22 #include "saa7164.h"
23
24 static struct saa7164_tvnorm saa7164_tvnorms[] = {
25         {
26                 .name      = "NTSC-M",
27                 .id        = V4L2_STD_NTSC_M,
28         }, {
29                 .name      = "NTSC-JP",
30                 .id        = V4L2_STD_NTSC_M_JP,
31         }
32 };
33
34 static const u32 saa7164_v4l2_ctrls[] = {
35         0
36 };
37
38 /* Take the encoder configuration from the port struct and
39  * flush it to the hardware.
40  */
41 static void saa7164_vbi_configure(struct saa7164_port *port)
42 {
43         struct saa7164_dev *dev = port->dev;
44         dprintk(DBGLVL_VBI, "%s()\n", __func__);
45
46         port->vbi_params.width = port->width;
47         port->vbi_params.height = port->height;
48         port->vbi_params.is_50hz =
49                 (port->encodernorm.id & V4L2_STD_625_50) != 0;
50
51         /* Set up the DIF (enable it) for analog mode by default */
52         saa7164_api_initialize_dif(port);
53
54 //      /* Configure the correct video standard */
55 //      saa7164_api_configure_dif(port, port->encodernorm.id);
56
57 //      /* Ensure the audio decoder is correct configured */
58 //      saa7164_api_set_audio_std(port);
59         dprintk(DBGLVL_VBI, "%s() ends\n", __func__);
60 }
61
62 static int saa7164_vbi_buffers_dealloc(struct saa7164_port *port)
63 {
64         struct list_head *c, *n, *p, *q, *l, *v;
65         struct saa7164_dev *dev = port->dev;
66         struct saa7164_buffer *buf;
67         struct saa7164_user_buffer *ubuf;
68
69         /* Remove any allocated buffers */
70         mutex_lock(&port->dmaqueue_lock);
71
72         dprintk(DBGLVL_VBI, "%s(port=%d) dmaqueue\n", __func__, port->nr);
73         list_for_each_safe(c, n, &port->dmaqueue.list) {
74                 buf = list_entry(c, struct saa7164_buffer, list);
75                 list_del(c);
76                 saa7164_buffer_dealloc(buf);
77         }
78
79         dprintk(DBGLVL_VBI, "%s(port=%d) used\n", __func__, port->nr);
80         list_for_each_safe(p, q, &port->list_buf_used.list) {
81                 ubuf = list_entry(p, struct saa7164_user_buffer, list);
82                 list_del(p);
83                 saa7164_buffer_dealloc_user(ubuf);
84         }
85
86         dprintk(DBGLVL_VBI, "%s(port=%d) free\n", __func__, port->nr);
87         list_for_each_safe(l, v, &port->list_buf_free.list) {
88                 ubuf = list_entry(l, struct saa7164_user_buffer, list);
89                 list_del(l);
90                 saa7164_buffer_dealloc_user(ubuf);
91         }
92
93         mutex_unlock(&port->dmaqueue_lock);
94         dprintk(DBGLVL_VBI, "%s(port=%d) done\n", __func__, port->nr);
95
96         return 0;
97 }
98
99 /* Dynamic buffer switch at vbi start time */
100 static int saa7164_vbi_buffers_alloc(struct saa7164_port *port)
101 {
102         struct saa7164_dev *dev = port->dev;
103         struct saa7164_buffer *buf;
104         struct saa7164_user_buffer *ubuf;
105         struct tmHWStreamParameters *params = &port->hw_streamingparams;
106         int result = -ENODEV, i;
107         int len = 0;
108
109         dprintk(DBGLVL_VBI, "%s()\n", __func__);
110
111         /* TODO: NTSC SPECIFIC */
112         /* Init and establish defaults */
113         params->samplesperline = 1440;
114         params->numberoflines = 12;
115         params->numberoflines = 18;
116         params->pitch = 1600;
117         params->pitch = 1440;
118         params->numpagetables = 2 +
119                 ((params->numberoflines * params->pitch) / PAGE_SIZE);
120         params->bitspersample = 8;
121         params->linethreshold = 0;
122         params->pagetablelistvirt = 0;
123         params->pagetablelistphys = 0;
124         params->numpagetableentries = port->hwcfg.buffercount;
125
126         /* Allocate the PCI resources, buffers (hard) */
127         for (i = 0; i < port->hwcfg.buffercount; i++) {
128                 buf = saa7164_buffer_alloc(port,
129                         params->numberoflines *
130                         params->pitch);
131
132                 if (!buf) {
133                         printk(KERN_ERR "%s() failed "
134                                "(errno = %d), unable to allocate buffer\n",
135                                 __func__, result);
136                         result = -ENOMEM;
137                         goto failed;
138                 } else {
139
140                         mutex_lock(&port->dmaqueue_lock);
141                         list_add_tail(&buf->list, &port->dmaqueue.list);
142                         mutex_unlock(&port->dmaqueue_lock);
143
144                 }
145         }
146
147         /* Allocate some kenrel kernel buffers for copying
148          * to userpsace.
149          */
150         len = params->numberoflines * params->pitch;
151
152         if (vbi_buffers < 16)
153                 vbi_buffers = 16;
154         if (vbi_buffers > 512)
155                 vbi_buffers = 512;
156
157         for (i = 0; i < vbi_buffers; i++) {
158
159                 ubuf = saa7164_buffer_alloc_user(dev, len);
160                 if (ubuf) {
161                         mutex_lock(&port->dmaqueue_lock);
162                         list_add_tail(&ubuf->list, &port->list_buf_free.list);
163                         mutex_unlock(&port->dmaqueue_lock);
164                 }
165
166         }
167
168         result = 0;
169
170 failed:
171         return result;
172 }
173
174
175 static int saa7164_vbi_initialize(struct saa7164_port *port)
176 {
177         saa7164_vbi_configure(port);
178         return 0;
179 }
180
181 /* -- V4L2 --------------------------------------------------------- */
182 static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id)
183 {
184         struct saa7164_vbi_fh *fh = file->private_data;
185         struct saa7164_port *port = fh->port;
186         struct saa7164_dev *dev = port->dev;
187         unsigned int i;
188
189         dprintk(DBGLVL_VBI, "%s(id=0x%x)\n", __func__, (u32)*id);
190
191         for (i = 0; i < ARRAY_SIZE(saa7164_tvnorms); i++) {
192                 if (*id & saa7164_tvnorms[i].id)
193                         break;
194         }
195         if (i == ARRAY_SIZE(saa7164_tvnorms))
196                 return -EINVAL;
197
198         port->encodernorm = saa7164_tvnorms[i];
199
200         /* Update the audio decoder while is not running in
201          * auto detect mode.
202          */
203         saa7164_api_set_audio_std(port);
204
205         dprintk(DBGLVL_VBI, "%s(id=0x%x) OK\n", __func__, (u32)*id);
206
207         return 0;
208 }
209
210 static int vidioc_enum_input(struct file *file, void *priv,
211         struct v4l2_input *i)
212 {
213         int n;
214
215         char *inputs[] = { "tuner", "composite", "svideo", "aux",
216                 "composite", "svideo", "aux" };
217
218         if (i->index >= 7)
219                 return -EINVAL;
220
221         strcpy(i->name, inputs[ i->index ]);
222
223         if (i->index == 0)
224                 i->type = V4L2_INPUT_TYPE_TUNER;
225         else
226                 i->type  = V4L2_INPUT_TYPE_CAMERA;
227
228         for (n = 0; n < ARRAY_SIZE(saa7164_tvnorms); n++)
229                 i->std |= saa7164_tvnorms[n].id;
230
231         return 0;
232 }
233
234 static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
235 {
236         struct saa7164_vbi_fh *fh = file->private_data;
237         struct saa7164_port *port = fh->port;
238         struct saa7164_dev *dev = port->dev;
239
240         if (saa7164_api_get_videomux(port) != SAA_OK)
241                 return -EIO;
242
243         *i = (port->mux_input - 1);
244
245         dprintk(DBGLVL_VBI, "%s() input=%d\n", __func__, *i);
246
247         return 0;
248 }
249
250 static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
251 {
252         struct saa7164_vbi_fh *fh = file->private_data;
253         struct saa7164_port *port = fh->port;
254         struct saa7164_dev *dev = port->dev;
255
256         dprintk(DBGLVL_VBI, "%s() input=%d\n", __func__, i);
257
258         if (i >= 7)
259                 return -EINVAL;
260
261         port->mux_input = i + 1;
262
263         if (saa7164_api_set_videomux(port) != SAA_OK)
264                 return -EIO;
265
266         return 0;
267 }
268
269 static int vidioc_g_tuner(struct file *file, void *priv,
270         struct v4l2_tuner *t)
271 {
272         struct saa7164_vbi_fh *fh = file->private_data;
273         struct saa7164_port *port = fh->port;
274         struct saa7164_dev *dev = port->dev;
275
276         if (0 != t->index)
277                 return -EINVAL;
278
279         strcpy(t->name, "tuner");
280         t->type = V4L2_TUNER_ANALOG_TV;
281         t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO;
282
283         dprintk(DBGLVL_VBI, "VIDIOC_G_TUNER: tuner type %d\n", t->type);
284
285         return 0;
286 }
287
288 static int vidioc_s_tuner(struct file *file, void *priv,
289         struct v4l2_tuner *t)
290 {
291         /* Update the A/V core */
292         return 0;
293 }
294
295 static int vidioc_g_frequency(struct file *file, void *priv,
296         struct v4l2_frequency *f)
297 {
298         struct saa7164_vbi_fh *fh = file->private_data;
299         struct saa7164_port *port = fh->port;
300
301         f->type = V4L2_TUNER_ANALOG_TV;
302         f->frequency = port->freq;
303
304         return 0;
305 }
306
307 static int vidioc_s_frequency(struct file *file, void *priv,
308         struct v4l2_frequency *f)
309 {
310         struct saa7164_vbi_fh *fh = file->private_data;
311         struct saa7164_port *port = fh->port;
312         struct saa7164_dev *dev = port->dev;
313         struct saa7164_port *tsport;
314         struct dvb_frontend *fe;
315
316         /* TODO: Pull this for the std */
317         struct analog_parameters params = {
318                 .mode      = V4L2_TUNER_ANALOG_TV,
319                 .audmode   = V4L2_TUNER_MODE_STEREO,
320                 .std       = port->encodernorm.id,
321                 .frequency = f->frequency
322         };
323
324         /* Stop the encoder */
325         dprintk(DBGLVL_VBI, "%s() frequency=%d tuner=%d\n", __func__,
326                 f->frequency, f->tuner);
327
328         if (f->tuner != 0)
329                 return -EINVAL;
330
331         if (f->type != V4L2_TUNER_ANALOG_TV)
332                 return -EINVAL;
333
334         port->freq = f->frequency;
335
336         /* Update the hardware */
337         if (port->nr == SAA7164_PORT_VBI1)
338                 tsport = &dev->ports[ SAA7164_PORT_TS1 ];
339         else
340         if (port->nr == SAA7164_PORT_VBI2)
341                 tsport = &dev->ports[ SAA7164_PORT_TS2 ];
342         else
343                 BUG();
344
345         fe = tsport->dvb.frontend;
346
347         if (fe && fe->ops.tuner_ops.set_analog_params)
348                 fe->ops.tuner_ops.set_analog_params(fe, &params);
349         else
350                 printk(KERN_ERR "%s() No analog tuner, aborting\n", __func__);
351
352         saa7164_vbi_initialize(port);
353
354         return 0;
355 }
356
357 static int vidioc_g_ctrl(struct file *file, void *priv,
358         struct v4l2_control *ctl)
359 {
360         struct saa7164_vbi_fh *fh = file->private_data;
361         struct saa7164_port *port = fh->port;
362         struct saa7164_dev *dev = port->dev;
363
364         dprintk(DBGLVL_VBI, "%s(id=%d, value=%d)\n", __func__,
365                 ctl->id, ctl->value);
366
367         switch (ctl->id) {
368         case V4L2_CID_BRIGHTNESS:
369                 ctl->value = port->ctl_brightness;
370                 break;
371         case V4L2_CID_CONTRAST:
372                 ctl->value = port->ctl_contrast;
373                 break;
374         case V4L2_CID_SATURATION:
375                 ctl->value = port->ctl_saturation;
376                 break;
377         case V4L2_CID_HUE:
378                 ctl->value = port->ctl_hue;
379                 break;
380         case V4L2_CID_SHARPNESS:
381                 ctl->value = port->ctl_sharpness;
382                 break;
383         case V4L2_CID_AUDIO_VOLUME:
384                 ctl->value = port->ctl_volume;
385                 break;
386         default:
387                 return -EINVAL;
388         }
389
390         return 0;
391 }
392
393 static int vidioc_s_ctrl(struct file *file, void *priv,
394         struct v4l2_control *ctl)
395 {
396         struct saa7164_vbi_fh *fh = file->private_data;
397         struct saa7164_port *port = fh->port;
398         struct saa7164_dev *dev = port->dev;
399         int ret = 0;
400
401         dprintk(DBGLVL_VBI, "%s(id=%d, value=%d)\n", __func__,
402                 ctl->id, ctl->value);
403
404         switch (ctl->id) {
405         case V4L2_CID_BRIGHTNESS:
406                 if ((ctl->value >= 0) && (ctl->value <= 255)) {
407                         port->ctl_brightness = ctl->value;
408                         saa7164_api_set_usercontrol(port,
409                                 PU_BRIGHTNESS_CONTROL);
410                 } else
411                         ret = -EINVAL;
412                 break;
413         case V4L2_CID_CONTRAST:
414                 if ((ctl->value >= 0) && (ctl->value <= 255)) {
415                         port->ctl_contrast = ctl->value;
416                         saa7164_api_set_usercontrol(port, PU_CONTRAST_CONTROL);
417                 } else
418                         ret = -EINVAL;
419                 break;
420         case V4L2_CID_SATURATION:
421                 if ((ctl->value >= 0) && (ctl->value <= 255)) {
422                         port->ctl_saturation = ctl->value;
423                         saa7164_api_set_usercontrol(port,
424                                 PU_SATURATION_CONTROL);
425                 } else
426                         ret = -EINVAL;
427                 break;
428         case V4L2_CID_HUE:
429                 if ((ctl->value >= 0) && (ctl->value <= 255)) {
430                         port->ctl_hue = ctl->value;
431                         saa7164_api_set_usercontrol(port, PU_HUE_CONTROL);
432                 } else
433                         ret = -EINVAL;
434                 break;
435         case V4L2_CID_SHARPNESS:
436                 if ((ctl->value >= 0) && (ctl->value <= 255)) {
437                         port->ctl_sharpness = ctl->value;
438                         saa7164_api_set_usercontrol(port, PU_SHARPNESS_CONTROL);
439                 } else
440                         ret = -EINVAL;
441                 break;
442         case V4L2_CID_AUDIO_VOLUME:
443                 if ((ctl->value >= -83) && (ctl->value <= 24)) {
444                         port->ctl_volume = ctl->value;
445                         saa7164_api_set_audio_volume(port, port->ctl_volume);
446                 } else
447                         ret = -EINVAL;
448                 break;
449         default:
450                 ret = -EINVAL;
451         }
452
453         return ret;
454 }
455
456 static int saa7164_get_ctrl(struct saa7164_port *port,
457         struct v4l2_ext_control *ctrl)
458 {
459         struct saa7164_vbi_params *params = &port->vbi_params;
460
461         switch (ctrl->id) {
462         case V4L2_CID_MPEG_STREAM_TYPE:
463                 ctrl->value = params->stream_type;
464                 break;
465         case V4L2_CID_MPEG_AUDIO_MUTE:
466                 ctrl->value = params->ctl_mute;
467                 break;
468         case V4L2_CID_MPEG_VIDEO_ASPECT:
469                 ctrl->value = params->ctl_aspect;
470                 break;
471         case V4L2_CID_MPEG_VIDEO_B_FRAMES:
472                 ctrl->value = params->refdist;
473                 break;
474         case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
475                 ctrl->value = params->gop_size;
476                 break;
477         default:
478                 return -EINVAL;
479         }
480         return 0;
481 }
482
483 static int vidioc_g_ext_ctrls(struct file *file, void *priv,
484         struct v4l2_ext_controls *ctrls)
485 {
486         struct saa7164_vbi_fh *fh = file->private_data;
487         struct saa7164_port *port = fh->port;
488         int i, err = 0;
489
490         if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
491                 for (i = 0; i < ctrls->count; i++) {
492                         struct v4l2_ext_control *ctrl = ctrls->controls + i;
493
494                         err = saa7164_get_ctrl(port, ctrl);
495                         if (err) {
496                                 ctrls->error_idx = i;
497                                 break;
498                         }
499                 }
500                 return err;
501
502         }
503
504         return -EINVAL;
505 }
506
507 static int saa7164_try_ctrl(struct v4l2_ext_control *ctrl, int ac3)
508 {
509         int ret = -EINVAL;
510
511         switch (ctrl->id) {
512         case V4L2_CID_MPEG_STREAM_TYPE:
513                 if ((ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_PS) ||
514                         (ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_TS))
515                         ret = 0;
516                 break;
517         case V4L2_CID_MPEG_AUDIO_MUTE:
518                 if ((ctrl->value >= 0) &&
519                         (ctrl->value <= 1))
520                         ret = 0;
521                 break;
522         case V4L2_CID_MPEG_VIDEO_ASPECT:
523                 if ((ctrl->value >= V4L2_MPEG_VIDEO_ASPECT_1x1) &&
524                         (ctrl->value <= V4L2_MPEG_VIDEO_ASPECT_221x100))
525                         ret = 0;
526                 break;
527         case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
528                 if ((ctrl->value >= 0) &&
529                         (ctrl->value <= 255))
530                         ret = 0;
531                 break;
532         case V4L2_CID_MPEG_VIDEO_B_FRAMES:
533                 if ((ctrl->value >= 1) &&
534                         (ctrl->value <= 3))
535                         ret = 0;
536                 break;
537         default:
538                 ret = -EINVAL;
539         }
540
541         return ret;
542 }
543
544 static int vidioc_try_ext_ctrls(struct file *file, void *priv,
545         struct v4l2_ext_controls *ctrls)
546 {
547         int i, err = 0;
548
549         if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
550                 for (i = 0; i < ctrls->count; i++) {
551                         struct v4l2_ext_control *ctrl = ctrls->controls + i;
552
553                         err = saa7164_try_ctrl(ctrl, 0);
554                         if (err) {
555                                 ctrls->error_idx = i;
556                                 break;
557                         }
558                 }
559                 return err;
560         }
561
562         return -EINVAL;
563 }
564
565 static int saa7164_set_ctrl(struct saa7164_port *port,
566         struct v4l2_ext_control *ctrl)
567 {
568         struct saa7164_vbi_params *params = &port->vbi_params;
569         int ret = 0;
570
571         switch (ctrl->id) {
572         case V4L2_CID_MPEG_STREAM_TYPE:
573                 params->stream_type = ctrl->value;
574                 break;
575         case V4L2_CID_MPEG_AUDIO_MUTE:
576                 params->ctl_mute = ctrl->value;
577                 ret = saa7164_api_audio_mute(port, params->ctl_mute);
578                 if (ret != SAA_OK) {
579                         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
580                                 ret);
581                         ret = -EIO;
582                 }
583                 break;
584         case V4L2_CID_MPEG_VIDEO_ASPECT:
585                 params->ctl_aspect = ctrl->value;
586                 ret = saa7164_api_set_aspect_ratio(port);
587                 if (ret != SAA_OK) {
588                         printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__,
589                                 ret);
590                         ret = -EIO;
591                 }
592                 break;
593         case V4L2_CID_MPEG_VIDEO_B_FRAMES:
594                 params->refdist = ctrl->value;
595                 break;
596         case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
597                 params->gop_size = ctrl->value;
598                 break;
599         default:
600                 return -EINVAL;
601         }
602
603         /* TODO: Update the hardware */
604
605         return ret;
606 }
607
608 static int vidioc_s_ext_ctrls(struct file *file, void *priv,
609         struct v4l2_ext_controls *ctrls)
610 {
611         struct saa7164_vbi_fh *fh = file->private_data;
612         struct saa7164_port *port = fh->port;
613         int i, err = 0;
614
615         if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
616                 for (i = 0; i < ctrls->count; i++) {
617                         struct v4l2_ext_control *ctrl = ctrls->controls + i;
618
619                         err = saa7164_try_ctrl(ctrl, 0);
620                         if (err) {
621                                 ctrls->error_idx = i;
622                                 break;
623                         }
624                         err = saa7164_set_ctrl(port, ctrl);
625                         if (err) {
626                                 ctrls->error_idx = i;
627                                 break;
628                         }
629                 }
630                 return err;
631
632         }
633
634         return -EINVAL;
635 }
636
637 static int vidioc_querycap(struct file *file, void  *priv,
638         struct v4l2_capability *cap)
639 {
640         struct saa7164_vbi_fh *fh = file->private_data;
641         struct saa7164_port *port = fh->port;
642         struct saa7164_dev *dev = port->dev;
643
644         strcpy(cap->driver, dev->name);
645         strlcpy(cap->card, saa7164_boards[dev->board].name,
646                 sizeof(cap->card));
647         sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
648
649         cap->capabilities =
650                 V4L2_CAP_VBI_CAPTURE |
651                 V4L2_CAP_READWRITE     |
652                 V4L2_CAP_STREAMING     |
653                 0;
654
655         cap->capabilities |= V4L2_CAP_TUNER;
656         cap->version = 0;
657
658         return 0;
659 }
660
661 static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
662         struct v4l2_fmtdesc *f)
663 {
664         if (f->index != 0)
665                 return -EINVAL;
666
667         strlcpy(f->description, "VBI", sizeof(f->description));
668         f->pixelformat = V4L2_PIX_FMT_MPEG;
669
670         return 0;
671 }
672
673 static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
674                                 struct v4l2_format *f)
675 {
676         struct saa7164_vbi_fh *fh = file->private_data;
677         struct saa7164_port *port = fh->port;
678         struct saa7164_dev *dev = port->dev;
679
680         f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
681         f->fmt.pix.bytesperline = 0;
682         f->fmt.pix.sizeimage    =
683                 port->ts_packet_size * port->ts_packet_count;
684         f->fmt.pix.colorspace   = 0;
685         f->fmt.pix.width        = port->width;
686         f->fmt.pix.height       = port->height;
687
688         dprintk(DBGLVL_VBI, "VIDIOC_G_FMT: w: %d, h: %d\n",
689                 port->width, port->height);
690
691         return 0;
692 }
693
694 static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
695                                 struct v4l2_format *f)
696 {
697         struct saa7164_vbi_fh *fh = file->private_data;
698         struct saa7164_port *port = fh->port;
699         struct saa7164_dev *dev = port->dev;
700
701         f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
702         f->fmt.pix.bytesperline = 0;
703         f->fmt.pix.sizeimage    =
704                 port->ts_packet_size * port->ts_packet_count;
705         f->fmt.pix.colorspace   = 0;
706         dprintk(DBGLVL_VBI, "VIDIOC_TRY_FMT: w: %d, h: %d\n",
707                 port->width, port->height);
708         return 0;
709 }
710
711 static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
712                                 struct v4l2_format *f)
713 {
714         struct saa7164_vbi_fh *fh = file->private_data;
715         struct saa7164_port *port = fh->port;
716         struct saa7164_dev *dev = port->dev;
717
718         f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
719         f->fmt.pix.bytesperline = 0;
720         f->fmt.pix.sizeimage    =
721                 port->ts_packet_size * port->ts_packet_count;
722         f->fmt.pix.colorspace   = 0;
723
724         dprintk(DBGLVL_VBI, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
725                 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
726
727         return 0;
728 }
729
730 static int vidioc_log_status(struct file *file, void *priv)
731 {
732         return 0;
733 }
734
735 static int fill_queryctrl(struct saa7164_vbi_params *params,
736         struct v4l2_queryctrl *c)
737 {
738         switch (c->id) {
739         case V4L2_CID_BRIGHTNESS:
740                 return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 127);
741         case V4L2_CID_CONTRAST:
742                 return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 66);
743         case V4L2_CID_SATURATION:
744                 return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 62);
745         case V4L2_CID_HUE:
746                 return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 128);
747         case V4L2_CID_SHARPNESS:
748                 return v4l2_ctrl_query_fill(c, 0x0, 0x0f, 1, 8);
749         case V4L2_CID_MPEG_AUDIO_MUTE:
750                 return v4l2_ctrl_query_fill(c, 0x0, 0x01, 1, 0);
751         case V4L2_CID_AUDIO_VOLUME:
752                 return v4l2_ctrl_query_fill(c, -83, 24, 1, 20);
753         case V4L2_CID_MPEG_STREAM_TYPE:
754                 return v4l2_ctrl_query_fill(c,
755                         V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
756                         V4L2_MPEG_STREAM_TYPE_MPEG2_TS,
757                         1, V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
758         case V4L2_CID_MPEG_VIDEO_ASPECT:
759                 return v4l2_ctrl_query_fill(c,
760                         V4L2_MPEG_VIDEO_ASPECT_1x1,
761                         V4L2_MPEG_VIDEO_ASPECT_221x100,
762                         1, V4L2_MPEG_VIDEO_ASPECT_4x3);
763         case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
764                 return v4l2_ctrl_query_fill(c, 1, 255, 1, 15);
765         case V4L2_CID_MPEG_VIDEO_B_FRAMES:
766                 return v4l2_ctrl_query_fill(c,
767                         1, 3, 1, 1);
768         default:
769                 return -EINVAL;
770         }
771 }
772
773 static int vidioc_queryctrl(struct file *file, void *priv,
774         struct v4l2_queryctrl *c)
775 {
776         struct saa7164_vbi_fh *fh = priv;
777         struct saa7164_port *port = fh->port;
778         int i, next;
779         u32 id = c->id;
780
781         memset(c, 0, sizeof(*c));
782
783         next = !!(id & V4L2_CTRL_FLAG_NEXT_CTRL);
784         c->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL;
785
786         for (i = 0; i < ARRAY_SIZE(saa7164_v4l2_ctrls); i++) {
787                 if (next) {
788                         if (c->id < saa7164_v4l2_ctrls[i])
789                                 c->id = saa7164_v4l2_ctrls[i];
790                         else
791                                 continue;
792                 }
793
794                 if (c->id == saa7164_v4l2_ctrls[i])
795                         return fill_queryctrl(&port->vbi_params, c);
796
797                 if (c->id < saa7164_v4l2_ctrls[i])
798                         break;
799         }
800
801         return -EINVAL;
802 }
803
804 static int saa7164_vbi_stop_port(struct saa7164_port *port)
805 {
806         struct saa7164_dev *dev = port->dev;
807         int ret;
808
809         ret = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
810         if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
811                 printk(KERN_ERR "%s() stop transition failed, ret = 0x%x\n",
812                         __func__, ret);
813                 ret = -EIO;
814         } else {
815                 dprintk(DBGLVL_VBI, "%s()    Stopped\n", __func__);
816                 ret = 0;
817         }
818
819         return ret;
820 }
821
822 static int saa7164_vbi_acquire_port(struct saa7164_port *port)
823 {
824         struct saa7164_dev *dev = port->dev;
825         int ret;
826
827         ret = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
828         if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
829                 printk(KERN_ERR "%s() acquire transition failed, ret = 0x%x\n",
830                         __func__, ret);
831                 ret = -EIO;
832         } else {
833                 dprintk(DBGLVL_VBI, "%s() Acquired\n", __func__);
834                 ret = 0;
835         }
836
837         return ret;
838 }
839
840 static int saa7164_vbi_pause_port(struct saa7164_port *port)
841 {
842         struct saa7164_dev *dev = port->dev;
843         int ret;
844
845         ret = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
846         if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
847                 printk(KERN_ERR "%s() pause transition failed, ret = 0x%x\n",
848                         __func__, ret);
849                 ret = -EIO;
850         } else {
851                 dprintk(DBGLVL_VBI, "%s()   Paused\n", __func__);
852                 ret = 0;
853         }
854
855         return ret;
856 }
857
858 /* Firmware is very windows centric, meaning you have to transition
859  * the part through AVStream / KS Windows stages, forwards or backwards.
860  * States are: stopped, acquired (h/w), paused, started.
861  * We have to leave here will all of the soft buffers on the free list,
862  * else the cfg_post() func won't have soft buffers to correctly configure.
863  */
864 static int saa7164_vbi_stop_streaming(struct saa7164_port *port)
865 {
866         struct saa7164_dev *dev = port->dev;
867         struct saa7164_buffer *buf;
868         struct saa7164_user_buffer *ubuf;
869         struct list_head *c, *n;
870         int ret;
871
872         dprintk(DBGLVL_VBI, "%s(port=%d)\n", __func__, port->nr);
873
874         ret = saa7164_vbi_pause_port(port);
875         ret = saa7164_vbi_acquire_port(port);
876         ret = saa7164_vbi_stop_port(port);
877
878         dprintk(DBGLVL_VBI, "%s(port=%d) Hardware stopped\n", __func__,
879                 port->nr);
880
881         /* Reset the state of any allocated buffer resources */
882         mutex_lock(&port->dmaqueue_lock);
883
884         /* Reset the hard and soft buffer state */
885         list_for_each_safe(c, n, &port->dmaqueue.list) {
886                 buf = list_entry(c, struct saa7164_buffer, list);
887                 buf->flags = SAA7164_BUFFER_FREE;
888                 buf->pos = 0;
889         }
890
891         list_for_each_safe(c, n, &port->list_buf_used.list) {
892                 ubuf = list_entry(c, struct saa7164_user_buffer, list);
893                 ubuf->pos = 0;
894                 list_move_tail(&ubuf->list, &port->list_buf_free.list);
895         }
896
897         mutex_unlock(&port->dmaqueue_lock);
898
899         /* Free any allocated resources */
900         saa7164_vbi_buffers_dealloc(port);
901
902         dprintk(DBGLVL_VBI, "%s(port=%d) Released\n", __func__, port->nr);
903
904         return ret;
905 }
906
907 static int saa7164_vbi_start_streaming(struct saa7164_port *port)
908 {
909         struct saa7164_dev *dev = port->dev;
910         int result, ret = 0;
911
912         dprintk(DBGLVL_VBI, "%s(port=%d)\n", __func__, port->nr);
913
914         port->done_first_interrupt = 0;
915
916         /* allocate all of the PCIe DMA buffer resources on the fly,
917          * allowing switching between TS and PS payloads without
918          * requiring a complete driver reload.
919          */
920         saa7164_vbi_buffers_alloc(port);
921
922         /* Configure the encoder with any cache values */
923 //      saa7164_api_set_encoder(port);
924 //      saa7164_api_get_encoder(port);
925
926         /* Place the empty buffers on the hardware */
927         saa7164_buffer_cfg_port(port);
928
929         /* Negotiate format */
930         if (saa7164_api_set_vbi_format(port) != SAA_OK) {
931                 printk(KERN_ERR "%s() No supported VBI format\n", __func__);
932                 ret = -EIO;
933                 goto out;
934         }
935
936         /* Acquire the hardware */
937         result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
938         if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
939                 printk(KERN_ERR "%s() acquire transition failed, res = 0x%x\n",
940                         __func__, result);
941
942                 ret = -EIO;
943                 goto out;
944         } else
945                 dprintk(DBGLVL_VBI, "%s()   Acquired\n", __func__);
946
947         /* Pause the hardware */
948         result = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
949         if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
950                 printk(KERN_ERR "%s() pause transition failed, res = 0x%x\n",
951                                 __func__, result);
952
953                 /* Stop the hardware, regardless */
954                 result = saa7164_vbi_stop_port(port);
955                 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
956                         printk(KERN_ERR "%s() pause/forced stop transition "
957                                 "failed, res = 0x%x\n", __func__, result);
958                 }
959
960                 ret = -EIO;
961                 goto out;
962         } else
963                 dprintk(DBGLVL_VBI, "%s()   Paused\n", __func__);
964
965         /* Start the hardware */
966         result = saa7164_api_transition_port(port, SAA_DMASTATE_RUN);
967         if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
968                 printk(KERN_ERR "%s() run transition failed, result = 0x%x\n",
969                                 __func__, result);
970
971                 /* Stop the hardware, regardless */
972                 result = saa7164_vbi_acquire_port(port);
973                 result = saa7164_vbi_stop_port(port);
974                 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
975                         printk(KERN_ERR "%s() run/forced stop transition "
976                                 "failed, res = 0x%x\n", __func__, result);
977                 }
978
979                 ret = -EIO;
980         } else
981                 dprintk(DBGLVL_VBI, "%s()   Running\n", __func__);
982
983 out:
984         return ret;
985 }
986
987 int saa7164_vbi_fmt(struct file *file, void *priv, struct v4l2_format *f)
988 {
989         /* ntsc */
990         f->fmt.vbi.samples_per_line = 1600;
991         f->fmt.vbi.samples_per_line = 1440;
992         f->fmt.vbi.sampling_rate = 27000000;
993         f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
994         f->fmt.vbi.offset = 0;
995         f->fmt.vbi.flags = 0;
996         f->fmt.vbi.start[0] = 10;
997         f->fmt.vbi.count[0] = 18;
998         f->fmt.vbi.start[1] = 263 + 10 + 1;
999         f->fmt.vbi.count[1] = 18;
1000         return 0;
1001 }
1002
1003 static int fops_open(struct file *file)
1004 {
1005         struct saa7164_dev *h, *dev = NULL;
1006         struct saa7164_port *port = NULL;
1007         struct saa7164_port *porte = NULL;
1008         struct saa7164_port *portf = NULL;
1009         struct saa7164_vbi_fh *fh;
1010         struct list_head *list;
1011         int minor = video_devdata(file)->minor;
1012
1013         dprintk(DBGLVL_VBI, "%s()\n", __func__);
1014
1015         /* TODO: Really, the BKL? - remove this */
1016         lock_kernel();
1017         list_for_each(list, &saa7164_devlist) {
1018                 h = list_entry(list, struct saa7164_dev, devlist);
1019
1020                 porte = &h->ports[ SAA7164_PORT_VBI1 ];
1021                 portf = &h->ports[ SAA7164_PORT_VBI2 ];
1022
1023                 if (porte->v4l_device &&
1024                     porte->v4l_device->minor == minor) {
1025                         dev = h;
1026                         port = porte;
1027                         break;
1028                 }
1029
1030                 if (portf->v4l_device &&
1031                     portf->v4l_device->minor == minor) {
1032                         dev = h;
1033                         port = portf;
1034                         break;
1035                 }
1036
1037         }
1038
1039         if (port == NULL) {
1040                 unlock_kernel();
1041                 return -ENODEV;
1042         }
1043
1044         /* allocate + initialize per filehandle data */
1045         fh = kzalloc(sizeof(*fh), GFP_KERNEL);
1046         if (NULL == fh) {
1047                 unlock_kernel();
1048                 return -ENOMEM;
1049         }
1050
1051         file->private_data = fh;
1052         fh->port = port;
1053
1054         unlock_kernel();
1055
1056         return 0;
1057 }
1058
1059 static int fops_release(struct file *file)
1060 {
1061         struct saa7164_vbi_fh *fh = file->private_data;
1062         struct saa7164_port *port = fh->port;
1063         struct saa7164_dev *dev = port->dev;
1064
1065         dprintk(DBGLVL_VBI, "%s()\n", __func__);
1066
1067         /* Shut device down on last close */
1068         if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) {
1069                 if (atomic_dec_return(&port->v4l_reader_count) == 0) {
1070                         /* stop vbi capture then cancel buffers */
1071                         saa7164_vbi_stop_streaming(port);
1072                 }
1073         }
1074
1075         file->private_data = NULL;
1076         kfree(fh);
1077
1078         return 0;
1079 }
1080
1081 struct saa7164_user_buffer *saa7164_vbi_next_buf(struct saa7164_port *port)
1082 {
1083         struct saa7164_user_buffer *ubuf = 0;
1084         struct saa7164_dev *dev = port->dev;
1085         u32 crc;
1086
1087         mutex_lock(&port->dmaqueue_lock);
1088         if (!list_empty(&port->list_buf_used.list)) {
1089                 ubuf = list_first_entry(&port->list_buf_used.list,
1090                         struct saa7164_user_buffer, list);
1091
1092                 if (crc_checking) {
1093                         crc = crc32(0, ubuf->data, ubuf->actual_size);
1094                         if (crc != ubuf->crc) {
1095                                 printk(KERN_ERR "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n", __func__,
1096                                         ubuf, ubuf->crc, crc);
1097                         }
1098                 }
1099
1100         }
1101         mutex_unlock(&port->dmaqueue_lock);
1102
1103         dprintk(DBGLVL_VBI, "%s() returns %p\n", __func__, ubuf);
1104
1105         return ubuf;
1106 }
1107
1108 static ssize_t fops_read(struct file *file, char __user *buffer,
1109         size_t count, loff_t *pos)
1110 {
1111         struct saa7164_vbi_fh *fh = file->private_data;
1112         struct saa7164_port *port = fh->port;
1113         struct saa7164_user_buffer *ubuf = NULL;
1114         struct saa7164_dev *dev = port->dev;
1115         unsigned int ret = 0;
1116         int rem, cnt;
1117         u8 *p;
1118
1119         port->last_read_msecs_diff = port->last_read_msecs;
1120         port->last_read_msecs = jiffies_to_msecs(jiffies);
1121         port->last_read_msecs_diff = port->last_read_msecs -
1122                 port->last_read_msecs_diff;
1123
1124         saa7164_histogram_update(&port->read_interval,
1125                 port->last_read_msecs_diff);
1126
1127         if (*pos) {
1128                 printk(KERN_ERR "%s() ESPIPE\n", __func__);
1129                 return -ESPIPE;
1130         }
1131
1132         if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
1133                 if (atomic_inc_return(&port->v4l_reader_count) == 1) {
1134
1135                         if (saa7164_vbi_initialize(port) < 0) {
1136                                 printk(KERN_ERR "%s() EINVAL\n", __func__);
1137                                 return -EINVAL;
1138                         }
1139
1140                         saa7164_vbi_start_streaming(port);
1141                         msleep(200);
1142                 }
1143         }
1144
1145         /* blocking wait for buffer */
1146         if ((file->f_flags & O_NONBLOCK) == 0) {
1147                 if (wait_event_interruptible(port->wait_read,
1148                         saa7164_vbi_next_buf(port))) {
1149                                 printk(KERN_ERR "%s() ERESTARTSYS\n", __func__);
1150                                 return -ERESTARTSYS;
1151                 }
1152         }
1153
1154         /* Pull the first buffer from the used list */
1155         ubuf = saa7164_vbi_next_buf(port);
1156
1157         while ((count > 0) && ubuf) {
1158
1159                 /* set remaining bytes to copy */
1160                 rem = ubuf->actual_size - ubuf->pos;
1161                 cnt = rem > count ? count : rem;
1162
1163                 p = ubuf->data + ubuf->pos;
1164
1165                 dprintk(DBGLVL_VBI,
1166                         "%s() count=%d cnt=%d rem=%d buf=%p buf->pos=%d\n",
1167                         __func__, (int)count, cnt, rem, ubuf, ubuf->pos);
1168
1169                 if (copy_to_user(buffer, p, cnt)) {
1170                         printk(KERN_ERR "%s() copy_to_user failed\n", __func__);
1171                         if (!ret) {
1172                                 printk(KERN_ERR "%s() EFAULT\n", __func__);
1173                                 ret = -EFAULT;
1174                         }
1175                         goto err;
1176                 }
1177
1178                 ubuf->pos += cnt;
1179                 count -= cnt;
1180                 buffer += cnt;
1181                 ret += cnt;
1182
1183                 if (ubuf->pos > ubuf->actual_size) {
1184                         printk(KERN_ERR "read() pos > actual, huh?\n");
1185                 }
1186
1187                 if (ubuf->pos == ubuf->actual_size) {
1188
1189                         /* finished with current buffer, take next buffer */
1190
1191                         /* Requeue the buffer on the free list */
1192                         ubuf->pos = 0;
1193
1194                         mutex_lock(&port->dmaqueue_lock);
1195                         list_move_tail(&ubuf->list, &port->list_buf_free.list);
1196                         mutex_unlock(&port->dmaqueue_lock);
1197
1198                         /* Dequeue next */
1199                         if ((file->f_flags & O_NONBLOCK) == 0) {
1200                                 if (wait_event_interruptible(port->wait_read,
1201                                         saa7164_vbi_next_buf(port))) {
1202                                                 break;
1203                                 }
1204                         }
1205                         ubuf = saa7164_vbi_next_buf(port);
1206                 }
1207         }
1208 err:
1209         if (!ret && !ubuf) {
1210                 printk(KERN_ERR "%s() EAGAIN\n", __func__);
1211                 ret = -EAGAIN;
1212         }
1213
1214         return ret;
1215 }
1216
1217 static unsigned int fops_poll(struct file *file, poll_table *wait)
1218 {
1219         struct saa7164_vbi_fh *fh = (struct saa7164_vbi_fh *)file->private_data;
1220         struct saa7164_port *port = fh->port;
1221         struct saa7164_user_buffer *ubuf;
1222         unsigned int mask = 0;
1223
1224         port->last_poll_msecs_diff = port->last_poll_msecs;
1225         port->last_poll_msecs = jiffies_to_msecs(jiffies);
1226         port->last_poll_msecs_diff = port->last_poll_msecs -
1227                 port->last_poll_msecs_diff;
1228
1229         saa7164_histogram_update(&port->poll_interval,
1230                 port->last_poll_msecs_diff);
1231
1232         if (!video_is_registered(port->v4l_device)) {
1233                 return -EIO;
1234         }
1235
1236         if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
1237                 if (atomic_inc_return(&port->v4l_reader_count) == 1) {
1238                         if (saa7164_vbi_initialize(port) < 0)
1239                                 return -EINVAL;
1240                         saa7164_vbi_start_streaming(port);
1241                         msleep(200);
1242                 }
1243         }
1244
1245         /* blocking wait for buffer */
1246         if ((file->f_flags & O_NONBLOCK) == 0) {
1247                 if (wait_event_interruptible(port->wait_read,
1248                         saa7164_vbi_next_buf(port))) {
1249                                 return -ERESTARTSYS;
1250                 }
1251         }
1252
1253         /* Pull the first buffer from the used list */
1254         ubuf = list_first_entry(&port->list_buf_used.list,
1255                 struct saa7164_user_buffer, list);
1256
1257         if (ubuf)
1258                 mask |= POLLIN | POLLRDNORM;
1259
1260         return mask;
1261 }
1262 static const struct v4l2_file_operations vbi_fops = {
1263         .owner          = THIS_MODULE,
1264         .open           = fops_open,
1265         .release        = fops_release,
1266         .read           = fops_read,
1267         .poll           = fops_poll,
1268         .unlocked_ioctl = video_ioctl2,
1269 };
1270
1271 static const struct v4l2_ioctl_ops vbi_ioctl_ops = {
1272         .vidioc_s_std            = vidioc_s_std,
1273         .vidioc_enum_input       = vidioc_enum_input,
1274         .vidioc_g_input          = vidioc_g_input,
1275         .vidioc_s_input          = vidioc_s_input,
1276         .vidioc_g_tuner          = vidioc_g_tuner,
1277         .vidioc_s_tuner          = vidioc_s_tuner,
1278         .vidioc_g_frequency      = vidioc_g_frequency,
1279         .vidioc_s_frequency      = vidioc_s_frequency,
1280         .vidioc_s_ctrl           = vidioc_s_ctrl,
1281         .vidioc_g_ctrl           = vidioc_g_ctrl,
1282         .vidioc_querycap         = vidioc_querycap,
1283         .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1284         .vidioc_g_fmt_vid_cap    = vidioc_g_fmt_vid_cap,
1285         .vidioc_try_fmt_vid_cap  = vidioc_try_fmt_vid_cap,
1286         .vidioc_s_fmt_vid_cap    = vidioc_s_fmt_vid_cap,
1287         .vidioc_g_ext_ctrls      = vidioc_g_ext_ctrls,
1288         .vidioc_s_ext_ctrls      = vidioc_s_ext_ctrls,
1289         .vidioc_try_ext_ctrls    = vidioc_try_ext_ctrls,
1290         .vidioc_log_status       = vidioc_log_status,
1291         .vidioc_queryctrl        = vidioc_queryctrl,
1292 //      .vidioc_g_chip_ident     = saa7164_g_chip_ident,
1293 #ifdef CONFIG_VIDEO_ADV_DEBUG
1294 //      .vidioc_g_register       = saa7164_g_register,
1295 //      .vidioc_s_register       = saa7164_s_register,
1296 #endif
1297         .vidioc_g_fmt_vbi_cap    = saa7164_vbi_fmt,
1298         .vidioc_try_fmt_vbi_cap  = saa7164_vbi_fmt,
1299         .vidioc_s_fmt_vbi_cap    = saa7164_vbi_fmt,
1300 };
1301
1302 static struct video_device saa7164_vbi_template = {
1303         .name          = "saa7164",
1304         .fops          = &vbi_fops,
1305         .ioctl_ops     = &vbi_ioctl_ops,
1306         .minor         = -1,
1307         .tvnorms       = SAA7164_NORMS,
1308         .current_norm  = V4L2_STD_NTSC_M,
1309 };
1310
1311 static struct video_device *saa7164_vbi_alloc(
1312         struct saa7164_port *port,
1313         struct pci_dev *pci,
1314         struct video_device *template,
1315         char *type)
1316 {
1317         struct video_device *vfd;
1318         struct saa7164_dev *dev = port->dev;
1319
1320         dprintk(DBGLVL_VBI, "%s()\n", __func__);
1321
1322         vfd = video_device_alloc();
1323         if (NULL == vfd)
1324                 return NULL;
1325
1326         *vfd = *template;
1327         snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name,
1328                 type, saa7164_boards[dev->board].name);
1329
1330         vfd->parent  = &pci->dev;
1331         vfd->release = video_device_release;
1332         return vfd;
1333 }
1334
1335 int saa7164_vbi_register(struct saa7164_port *port)
1336 {
1337         struct saa7164_dev *dev = port->dev;
1338         int result = -ENODEV;
1339
1340         dprintk(DBGLVL_VBI, "%s()\n", __func__);
1341
1342         if (port->type != SAA7164_MPEG_VBI)
1343                 BUG();
1344
1345         /* Sanity check that the PCI configuration space is active */
1346         if (port->hwcfg.BARLocation == 0) {
1347                 printk(KERN_ERR "%s() failed "
1348                        "(errno = %d), NO PCI configuration\n",
1349                         __func__, result);
1350                 result = -ENOMEM;
1351                 goto failed;
1352         }
1353
1354         /* Establish VBI defaults here */
1355
1356         /* Allocate and register the video device node */
1357         port->v4l_device = saa7164_vbi_alloc(port,
1358                 dev->pci, &saa7164_vbi_template, "vbi");
1359
1360         if (port->v4l_device == NULL) {
1361                 printk(KERN_INFO "%s: can't allocate vbi device\n",
1362                         dev->name);
1363                 result = -ENOMEM;
1364                 goto failed;
1365         }
1366
1367         result = video_register_device(port->v4l_device,
1368                 VFL_TYPE_VBI, -1);
1369         if (result < 0) {
1370                 printk(KERN_INFO "%s: can't register vbi device\n",
1371                         dev->name);
1372                 /* TODO: We're going to leak here if we don't dealloc
1373                  The buffers above. The unreg function can't deal wit it.
1374                 */
1375                 goto failed;
1376         }
1377
1378         printk(KERN_INFO "%s: registered device vbi%d [vbi]\n",
1379                 dev->name, port->v4l_device->num);
1380
1381         /* Configure the hardware defaults */
1382
1383         result = 0;
1384 failed:
1385         return result;
1386 }
1387
1388 void saa7164_vbi_unregister(struct saa7164_port *port)
1389 {
1390         struct saa7164_dev *dev = port->dev;
1391
1392         dprintk(DBGLVL_VBI, "%s(port=%d)\n", __func__, port->nr);
1393
1394         if (port->type != SAA7164_MPEG_VBI)
1395                 BUG();
1396
1397         if (port->v4l_device) {
1398                 if (port->v4l_device->minor != -1)
1399                         video_unregister_device(port->v4l_device);
1400                 else
1401                         video_device_release(port->v4l_device);
1402
1403                 port->v4l_device = NULL;
1404         }
1405
1406 }