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