Kernel bump from 4.1.3-rt to 4.1.7-rt.
[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->device_caps =
664                 V4L2_CAP_VBI_CAPTURE |
665                 V4L2_CAP_READWRITE |
666                 V4L2_CAP_TUNER;
667
668         cap->capabilities = cap->device_caps |
669                 V4L2_CAP_VIDEO_CAPTURE |
670                 V4L2_CAP_DEVICE_CAPS;
671
672         return 0;
673 }
674
675 static int vidioc_enum_fmt_vid_cap(struct file *file, void  *priv,
676         struct v4l2_fmtdesc *f)
677 {
678         if (f->index != 0)
679                 return -EINVAL;
680
681         strlcpy(f->description, "VBI", sizeof(f->description));
682         f->pixelformat = V4L2_PIX_FMT_MPEG;
683
684         return 0;
685 }
686
687 static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
688                                 struct v4l2_format *f)
689 {
690         struct saa7164_vbi_fh *fh = file->private_data;
691         struct saa7164_port *port = fh->port;
692         struct saa7164_dev *dev = port->dev;
693
694         f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
695         f->fmt.pix.bytesperline = 0;
696         f->fmt.pix.sizeimage    =
697                 port->ts_packet_size * port->ts_packet_count;
698         f->fmt.pix.colorspace   = 0;
699         f->fmt.pix.width        = port->width;
700         f->fmt.pix.height       = port->height;
701
702         dprintk(DBGLVL_VBI, "VIDIOC_G_FMT: w: %d, h: %d\n",
703                 port->width, port->height);
704
705         return 0;
706 }
707
708 static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
709                                 struct v4l2_format *f)
710 {
711         struct saa7164_vbi_fh *fh = file->private_data;
712         struct saa7164_port *port = fh->port;
713         struct saa7164_dev *dev = port->dev;
714
715         f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
716         f->fmt.pix.bytesperline = 0;
717         f->fmt.pix.sizeimage    =
718                 port->ts_packet_size * port->ts_packet_count;
719         f->fmt.pix.colorspace   = 0;
720         dprintk(DBGLVL_VBI, "VIDIOC_TRY_FMT: w: %d, h: %d\n",
721                 port->width, port->height);
722         return 0;
723 }
724
725 static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
726                                 struct v4l2_format *f)
727 {
728         struct saa7164_vbi_fh *fh = file->private_data;
729         struct saa7164_port *port = fh->port;
730         struct saa7164_dev *dev = port->dev;
731
732         f->fmt.pix.pixelformat  = V4L2_PIX_FMT_MPEG;
733         f->fmt.pix.bytesperline = 0;
734         f->fmt.pix.sizeimage    =
735                 port->ts_packet_size * port->ts_packet_count;
736         f->fmt.pix.colorspace   = 0;
737
738         dprintk(DBGLVL_VBI, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n",
739                 f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field);
740
741         return 0;
742 }
743
744 static int fill_queryctrl(struct saa7164_vbi_params *params,
745         struct v4l2_queryctrl *c)
746 {
747         switch (c->id) {
748         case V4L2_CID_BRIGHTNESS:
749                 return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 127);
750         case V4L2_CID_CONTRAST:
751                 return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 66);
752         case V4L2_CID_SATURATION:
753                 return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 62);
754         case V4L2_CID_HUE:
755                 return v4l2_ctrl_query_fill(c, 0x0, 0xff, 1, 128);
756         case V4L2_CID_SHARPNESS:
757                 return v4l2_ctrl_query_fill(c, 0x0, 0x0f, 1, 8);
758         case V4L2_CID_MPEG_AUDIO_MUTE:
759                 return v4l2_ctrl_query_fill(c, 0x0, 0x01, 1, 0);
760         case V4L2_CID_AUDIO_VOLUME:
761                 return v4l2_ctrl_query_fill(c, -83, 24, 1, 20);
762         case V4L2_CID_MPEG_STREAM_TYPE:
763                 return v4l2_ctrl_query_fill(c,
764                         V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
765                         V4L2_MPEG_STREAM_TYPE_MPEG2_TS,
766                         1, V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
767         case V4L2_CID_MPEG_VIDEO_ASPECT:
768                 return v4l2_ctrl_query_fill(c,
769                         V4L2_MPEG_VIDEO_ASPECT_1x1,
770                         V4L2_MPEG_VIDEO_ASPECT_221x100,
771                         1, V4L2_MPEG_VIDEO_ASPECT_4x3);
772         case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
773                 return v4l2_ctrl_query_fill(c, 1, 255, 1, 15);
774         case V4L2_CID_MPEG_VIDEO_B_FRAMES:
775                 return v4l2_ctrl_query_fill(c,
776                         1, 3, 1, 1);
777         default:
778                 return -EINVAL;
779         }
780 }
781
782 static int vidioc_queryctrl(struct file *file, void *priv,
783         struct v4l2_queryctrl *c)
784 {
785         struct saa7164_vbi_fh *fh = priv;
786         struct saa7164_port *port = fh->port;
787         int i, next;
788         u32 id = c->id;
789
790         memset(c, 0, sizeof(*c));
791
792         next = !!(id & V4L2_CTRL_FLAG_NEXT_CTRL);
793         c->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL;
794
795         for (i = 0; i < ARRAY_SIZE(saa7164_v4l2_ctrls); i++) {
796                 if (next) {
797                         if (c->id < saa7164_v4l2_ctrls[i])
798                                 c->id = saa7164_v4l2_ctrls[i];
799                         else
800                                 continue;
801                 }
802
803                 if (c->id == saa7164_v4l2_ctrls[i])
804                         return fill_queryctrl(&port->vbi_params, c);
805
806                 if (c->id < saa7164_v4l2_ctrls[i])
807                         break;
808         }
809
810         return -EINVAL;
811 }
812
813 static int saa7164_vbi_stop_port(struct saa7164_port *port)
814 {
815         struct saa7164_dev *dev = port->dev;
816         int ret;
817
818         ret = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
819         if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
820                 printk(KERN_ERR "%s() stop transition failed, ret = 0x%x\n",
821                         __func__, ret);
822                 ret = -EIO;
823         } else {
824                 dprintk(DBGLVL_VBI, "%s()    Stopped\n", __func__);
825                 ret = 0;
826         }
827
828         return ret;
829 }
830
831 static int saa7164_vbi_acquire_port(struct saa7164_port *port)
832 {
833         struct saa7164_dev *dev = port->dev;
834         int ret;
835
836         ret = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
837         if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
838                 printk(KERN_ERR "%s() acquire transition failed, ret = 0x%x\n",
839                         __func__, ret);
840                 ret = -EIO;
841         } else {
842                 dprintk(DBGLVL_VBI, "%s() Acquired\n", __func__);
843                 ret = 0;
844         }
845
846         return ret;
847 }
848
849 static int saa7164_vbi_pause_port(struct saa7164_port *port)
850 {
851         struct saa7164_dev *dev = port->dev;
852         int ret;
853
854         ret = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
855         if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
856                 printk(KERN_ERR "%s() pause transition failed, ret = 0x%x\n",
857                         __func__, ret);
858                 ret = -EIO;
859         } else {
860                 dprintk(DBGLVL_VBI, "%s()   Paused\n", __func__);
861                 ret = 0;
862         }
863
864         return ret;
865 }
866
867 /* Firmware is very windows centric, meaning you have to transition
868  * the part through AVStream / KS Windows stages, forwards or backwards.
869  * States are: stopped, acquired (h/w), paused, started.
870  * We have to leave here will all of the soft buffers on the free list,
871  * else the cfg_post() func won't have soft buffers to correctly configure.
872  */
873 static int saa7164_vbi_stop_streaming(struct saa7164_port *port)
874 {
875         struct saa7164_dev *dev = port->dev;
876         struct saa7164_buffer *buf;
877         struct saa7164_user_buffer *ubuf;
878         struct list_head *c, *n;
879         int ret;
880
881         dprintk(DBGLVL_VBI, "%s(port=%d)\n", __func__, port->nr);
882
883         ret = saa7164_vbi_pause_port(port);
884         ret = saa7164_vbi_acquire_port(port);
885         ret = saa7164_vbi_stop_port(port);
886
887         dprintk(DBGLVL_VBI, "%s(port=%d) Hardware stopped\n", __func__,
888                 port->nr);
889
890         /* Reset the state of any allocated buffer resources */
891         mutex_lock(&port->dmaqueue_lock);
892
893         /* Reset the hard and soft buffer state */
894         list_for_each_safe(c, n, &port->dmaqueue.list) {
895                 buf = list_entry(c, struct saa7164_buffer, list);
896                 buf->flags = SAA7164_BUFFER_FREE;
897                 buf->pos = 0;
898         }
899
900         list_for_each_safe(c, n, &port->list_buf_used.list) {
901                 ubuf = list_entry(c, struct saa7164_user_buffer, list);
902                 ubuf->pos = 0;
903                 list_move_tail(&ubuf->list, &port->list_buf_free.list);
904         }
905
906         mutex_unlock(&port->dmaqueue_lock);
907
908         /* Free any allocated resources */
909         saa7164_vbi_buffers_dealloc(port);
910
911         dprintk(DBGLVL_VBI, "%s(port=%d) Released\n", __func__, port->nr);
912
913         return ret;
914 }
915
916 static int saa7164_vbi_start_streaming(struct saa7164_port *port)
917 {
918         struct saa7164_dev *dev = port->dev;
919         int result, ret = 0;
920
921         dprintk(DBGLVL_VBI, "%s(port=%d)\n", __func__, port->nr);
922
923         port->done_first_interrupt = 0;
924
925         /* allocate all of the PCIe DMA buffer resources on the fly,
926          * allowing switching between TS and PS payloads without
927          * requiring a complete driver reload.
928          */
929         saa7164_vbi_buffers_alloc(port);
930
931         /* Configure the encoder with any cache values */
932 #if 0
933         saa7164_api_set_encoder(port);
934         saa7164_api_get_encoder(port);
935 #endif
936
937         /* Place the empty buffers on the hardware */
938         saa7164_buffer_cfg_port(port);
939
940         /* Negotiate format */
941         if (saa7164_api_set_vbi_format(port) != SAA_OK) {
942                 printk(KERN_ERR "%s() No supported VBI format\n", __func__);
943                 ret = -EIO;
944                 goto out;
945         }
946
947         /* Acquire the hardware */
948         result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
949         if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
950                 printk(KERN_ERR "%s() acquire transition failed, res = 0x%x\n",
951                         __func__, result);
952
953                 ret = -EIO;
954                 goto out;
955         } else
956                 dprintk(DBGLVL_VBI, "%s()   Acquired\n", __func__);
957
958         /* Pause the hardware */
959         result = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
960         if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
961                 printk(KERN_ERR "%s() pause transition failed, res = 0x%x\n",
962                                 __func__, result);
963
964                 /* Stop the hardware, regardless */
965                 result = saa7164_vbi_stop_port(port);
966                 if (result != SAA_OK) {
967                         printk(KERN_ERR "%s() pause/forced stop transition "
968                                 "failed, res = 0x%x\n", __func__, result);
969                 }
970
971                 ret = -EIO;
972                 goto out;
973         } else
974                 dprintk(DBGLVL_VBI, "%s()   Paused\n", __func__);
975
976         /* Start the hardware */
977         result = saa7164_api_transition_port(port, SAA_DMASTATE_RUN);
978         if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
979                 printk(KERN_ERR "%s() run transition failed, result = 0x%x\n",
980                                 __func__, result);
981
982                 /* Stop the hardware, regardless */
983                 result = saa7164_vbi_acquire_port(port);
984                 result = saa7164_vbi_stop_port(port);
985                 if (result != SAA_OK) {
986                         printk(KERN_ERR "%s() run/forced stop transition "
987                                 "failed, res = 0x%x\n", __func__, result);
988                 }
989
990                 ret = -EIO;
991         } else
992                 dprintk(DBGLVL_VBI, "%s()   Running\n", __func__);
993
994 out:
995         return ret;
996 }
997
998 static int saa7164_vbi_fmt(struct file *file, void *priv,
999                            struct v4l2_format *f)
1000 {
1001         /* ntsc */
1002         f->fmt.vbi.samples_per_line = 1600;
1003         f->fmt.vbi.samples_per_line = 1440;
1004         f->fmt.vbi.sampling_rate = 27000000;
1005         f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
1006         f->fmt.vbi.offset = 0;
1007         f->fmt.vbi.flags = 0;
1008         f->fmt.vbi.start[0] = 10;
1009         f->fmt.vbi.count[0] = 18;
1010         f->fmt.vbi.start[1] = 263 + 10 + 1;
1011         f->fmt.vbi.count[1] = 18;
1012         return 0;
1013 }
1014
1015 static int fops_open(struct file *file)
1016 {
1017         struct saa7164_dev *dev;
1018         struct saa7164_port *port;
1019         struct saa7164_vbi_fh *fh;
1020
1021         port = (struct saa7164_port *)video_get_drvdata(video_devdata(file));
1022         if (!port)
1023                 return -ENODEV;
1024
1025         dev = port->dev;
1026
1027         dprintk(DBGLVL_VBI, "%s()\n", __func__);
1028
1029         /* allocate + initialize per filehandle data */
1030         fh = kzalloc(sizeof(*fh), GFP_KERNEL);
1031         if (NULL == fh)
1032                 return -ENOMEM;
1033
1034         file->private_data = fh;
1035         fh->port = port;
1036
1037         return 0;
1038 }
1039
1040 static int fops_release(struct file *file)
1041 {
1042         struct saa7164_vbi_fh *fh = file->private_data;
1043         struct saa7164_port *port = fh->port;
1044         struct saa7164_dev *dev = port->dev;
1045
1046         dprintk(DBGLVL_VBI, "%s()\n", __func__);
1047
1048         /* Shut device down on last close */
1049         if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) {
1050                 if (atomic_dec_return(&port->v4l_reader_count) == 0) {
1051                         /* stop vbi capture then cancel buffers */
1052                         saa7164_vbi_stop_streaming(port);
1053                 }
1054         }
1055
1056         file->private_data = NULL;
1057         kfree(fh);
1058
1059         return 0;
1060 }
1061
1062 static struct
1063 saa7164_user_buffer *saa7164_vbi_next_buf(struct saa7164_port *port)
1064 {
1065         struct saa7164_user_buffer *ubuf = NULL;
1066         struct saa7164_dev *dev = port->dev;
1067         u32 crc;
1068
1069         mutex_lock(&port->dmaqueue_lock);
1070         if (!list_empty(&port->list_buf_used.list)) {
1071                 ubuf = list_first_entry(&port->list_buf_used.list,
1072                         struct saa7164_user_buffer, list);
1073
1074                 if (crc_checking) {
1075                         crc = crc32(0, ubuf->data, ubuf->actual_size);
1076                         if (crc != ubuf->crc) {
1077                                 printk(KERN_ERR "%s() ubuf %p crc became invalid, was 0x%x became 0x%x\n",
1078                                         __func__,
1079                                         ubuf, ubuf->crc, crc);
1080                         }
1081                 }
1082
1083         }
1084         mutex_unlock(&port->dmaqueue_lock);
1085
1086         dprintk(DBGLVL_VBI, "%s() returns %p\n", __func__, ubuf);
1087
1088         return ubuf;
1089 }
1090
1091 static ssize_t fops_read(struct file *file, char __user *buffer,
1092         size_t count, loff_t *pos)
1093 {
1094         struct saa7164_vbi_fh *fh = file->private_data;
1095         struct saa7164_port *port = fh->port;
1096         struct saa7164_user_buffer *ubuf = NULL;
1097         struct saa7164_dev *dev = port->dev;
1098         int ret = 0;
1099         int rem, cnt;
1100         u8 *p;
1101
1102         port->last_read_msecs_diff = port->last_read_msecs;
1103         port->last_read_msecs = jiffies_to_msecs(jiffies);
1104         port->last_read_msecs_diff = port->last_read_msecs -
1105                 port->last_read_msecs_diff;
1106
1107         saa7164_histogram_update(&port->read_interval,
1108                 port->last_read_msecs_diff);
1109
1110         if (*pos) {
1111                 printk(KERN_ERR "%s() ESPIPE\n", __func__);
1112                 return -ESPIPE;
1113         }
1114
1115         if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
1116                 if (atomic_inc_return(&port->v4l_reader_count) == 1) {
1117
1118                         if (saa7164_vbi_initialize(port) < 0) {
1119                                 printk(KERN_ERR "%s() EINVAL\n", __func__);
1120                                 return -EINVAL;
1121                         }
1122
1123                         saa7164_vbi_start_streaming(port);
1124                         msleep(200);
1125                 }
1126         }
1127
1128         /* blocking wait for buffer */
1129         if ((file->f_flags & O_NONBLOCK) == 0) {
1130                 if (wait_event_interruptible(port->wait_read,
1131                         saa7164_vbi_next_buf(port))) {
1132                                 printk(KERN_ERR "%s() ERESTARTSYS\n", __func__);
1133                                 return -ERESTARTSYS;
1134                 }
1135         }
1136
1137         /* Pull the first buffer from the used list */
1138         ubuf = saa7164_vbi_next_buf(port);
1139
1140         while ((count > 0) && ubuf) {
1141
1142                 /* set remaining bytes to copy */
1143                 rem = ubuf->actual_size - ubuf->pos;
1144                 cnt = rem > count ? count : rem;
1145
1146                 p = ubuf->data + ubuf->pos;
1147
1148                 dprintk(DBGLVL_VBI,
1149                         "%s() count=%d cnt=%d rem=%d buf=%p buf->pos=%d\n",
1150                         __func__, (int)count, cnt, rem, ubuf, ubuf->pos);
1151
1152                 if (copy_to_user(buffer, p, cnt)) {
1153                         printk(KERN_ERR "%s() copy_to_user failed\n", __func__);
1154                         if (!ret) {
1155                                 printk(KERN_ERR "%s() EFAULT\n", __func__);
1156                                 ret = -EFAULT;
1157                         }
1158                         goto err;
1159                 }
1160
1161                 ubuf->pos += cnt;
1162                 count -= cnt;
1163                 buffer += cnt;
1164                 ret += cnt;
1165
1166                 if (ubuf->pos > ubuf->actual_size)
1167                         printk(KERN_ERR "read() pos > actual, huh?\n");
1168
1169                 if (ubuf->pos == ubuf->actual_size) {
1170
1171                         /* finished with current buffer, take next buffer */
1172
1173                         /* Requeue the buffer on the free list */
1174                         ubuf->pos = 0;
1175
1176                         mutex_lock(&port->dmaqueue_lock);
1177                         list_move_tail(&ubuf->list, &port->list_buf_free.list);
1178                         mutex_unlock(&port->dmaqueue_lock);
1179
1180                         /* Dequeue next */
1181                         if ((file->f_flags & O_NONBLOCK) == 0) {
1182                                 if (wait_event_interruptible(port->wait_read,
1183                                         saa7164_vbi_next_buf(port))) {
1184                                                 break;
1185                                 }
1186                         }
1187                         ubuf = saa7164_vbi_next_buf(port);
1188                 }
1189         }
1190 err:
1191         if (!ret && !ubuf) {
1192                 printk(KERN_ERR "%s() EAGAIN\n", __func__);
1193                 ret = -EAGAIN;
1194         }
1195
1196         return ret;
1197 }
1198
1199 static unsigned int fops_poll(struct file *file, poll_table *wait)
1200 {
1201         struct saa7164_vbi_fh *fh = (struct saa7164_vbi_fh *)file->private_data;
1202         struct saa7164_port *port = fh->port;
1203         unsigned int mask = 0;
1204
1205         port->last_poll_msecs_diff = port->last_poll_msecs;
1206         port->last_poll_msecs = jiffies_to_msecs(jiffies);
1207         port->last_poll_msecs_diff = port->last_poll_msecs -
1208                 port->last_poll_msecs_diff;
1209
1210         saa7164_histogram_update(&port->poll_interval,
1211                 port->last_poll_msecs_diff);
1212
1213         if (!video_is_registered(port->v4l_device))
1214                 return -EIO;
1215
1216         if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) {
1217                 if (atomic_inc_return(&port->v4l_reader_count) == 1) {
1218                         if (saa7164_vbi_initialize(port) < 0)
1219                                 return -EINVAL;
1220                         saa7164_vbi_start_streaming(port);
1221                         msleep(200);
1222                 }
1223         }
1224
1225         /* blocking wait for buffer */
1226         if ((file->f_flags & O_NONBLOCK) == 0) {
1227                 if (wait_event_interruptible(port->wait_read,
1228                         saa7164_vbi_next_buf(port))) {
1229                                 return -ERESTARTSYS;
1230                 }
1231         }
1232
1233         /* Pull the first buffer from the used list */
1234         if (!list_empty(&port->list_buf_used.list))
1235                 mask |= POLLIN | POLLRDNORM;
1236
1237         return mask;
1238 }
1239 static const struct v4l2_file_operations vbi_fops = {
1240         .owner          = THIS_MODULE,
1241         .open           = fops_open,
1242         .release        = fops_release,
1243         .read           = fops_read,
1244         .poll           = fops_poll,
1245         .unlocked_ioctl = video_ioctl2,
1246 };
1247
1248 static const struct v4l2_ioctl_ops vbi_ioctl_ops = {
1249         .vidioc_s_std            = vidioc_s_std,
1250         .vidioc_g_std            = vidioc_g_std,
1251         .vidioc_enum_input       = vidioc_enum_input,
1252         .vidioc_g_input          = vidioc_g_input,
1253         .vidioc_s_input          = vidioc_s_input,
1254         .vidioc_g_tuner          = vidioc_g_tuner,
1255         .vidioc_s_tuner          = vidioc_s_tuner,
1256         .vidioc_g_frequency      = vidioc_g_frequency,
1257         .vidioc_s_frequency      = vidioc_s_frequency,
1258         .vidioc_s_ctrl           = vidioc_s_ctrl,
1259         .vidioc_g_ctrl           = vidioc_g_ctrl,
1260         .vidioc_querycap         = vidioc_querycap,
1261         .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1262         .vidioc_g_fmt_vid_cap    = vidioc_g_fmt_vid_cap,
1263         .vidioc_try_fmt_vid_cap  = vidioc_try_fmt_vid_cap,
1264         .vidioc_s_fmt_vid_cap    = vidioc_s_fmt_vid_cap,
1265         .vidioc_g_ext_ctrls      = vidioc_g_ext_ctrls,
1266         .vidioc_s_ext_ctrls      = vidioc_s_ext_ctrls,
1267         .vidioc_try_ext_ctrls    = vidioc_try_ext_ctrls,
1268         .vidioc_queryctrl        = vidioc_queryctrl,
1269         .vidioc_g_fmt_vbi_cap    = saa7164_vbi_fmt,
1270         .vidioc_try_fmt_vbi_cap  = saa7164_vbi_fmt,
1271         .vidioc_s_fmt_vbi_cap    = saa7164_vbi_fmt,
1272 };
1273
1274 static struct video_device saa7164_vbi_template = {
1275         .name          = "saa7164",
1276         .fops          = &vbi_fops,
1277         .ioctl_ops     = &vbi_ioctl_ops,
1278         .minor         = -1,
1279         .tvnorms       = SAA7164_NORMS,
1280 };
1281
1282 static struct video_device *saa7164_vbi_alloc(
1283         struct saa7164_port *port,
1284         struct pci_dev *pci,
1285         struct video_device *template,
1286         char *type)
1287 {
1288         struct video_device *vfd;
1289         struct saa7164_dev *dev = port->dev;
1290
1291         dprintk(DBGLVL_VBI, "%s()\n", __func__);
1292
1293         vfd = video_device_alloc();
1294         if (NULL == vfd)
1295                 return NULL;
1296
1297         *vfd = *template;
1298         snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name,
1299                 type, saa7164_boards[dev->board].name);
1300
1301         vfd->v4l2_dev  = &dev->v4l2_dev;
1302         vfd->release = video_device_release;
1303         return vfd;
1304 }
1305
1306 int saa7164_vbi_register(struct saa7164_port *port)
1307 {
1308         struct saa7164_dev *dev = port->dev;
1309         int result = -ENODEV;
1310
1311         dprintk(DBGLVL_VBI, "%s()\n", __func__);
1312
1313         if (port->type != SAA7164_MPEG_VBI)
1314                 BUG();
1315
1316         /* Sanity check that the PCI configuration space is active */
1317         if (port->hwcfg.BARLocation == 0) {
1318                 printk(KERN_ERR "%s() failed "
1319                        "(errno = %d), NO PCI configuration\n",
1320                         __func__, result);
1321                 result = -ENOMEM;
1322                 goto failed;
1323         }
1324
1325         /* Establish VBI defaults here */
1326
1327         /* Allocate and register the video device node */
1328         port->v4l_device = saa7164_vbi_alloc(port,
1329                 dev->pci, &saa7164_vbi_template, "vbi");
1330
1331         if (!port->v4l_device) {
1332                 printk(KERN_INFO "%s: can't allocate vbi device\n",
1333                         dev->name);
1334                 result = -ENOMEM;
1335                 goto failed;
1336         }
1337
1338         port->std = V4L2_STD_NTSC_M;
1339         video_set_drvdata(port->v4l_device, port);
1340         result = video_register_device(port->v4l_device,
1341                 VFL_TYPE_VBI, -1);
1342         if (result < 0) {
1343                 printk(KERN_INFO "%s: can't register vbi device\n",
1344                         dev->name);
1345                 /* TODO: We're going to leak here if we don't dealloc
1346                  The buffers above. The unreg function can't deal wit it.
1347                 */
1348                 goto failed;
1349         }
1350
1351         printk(KERN_INFO "%s: registered device vbi%d [vbi]\n",
1352                 dev->name, port->v4l_device->num);
1353
1354         /* Configure the hardware defaults */
1355
1356         result = 0;
1357 failed:
1358         return result;
1359 }
1360
1361 void saa7164_vbi_unregister(struct saa7164_port *port)
1362 {
1363         struct saa7164_dev *dev = port->dev;
1364
1365         dprintk(DBGLVL_VBI, "%s(port=%d)\n", __func__, port->nr);
1366
1367         if (port->type != SAA7164_MPEG_VBI)
1368                 BUG();
1369
1370         if (port->v4l_device) {
1371                 if (port->v4l_device->minor != -1)
1372                         video_unregister_device(port->v4l_device);
1373                 else
1374                         video_device_release(port->v4l_device);
1375
1376                 port->v4l_device = NULL;
1377         }
1378
1379 }