2 * Driver for the Conexant CX23885 PCIe bridge
4 * Copyright (c) 2007 Steven Toth <stoth@hauppauge.com>
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.
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
15 * GNU General Public License for more details.
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.
22 #include <linux/init.h>
23 #include <linux/list.h>
24 #include <linux/module.h>
25 #include <linux/moduleparam.h>
26 #include <linux/kmod.h>
27 #include <linux/kernel.h>
28 #include <linux/slab.h>
29 #include <linux/interrupt.h>
30 #include <linux/delay.h>
31 #include <linux/kthread.h>
32 #include <asm/div64.h>
35 #include <media/v4l2-common.h>
36 #include <media/v4l2-ioctl.h>
38 #ifdef CONFIG_VIDEO_V4L1_COMPAT
39 /* Include V4L1 specific functions. Should be removed soon */
40 #include <linux/videodev.h>
43 MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards");
44 MODULE_AUTHOR("Steven Toth <stoth@hauppauge.com>");
45 MODULE_LICENSE("GPL");
47 /* ------------------------------------------------------------------ */
49 static unsigned int video_nr
[] = {[0 ... (CX23885_MAXBOARDS
- 1)] = UNSET
};
50 static unsigned int vbi_nr
[] = {[0 ... (CX23885_MAXBOARDS
- 1)] = UNSET
};
51 static unsigned int radio_nr
[] = {[0 ... (CX23885_MAXBOARDS
- 1)] = UNSET
};
53 module_param_array(video_nr
, int, NULL
, 0444);
54 module_param_array(vbi_nr
, int, NULL
, 0444);
55 module_param_array(radio_nr
, int, NULL
, 0444);
57 MODULE_PARM_DESC(video_nr
, "video device numbers");
58 MODULE_PARM_DESC(vbi_nr
, "vbi device numbers");
59 MODULE_PARM_DESC(radio_nr
, "radio device numbers");
61 static unsigned int video_debug
;
62 module_param(video_debug
, int, 0644);
63 MODULE_PARM_DESC(video_debug
, "enable debug messages [video]");
65 static unsigned int irq_debug
;
66 module_param(irq_debug
, int, 0644);
67 MODULE_PARM_DESC(irq_debug
, "enable debug messages [IRQ handler]");
69 static unsigned int vid_limit
= 16;
70 module_param(vid_limit
, int, 0644);
71 MODULE_PARM_DESC(vid_limit
, "capture memory limit in megabytes");
73 #define dprintk(level, fmt, arg...)\
74 do { if (video_debug >= level)\
75 printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\
78 /* ------------------------------------------------------------------- */
81 #define FORMAT_FLAGS_PACKED 0x01
83 static struct cx23885_fmt formats
[] = {
85 .name
= "8 bpp, gray",
86 .fourcc
= V4L2_PIX_FMT_GREY
,
88 .flags
= FORMAT_FLAGS_PACKED
,
90 .name
= "15 bpp RGB, le",
91 .fourcc
= V4L2_PIX_FMT_RGB555
,
93 .flags
= FORMAT_FLAGS_PACKED
,
95 .name
= "15 bpp RGB, be",
96 .fourcc
= V4L2_PIX_FMT_RGB555X
,
98 .flags
= FORMAT_FLAGS_PACKED
,
100 .name
= "16 bpp RGB, le",
101 .fourcc
= V4L2_PIX_FMT_RGB565
,
103 .flags
= FORMAT_FLAGS_PACKED
,
105 .name
= "16 bpp RGB, be",
106 .fourcc
= V4L2_PIX_FMT_RGB565X
,
108 .flags
= FORMAT_FLAGS_PACKED
,
110 .name
= "24 bpp RGB, le",
111 .fourcc
= V4L2_PIX_FMT_BGR24
,
113 .flags
= FORMAT_FLAGS_PACKED
,
115 .name
= "32 bpp RGB, le",
116 .fourcc
= V4L2_PIX_FMT_BGR32
,
118 .flags
= FORMAT_FLAGS_PACKED
,
120 .name
= "32 bpp RGB, be",
121 .fourcc
= V4L2_PIX_FMT_RGB32
,
123 .flags
= FORMAT_FLAGS_PACKED
,
125 .name
= "4:2:2, packed, YUYV",
126 .fourcc
= V4L2_PIX_FMT_YUYV
,
128 .flags
= FORMAT_FLAGS_PACKED
,
130 .name
= "4:2:2, packed, UYVY",
131 .fourcc
= V4L2_PIX_FMT_UYVY
,
133 .flags
= FORMAT_FLAGS_PACKED
,
137 static struct cx23885_fmt
*format_by_fourcc(unsigned int fourcc
)
141 for (i
= 0; i
< ARRAY_SIZE(formats
); i
++)
142 if (formats
[i
].fourcc
== fourcc
)
145 printk(KERN_ERR
"%s(0x%08x) NOT FOUND\n", __func__
, fourcc
);
149 /* ------------------------------------------------------------------- */
151 static const struct v4l2_queryctrl no_ctl
= {
153 .flags
= V4L2_CTRL_FLAG_DISABLED
,
156 static struct cx23885_ctrl cx23885_ctls
[] = {
160 .id
= V4L2_CID_BRIGHTNESS
,
161 .name
= "Brightness",
165 .default_value
= 0x7f,
166 .type
= V4L2_CTRL_TYPE_INTEGER
,
174 .id
= V4L2_CID_CONTRAST
,
179 .default_value
= 0x3f,
180 .type
= V4L2_CTRL_TYPE_INTEGER
,
193 .default_value
= 0x7f,
194 .type
= V4L2_CTRL_TYPE_INTEGER
,
201 /* strictly, this only describes only U saturation.
202 * V saturation is handled specially through code.
205 .id
= V4L2_CID_SATURATION
,
206 .name
= "Saturation",
210 .default_value
= 0x7f,
211 .type
= V4L2_CTRL_TYPE_INTEGER
,
220 .id
= V4L2_CID_AUDIO_MUTE
,
225 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
228 .mask
= (0x1f << 24),
232 .id
= V4L2_CID_AUDIO_VOLUME
,
237 .default_value
= 0x3f,
238 .type
= V4L2_CTRL_TYPE_INTEGER
,
240 .reg
= PATH1_VOL_CTL
,
245 static const int CX23885_CTLS
= ARRAY_SIZE(cx23885_ctls
);
247 const u32 cx23885_user_ctrls
[] = {
253 V4L2_CID_AUDIO_VOLUME
,
257 EXPORT_SYMBOL(cx23885_user_ctrls
);
259 static const u32
*ctrl_classes
[] = {
264 void cx23885_video_wakeup(struct cx23885_dev
*dev
,
265 struct cx23885_dmaqueue
*q
, u32 count
)
267 struct cx23885_buffer
*buf
;
270 for (bc
= 0;; bc
++) {
271 if (list_empty(&q
->active
))
273 buf
= list_entry(q
->active
.next
,
274 struct cx23885_buffer
, vb
.queue
);
276 /* count comes from the hw and is is 16bit wide --
277 * this trick handles wrap-arounds correctly for
278 * up to 32767 buffers in flight... */
279 if ((s16
) (count
- buf
->count
) < 0)
282 do_gettimeofday(&buf
->vb
.ts
);
283 dprintk(2, "[%p/%d] wakeup reg=%d buf=%d\n", buf
, buf
->vb
.i
,
285 buf
->vb
.state
= VIDEOBUF_DONE
;
286 list_del(&buf
->vb
.queue
);
287 wake_up(&buf
->vb
.done
);
289 if (list_empty(&q
->active
)) {
290 del_timer(&q
->timeout
);
292 mod_timer(&q
->timeout
, jiffies
+BUFFER_TIMEOUT
);
295 printk(KERN_ERR
"%s: %d buffers handled (should be 1)\n",
299 int cx23885_set_tvnorm(struct cx23885_dev
*dev
, v4l2_std_id norm
)
301 dprintk(1, "%s(norm = 0x%08x) name: [%s]\n",
304 v4l2_norm_to_name(norm
));
308 /* Tell the analog tuner/demods */
309 cx23885_call_i2c_clients(&dev
->i2c_bus
[1], VIDIOC_S_STD
, &norm
);
311 /* Tell the internal A/V decoder */
312 cx23885_call_i2c_clients(&dev
->i2c_bus
[2], VIDIOC_S_STD
, &norm
);
317 struct video_device
*cx23885_vdev_init(struct cx23885_dev
*dev
,
319 struct video_device
*template,
322 struct video_device
*vfd
;
323 dprintk(1, "%s()\n", __func__
);
325 vfd
= video_device_alloc();
330 vfd
->parent
= &pci
->dev
;
331 vfd
->release
= video_device_release
;
332 snprintf(vfd
->name
, sizeof(vfd
->name
), "%s %s (%s)",
333 dev
->name
, type
, cx23885_boards
[dev
->board
].name
);
337 int cx23885_ctrl_query(struct v4l2_queryctrl
*qctrl
)
341 if (qctrl
->id
< V4L2_CID_BASE
||
342 qctrl
->id
>= V4L2_CID_LASTP1
)
344 for (i
= 0; i
< CX23885_CTLS
; i
++)
345 if (cx23885_ctls
[i
].v
.id
== qctrl
->id
)
347 if (i
== CX23885_CTLS
) {
351 *qctrl
= cx23885_ctls
[i
].v
;
354 EXPORT_SYMBOL(cx23885_ctrl_query
);
356 /* ------------------------------------------------------------------- */
357 /* resource management */
359 static int res_get(struct cx23885_dev
*dev
, struct cx23885_fh
*fh
,
362 dprintk(1, "%s()\n", __func__
);
363 if (fh
->resources
& bit
)
364 /* have it already allocated */
368 mutex_lock(&dev
->lock
);
369 if (dev
->resources
& bit
) {
370 /* no, someone else uses it */
371 mutex_unlock(&dev
->lock
);
374 /* it's free, grab it */
375 fh
->resources
|= bit
;
376 dev
->resources
|= bit
;
377 dprintk(1, "res: get %d\n", bit
);
378 mutex_unlock(&dev
->lock
);
382 static int res_check(struct cx23885_fh
*fh
, unsigned int bit
)
384 return (fh
->resources
& bit
);
387 static int res_locked(struct cx23885_dev
*dev
, unsigned int bit
)
389 return (dev
->resources
& bit
);
392 static void res_free(struct cx23885_dev
*dev
, struct cx23885_fh
*fh
,
395 BUG_ON((fh
->resources
& bits
) != bits
);
396 dprintk(1, "%s()\n", __func__
);
398 mutex_lock(&dev
->lock
);
399 fh
->resources
&= ~bits
;
400 dev
->resources
&= ~bits
;
401 dprintk(1, "res: put %d\n", bits
);
402 mutex_unlock(&dev
->lock
);
405 int cx23885_video_mux(struct cx23885_dev
*dev
, unsigned int input
)
407 struct v4l2_routing route
;
408 memset(&route
, 0, sizeof(route
));
410 dprintk(1, "%s() video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n",
412 input
, INPUT(input
)->vmux
,
413 INPUT(input
)->gpio0
, INPUT(input
)->gpio1
,
414 INPUT(input
)->gpio2
, INPUT(input
)->gpio3
);
417 route
.input
= INPUT(input
)->vmux
;
419 /* Tell the internal A/V decoder */
420 cx23885_call_i2c_clients(&dev
->i2c_bus
[2],
421 VIDIOC_INT_S_VIDEO_ROUTING
, &route
);
425 EXPORT_SYMBOL(cx23885_video_mux
);
427 /* ------------------------------------------------------------------ */
428 int cx23885_set_scale(struct cx23885_dev
*dev
, unsigned int width
,
429 unsigned int height
, enum v4l2_field field
)
431 dprintk(1, "%s()\n", __func__
);
435 static int cx23885_start_video_dma(struct cx23885_dev
*dev
,
436 struct cx23885_dmaqueue
*q
,
437 struct cx23885_buffer
*buf
)
439 dprintk(1, "%s()\n", __func__
);
441 /* setup fifo + format */
442 cx23885_sram_channel_setup(dev
, &dev
->sram_channels
[SRAM_CH01
],
443 buf
->bpl
, buf
->risc
.dma
);
444 cx23885_set_scale(dev
, buf
->vb
.width
, buf
->vb
.height
, buf
->vb
.field
);
447 cx_write(VID_A_GPCNT_CTL
, 3);
451 cx_set(PCI_INT_MSK
, cx_read(PCI_INT_MSK
) | 0x01);
452 cx_set(VID_A_INT_MSK
, 0x000011);
455 cx_set(DEV_CNTRL2
, (1<<5));
456 cx_set(VID_A_DMA_CTL
, 0x11); /* FIFO and RISC enable */
462 static int cx23885_restart_video_queue(struct cx23885_dev
*dev
,
463 struct cx23885_dmaqueue
*q
)
465 struct cx23885_buffer
*buf
, *prev
;
466 struct list_head
*item
;
467 dprintk(1, "%s()\n", __func__
);
469 if (!list_empty(&q
->active
)) {
470 buf
= list_entry(q
->active
.next
, struct cx23885_buffer
,
472 dprintk(2, "restart_queue [%p/%d]: restart dma\n",
474 cx23885_start_video_dma(dev
, q
, buf
);
475 list_for_each(item
, &q
->active
) {
476 buf
= list_entry(item
, struct cx23885_buffer
,
478 buf
->count
= q
->count
++;
480 mod_timer(&q
->timeout
, jiffies
+BUFFER_TIMEOUT
);
486 if (list_empty(&q
->queued
))
488 buf
= list_entry(q
->queued
.next
, struct cx23885_buffer
,
491 list_move_tail(&buf
->vb
.queue
, &q
->active
);
492 cx23885_start_video_dma(dev
, q
, buf
);
493 buf
->vb
.state
= VIDEOBUF_ACTIVE
;
494 buf
->count
= q
->count
++;
495 mod_timer(&q
->timeout
, jiffies
+BUFFER_TIMEOUT
);
496 dprintk(2, "[%p/%d] restart_queue - first active\n",
499 } else if (prev
->vb
.width
== buf
->vb
.width
&&
500 prev
->vb
.height
== buf
->vb
.height
&&
501 prev
->fmt
== buf
->fmt
) {
502 list_move_tail(&buf
->vb
.queue
, &q
->active
);
503 buf
->vb
.state
= VIDEOBUF_ACTIVE
;
504 buf
->count
= q
->count
++;
505 prev
->risc
.jmp
[1] = cpu_to_le32(buf
->risc
.dma
);
506 prev
->risc
.jmp
[2] = cpu_to_le32(0); /* Bits 63 - 32 */
507 dprintk(2, "[%p/%d] restart_queue - move to active\n",
516 static int buffer_setup(struct videobuf_queue
*q
, unsigned int *count
,
519 struct cx23885_fh
*fh
= q
->priv_data
;
521 *size
= fh
->fmt
->depth
*fh
->width
*fh
->height
>> 3;
524 while (*size
* *count
> vid_limit
* 1024 * 1024)
529 static int buffer_prepare(struct videobuf_queue
*q
, struct videobuf_buffer
*vb
,
530 enum v4l2_field field
)
532 struct cx23885_fh
*fh
= q
->priv_data
;
533 struct cx23885_dev
*dev
= fh
->dev
;
534 struct cx23885_buffer
*buf
=
535 container_of(vb
, struct cx23885_buffer
, vb
);
536 int rc
, init_buffer
= 0;
537 u32 line0_offset
, line1_offset
;
538 struct videobuf_dmabuf
*dma
= videobuf_to_dma(&buf
->vb
);
540 BUG_ON(NULL
== fh
->fmt
);
541 if (fh
->width
< 48 || fh
->width
> norm_maxw(dev
->tvnorm
) ||
542 fh
->height
< 32 || fh
->height
> norm_maxh(dev
->tvnorm
))
544 buf
->vb
.size
= (fh
->width
* fh
->height
* fh
->fmt
->depth
) >> 3;
545 if (0 != buf
->vb
.baddr
&& buf
->vb
.bsize
< buf
->vb
.size
)
548 if (buf
->fmt
!= fh
->fmt
||
549 buf
->vb
.width
!= fh
->width
||
550 buf
->vb
.height
!= fh
->height
||
551 buf
->vb
.field
!= field
) {
553 buf
->vb
.width
= fh
->width
;
554 buf
->vb
.height
= fh
->height
;
555 buf
->vb
.field
= field
;
559 if (VIDEOBUF_NEEDS_INIT
== buf
->vb
.state
) {
561 rc
= videobuf_iolock(q
, &buf
->vb
, NULL
);
567 buf
->bpl
= buf
->vb
.width
* buf
->fmt
->depth
>> 3;
568 switch (buf
->vb
.field
) {
570 cx23885_risc_buffer(dev
->pci
, &buf
->risc
,
571 dma
->sglist
, 0, UNSET
,
572 buf
->bpl
, 0, buf
->vb
.height
);
574 case V4L2_FIELD_BOTTOM
:
575 cx23885_risc_buffer(dev
->pci
, &buf
->risc
,
576 dma
->sglist
, UNSET
, 0,
577 buf
->bpl
, 0, buf
->vb
.height
);
579 case V4L2_FIELD_INTERLACED
:
580 if (dev
->tvnorm
& V4L2_STD_NTSC
) {
581 /* cx25840 transmits NTSC bottom field first */
582 dprintk(1, "%s() Creating NTSC risc\n",
584 line0_offset
= buf
->bpl
;
587 /* All other formats are top field first */
588 dprintk(1, "%s() Creating PAL/SECAM risc\n",
591 line1_offset
= buf
->bpl
;
593 cx23885_risc_buffer(dev
->pci
, &buf
->risc
,
594 dma
->sglist
, line0_offset
,
597 buf
->vb
.height
>> 1);
599 case V4L2_FIELD_SEQ_TB
:
600 cx23885_risc_buffer(dev
->pci
, &buf
->risc
,
602 0, buf
->bpl
* (buf
->vb
.height
>> 1),
604 buf
->vb
.height
>> 1);
606 case V4L2_FIELD_SEQ_BT
:
607 cx23885_risc_buffer(dev
->pci
, &buf
->risc
,
609 buf
->bpl
* (buf
->vb
.height
>> 1), 0,
611 buf
->vb
.height
>> 1);
617 dprintk(2, "[%p/%d] buffer_prep - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
619 fh
->width
, fh
->height
, fh
->fmt
->depth
, fh
->fmt
->name
,
620 (unsigned long)buf
->risc
.dma
);
622 buf
->vb
.state
= VIDEOBUF_PREPARED
;
626 cx23885_free_buffer(q
, buf
);
630 static void buffer_queue(struct videobuf_queue
*vq
, struct videobuf_buffer
*vb
)
632 struct cx23885_buffer
*buf
= container_of(vb
,
633 struct cx23885_buffer
, vb
);
634 struct cx23885_buffer
*prev
;
635 struct cx23885_fh
*fh
= vq
->priv_data
;
636 struct cx23885_dev
*dev
= fh
->dev
;
637 struct cx23885_dmaqueue
*q
= &dev
->vidq
;
639 /* add jump to stopper */
640 buf
->risc
.jmp
[0] = cpu_to_le32(RISC_JUMP
| RISC_IRQ1
| RISC_CNT_INC
);
641 buf
->risc
.jmp
[1] = cpu_to_le32(q
->stopper
.dma
);
642 buf
->risc
.jmp
[2] = cpu_to_le32(0); /* bits 63-32 */
644 if (!list_empty(&q
->queued
)) {
645 list_add_tail(&buf
->vb
.queue
, &q
->queued
);
646 buf
->vb
.state
= VIDEOBUF_QUEUED
;
647 dprintk(2, "[%p/%d] buffer_queue - append to queued\n",
650 } else if (list_empty(&q
->active
)) {
651 list_add_tail(&buf
->vb
.queue
, &q
->active
);
652 cx23885_start_video_dma(dev
, q
, buf
);
653 buf
->vb
.state
= VIDEOBUF_ACTIVE
;
654 buf
->count
= q
->count
++;
655 mod_timer(&q
->timeout
, jiffies
+BUFFER_TIMEOUT
);
656 dprintk(2, "[%p/%d] buffer_queue - first active\n",
660 prev
= list_entry(q
->active
.prev
, struct cx23885_buffer
,
662 if (prev
->vb
.width
== buf
->vb
.width
&&
663 prev
->vb
.height
== buf
->vb
.height
&&
664 prev
->fmt
== buf
->fmt
) {
665 list_add_tail(&buf
->vb
.queue
, &q
->active
);
666 buf
->vb
.state
= VIDEOBUF_ACTIVE
;
667 buf
->count
= q
->count
++;
668 prev
->risc
.jmp
[1] = cpu_to_le32(buf
->risc
.dma
);
669 /* 64 bit bits 63-32 */
670 prev
->risc
.jmp
[2] = cpu_to_le32(0);
671 dprintk(2, "[%p/%d] buffer_queue - append to active\n",
675 list_add_tail(&buf
->vb
.queue
, &q
->queued
);
676 buf
->vb
.state
= VIDEOBUF_QUEUED
;
677 dprintk(2, "[%p/%d] buffer_queue - first queued\n",
683 static void buffer_release(struct videobuf_queue
*q
,
684 struct videobuf_buffer
*vb
)
686 struct cx23885_buffer
*buf
= container_of(vb
,
687 struct cx23885_buffer
, vb
);
689 cx23885_free_buffer(q
, buf
);
692 static struct videobuf_queue_ops cx23885_video_qops
= {
693 .buf_setup
= buffer_setup
,
694 .buf_prepare
= buffer_prepare
,
695 .buf_queue
= buffer_queue
,
696 .buf_release
= buffer_release
,
699 static struct videobuf_queue
*get_queue(struct cx23885_fh
*fh
)
702 case V4L2_BUF_TYPE_VIDEO_CAPTURE
:
704 case V4L2_BUF_TYPE_VBI_CAPTURE
:
712 static int get_resource(struct cx23885_fh
*fh
)
715 case V4L2_BUF_TYPE_VIDEO_CAPTURE
:
716 return RESOURCE_VIDEO
;
717 case V4L2_BUF_TYPE_VBI_CAPTURE
:
725 static int video_open(struct inode
*inode
, struct file
*file
)
727 int minor
= iminor(inode
);
728 struct cx23885_dev
*h
, *dev
= NULL
;
729 struct cx23885_fh
*fh
;
730 struct list_head
*list
;
731 enum v4l2_buf_type type
= 0;
734 list_for_each(list
, &cx23885_devlist
) {
735 h
= list_entry(list
, struct cx23885_dev
, devlist
);
736 if (h
->video_dev
->minor
== minor
) {
738 type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
741 h
->vbi_dev
->minor
== minor
) {
743 type
= V4L2_BUF_TYPE_VBI_CAPTURE
;
746 h
->radio_dev
->minor
== minor
) {
754 dprintk(1, "open minor=%d radio=%d type=%s\n",
755 minor
, radio
, v4l2_type_names
[type
]);
757 /* allocate + initialize per filehandle data */
758 fh
= kzalloc(sizeof(*fh
), GFP_KERNEL
);
761 file
->private_data
= fh
;
767 fh
->fmt
= format_by_fourcc(V4L2_PIX_FMT_BGR24
);
769 videobuf_queue_sg_init(&fh
->vidq
, &cx23885_video_qops
,
770 &dev
->pci
->dev
, &dev
->slock
,
771 V4L2_BUF_TYPE_VIDEO_CAPTURE
,
772 V4L2_FIELD_INTERLACED
,
773 sizeof(struct cx23885_buffer
),
776 dprintk(1, "post videobuf_queue_init()\n");
782 static ssize_t
video_read(struct file
*file
, char __user
*data
,
783 size_t count
, loff_t
*ppos
)
785 struct cx23885_fh
*fh
= file
->private_data
;
788 case V4L2_BUF_TYPE_VIDEO_CAPTURE
:
789 if (res_locked(fh
->dev
, RESOURCE_VIDEO
))
791 return videobuf_read_one(&fh
->vidq
, data
, count
, ppos
,
792 file
->f_flags
& O_NONBLOCK
);
793 case V4L2_BUF_TYPE_VBI_CAPTURE
:
794 if (!res_get(fh
->dev
, fh
, RESOURCE_VBI
))
796 return videobuf_read_stream(&fh
->vbiq
, data
, count
, ppos
, 1,
797 file
->f_flags
& O_NONBLOCK
);
804 static unsigned int video_poll(struct file
*file
,
805 struct poll_table_struct
*wait
)
807 struct cx23885_fh
*fh
= file
->private_data
;
808 struct cx23885_buffer
*buf
;
810 if (V4L2_BUF_TYPE_VBI_CAPTURE
== fh
->type
) {
811 if (!res_get(fh
->dev
, fh
, RESOURCE_VBI
))
813 return videobuf_poll_stream(file
, &fh
->vbiq
, wait
);
816 if (res_check(fh
, RESOURCE_VIDEO
)) {
817 /* streaming capture */
818 if (list_empty(&fh
->vidq
.stream
))
820 buf
= list_entry(fh
->vidq
.stream
.next
,
821 struct cx23885_buffer
, vb
.stream
);
824 buf
= (struct cx23885_buffer
*)fh
->vidq
.read_buf
;
828 poll_wait(file
, &buf
->vb
.done
, wait
);
829 if (buf
->vb
.state
== VIDEOBUF_DONE
||
830 buf
->vb
.state
== VIDEOBUF_ERROR
)
831 return POLLIN
|POLLRDNORM
;
835 static int video_release(struct inode
*inode
, struct file
*file
)
837 struct cx23885_fh
*fh
= file
->private_data
;
838 struct cx23885_dev
*dev
= fh
->dev
;
840 /* turn off overlay */
841 if (res_check(fh
, RESOURCE_OVERLAY
)) {
843 res_free(dev
, fh
, RESOURCE_OVERLAY
);
846 /* stop video capture */
847 if (res_check(fh
, RESOURCE_VIDEO
)) {
848 videobuf_queue_cancel(&fh
->vidq
);
849 res_free(dev
, fh
, RESOURCE_VIDEO
);
851 if (fh
->vidq
.read_buf
) {
852 buffer_release(&fh
->vidq
, fh
->vidq
.read_buf
);
853 kfree(fh
->vidq
.read_buf
);
856 /* stop vbi capture */
857 if (res_check(fh
, RESOURCE_VBI
)) {
858 if (fh
->vbiq
.streaming
)
859 videobuf_streamoff(&fh
->vbiq
);
860 if (fh
->vbiq
.reading
)
861 videobuf_read_stop(&fh
->vbiq
);
862 res_free(dev
, fh
, RESOURCE_VBI
);
865 videobuf_mmap_free(&fh
->vidq
);
866 file
->private_data
= NULL
;
869 /* We are not putting the tuner to sleep here on exit, because
870 * we want to use the mpeg encoder in another session to capture
871 * tuner video. Closing this will result in no video to the encoder.
877 static int video_mmap(struct file
*file
, struct vm_area_struct
*vma
)
879 struct cx23885_fh
*fh
= file
->private_data
;
881 return videobuf_mmap_mapper(get_queue(fh
), vma
);
884 /* ------------------------------------------------------------------ */
885 /* VIDEO CTRL IOCTLS */
887 int cx23885_get_control(struct cx23885_dev
*dev
, struct v4l2_control
*ctl
)
889 dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __func__
);
890 cx23885_call_i2c_clients(&dev
->i2c_bus
[2], VIDIOC_G_CTRL
, ctl
);
893 EXPORT_SYMBOL(cx23885_get_control
);
895 int cx23885_set_control(struct cx23885_dev
*dev
, struct v4l2_control
*ctl
)
897 dprintk(1, "%s() calling cx25840(VIDIOC_S_CTRL)"
898 " (disabled - no action)\n", __func__
);
901 EXPORT_SYMBOL(cx23885_set_control
);
903 static void init_controls(struct cx23885_dev
*dev
)
905 struct v4l2_control ctrl
;
908 for (i
= 0; i
< CX23885_CTLS
; i
++) {
909 ctrl
.id
= cx23885_ctls
[i
].v
.id
;
910 ctrl
.value
= cx23885_ctls
[i
].v
.default_value
;
912 cx23885_set_control(dev
, &ctrl
);
916 /* ------------------------------------------------------------------ */
919 static int vidioc_g_fmt_vid_cap(struct file
*file
, void *priv
,
920 struct v4l2_format
*f
)
922 struct cx23885_fh
*fh
= priv
;
924 f
->fmt
.pix
.width
= fh
->width
;
925 f
->fmt
.pix
.height
= fh
->height
;
926 f
->fmt
.pix
.field
= fh
->vidq
.field
;
927 f
->fmt
.pix
.pixelformat
= fh
->fmt
->fourcc
;
928 f
->fmt
.pix
.bytesperline
=
929 (f
->fmt
.pix
.width
* fh
->fmt
->depth
) >> 3;
930 f
->fmt
.pix
.sizeimage
=
931 f
->fmt
.pix
.height
* f
->fmt
.pix
.bytesperline
;
936 static int vidioc_try_fmt_vid_cap(struct file
*file
, void *priv
,
937 struct v4l2_format
*f
)
939 struct cx23885_dev
*dev
= ((struct cx23885_fh
*)priv
)->dev
;
940 struct cx23885_fmt
*fmt
;
941 enum v4l2_field field
;
942 unsigned int maxw
, maxh
;
944 fmt
= format_by_fourcc(f
->fmt
.pix
.pixelformat
);
948 field
= f
->fmt
.pix
.field
;
949 maxw
= norm_maxw(dev
->tvnorm
);
950 maxh
= norm_maxh(dev
->tvnorm
);
952 if (V4L2_FIELD_ANY
== field
) {
953 field
= (f
->fmt
.pix
.height
> maxh
/2)
954 ? V4L2_FIELD_INTERLACED
960 case V4L2_FIELD_BOTTOM
:
963 case V4L2_FIELD_INTERLACED
:
969 f
->fmt
.pix
.field
= field
;
970 if (f
->fmt
.pix
.height
< 32)
971 f
->fmt
.pix
.height
= 32;
972 if (f
->fmt
.pix
.height
> maxh
)
973 f
->fmt
.pix
.height
= maxh
;
974 if (f
->fmt
.pix
.width
< 48)
975 f
->fmt
.pix
.width
= 48;
976 if (f
->fmt
.pix
.width
> maxw
)
977 f
->fmt
.pix
.width
= maxw
;
978 f
->fmt
.pix
.width
&= ~0x03;
979 f
->fmt
.pix
.bytesperline
=
980 (f
->fmt
.pix
.width
* fmt
->depth
) >> 3;
981 f
->fmt
.pix
.sizeimage
=
982 f
->fmt
.pix
.height
* f
->fmt
.pix
.bytesperline
;
987 static int vidioc_s_fmt_vid_cap(struct file
*file
, void *priv
,
988 struct v4l2_format
*f
)
990 struct cx23885_fh
*fh
= priv
;
991 struct cx23885_dev
*dev
= ((struct cx23885_fh
*)priv
)->dev
;
994 dprintk(2, "%s()\n", __func__
);
995 err
= vidioc_try_fmt_vid_cap(file
, priv
, f
);
999 fh
->fmt
= format_by_fourcc(f
->fmt
.pix
.pixelformat
);
1000 fh
->width
= f
->fmt
.pix
.width
;
1001 fh
->height
= f
->fmt
.pix
.height
;
1002 fh
->vidq
.field
= f
->fmt
.pix
.field
;
1003 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__
,
1004 fh
->width
, fh
->height
, fh
->vidq
.field
);
1005 cx23885_call_i2c_clients(&dev
->i2c_bus
[2], VIDIOC_S_FMT
, f
);
1009 static int vidioc_querycap(struct file
*file
, void *priv
,
1010 struct v4l2_capability
*cap
)
1012 struct cx23885_dev
*dev
= ((struct cx23885_fh
*)priv
)->dev
;
1014 strcpy(cap
->driver
, "cx23885");
1015 strlcpy(cap
->card
, cx23885_boards
[dev
->board
].name
,
1017 sprintf(cap
->bus_info
, "PCIe:%s", pci_name(dev
->pci
));
1018 cap
->version
= CX23885_VERSION_CODE
;
1020 V4L2_CAP_VIDEO_CAPTURE
|
1021 V4L2_CAP_READWRITE
|
1022 V4L2_CAP_STREAMING
|
1023 V4L2_CAP_VBI_CAPTURE
;
1024 if (UNSET
!= dev
->tuner_type
)
1025 cap
->capabilities
|= V4L2_CAP_TUNER
;
1029 static int vidioc_enum_fmt_vid_cap(struct file
*file
, void *priv
,
1030 struct v4l2_fmtdesc
*f
)
1032 if (unlikely(f
->index
>= ARRAY_SIZE(formats
)))
1035 strlcpy(f
->description
, formats
[f
->index
].name
,
1036 sizeof(f
->description
));
1037 f
->pixelformat
= formats
[f
->index
].fourcc
;
1042 #ifdef CONFIG_VIDEO_V4L1_COMPAT
1043 static int vidiocgmbuf(struct file
*file
, void *priv
,
1044 struct video_mbuf
*mbuf
)
1046 struct cx23885_fh
*fh
= priv
;
1047 struct videobuf_queue
*q
;
1048 struct v4l2_requestbuffers req
;
1053 memset(&req
, 0, sizeof(req
));
1056 req
.memory
= V4L2_MEMORY_MMAP
;
1057 err
= videobuf_reqbufs(q
, &req
);
1061 mbuf
->frames
= req
.count
;
1063 for (i
= 0; i
< mbuf
->frames
; i
++) {
1064 mbuf
->offsets
[i
] = q
->bufs
[i
]->boff
;
1065 mbuf
->size
+= q
->bufs
[i
]->bsize
;
1071 static int vidioc_reqbufs(struct file
*file
, void *priv
,
1072 struct v4l2_requestbuffers
*p
)
1074 struct cx23885_fh
*fh
= priv
;
1075 return (videobuf_reqbufs(get_queue(fh
), p
));
1078 static int vidioc_querybuf(struct file
*file
, void *priv
,
1079 struct v4l2_buffer
*p
)
1081 struct cx23885_fh
*fh
= priv
;
1082 return (videobuf_querybuf(get_queue(fh
), p
));
1085 static int vidioc_qbuf(struct file
*file
, void *priv
,
1086 struct v4l2_buffer
*p
)
1088 struct cx23885_fh
*fh
= priv
;
1089 return (videobuf_qbuf(get_queue(fh
), p
));
1092 static int vidioc_dqbuf(struct file
*file
, void *priv
,
1093 struct v4l2_buffer
*p
)
1095 struct cx23885_fh
*fh
= priv
;
1096 return (videobuf_dqbuf(get_queue(fh
), p
,
1097 file
->f_flags
& O_NONBLOCK
));
1100 static int vidioc_streamon(struct file
*file
, void *priv
,
1101 enum v4l2_buf_type i
)
1103 struct cx23885_fh
*fh
= priv
;
1104 struct cx23885_dev
*dev
= fh
->dev
;
1105 dprintk(1, "%s()\n", __func__
);
1107 if (unlikely(fh
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
))
1109 if (unlikely(i
!= fh
->type
))
1112 if (unlikely(!res_get(dev
, fh
, get_resource(fh
))))
1114 return videobuf_streamon(get_queue(fh
));
1117 static int vidioc_streamoff(struct file
*file
, void *priv
, enum v4l2_buf_type i
)
1119 struct cx23885_fh
*fh
= priv
;
1120 struct cx23885_dev
*dev
= fh
->dev
;
1122 dprintk(1, "%s()\n", __func__
);
1124 if (fh
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
1129 res
= get_resource(fh
);
1130 err
= videobuf_streamoff(get_queue(fh
));
1133 res_free(dev
, fh
, res
);
1137 static int vidioc_s_std(struct file
*file
, void *priv
, v4l2_std_id
*tvnorms
)
1139 struct cx23885_dev
*dev
= ((struct cx23885_fh
*)priv
)->dev
;
1140 dprintk(1, "%s()\n", __func__
);
1142 mutex_lock(&dev
->lock
);
1143 cx23885_set_tvnorm(dev
, *tvnorms
);
1144 mutex_unlock(&dev
->lock
);
1149 int cx23885_enum_input(struct cx23885_dev
*dev
, struct v4l2_input
*i
)
1151 static const char *iname
[] = {
1152 [CX23885_VMUX_COMPOSITE1
] = "Composite1",
1153 [CX23885_VMUX_COMPOSITE2
] = "Composite2",
1154 [CX23885_VMUX_COMPOSITE3
] = "Composite3",
1155 [CX23885_VMUX_COMPOSITE4
] = "Composite4",
1156 [CX23885_VMUX_SVIDEO
] = "S-Video",
1157 [CX23885_VMUX_TELEVISION
] = "Television",
1158 [CX23885_VMUX_CABLE
] = "Cable TV",
1159 [CX23885_VMUX_DVB
] = "DVB",
1160 [CX23885_VMUX_DEBUG
] = "for debug only",
1163 dprintk(1, "%s()\n", __func__
);
1169 if (0 == INPUT(n
)->type
)
1172 memset(i
, 0, sizeof(*i
));
1174 i
->type
= V4L2_INPUT_TYPE_CAMERA
;
1175 strcpy(i
->name
, iname
[INPUT(n
)->type
]);
1176 if ((CX23885_VMUX_TELEVISION
== INPUT(n
)->type
) ||
1177 (CX23885_VMUX_CABLE
== INPUT(n
)->type
))
1178 i
->type
= V4L2_INPUT_TYPE_TUNER
;
1179 i
->std
= CX23885_NORMS
;
1182 EXPORT_SYMBOL(cx23885_enum_input
);
1184 static int vidioc_enum_input(struct file
*file
, void *priv
,
1185 struct v4l2_input
*i
)
1187 struct cx23885_dev
*dev
= ((struct cx23885_fh
*)priv
)->dev
;
1188 dprintk(1, "%s()\n", __func__
);
1189 return cx23885_enum_input(dev
, i
);
1192 static int vidioc_g_input(struct file
*file
, void *priv
, unsigned int *i
)
1194 struct cx23885_dev
*dev
= ((struct cx23885_fh
*)priv
)->dev
;
1197 dprintk(1, "%s() returns %d\n", __func__
, *i
);
1201 static int vidioc_s_input(struct file
*file
, void *priv
, unsigned int i
)
1203 struct cx23885_dev
*dev
= ((struct cx23885_fh
*)priv
)->dev
;
1205 dprintk(1, "%s(%d)\n", __func__
, i
);
1208 dprintk(1, "%s() -EINVAL\n", __func__
);
1212 mutex_lock(&dev
->lock
);
1213 cx23885_video_mux(dev
, i
);
1214 mutex_unlock(&dev
->lock
);
1218 static int vidioc_queryctrl(struct file
*file
, void *priv
,
1219 struct v4l2_queryctrl
*qctrl
)
1221 qctrl
->id
= v4l2_ctrl_next(ctrl_classes
, qctrl
->id
);
1222 if (unlikely(qctrl
->id
== 0))
1224 return cx23885_ctrl_query(qctrl
);
1227 static int vidioc_g_ctrl(struct file
*file
, void *priv
,
1228 struct v4l2_control
*ctl
)
1230 struct cx23885_dev
*dev
= ((struct cx23885_fh
*)priv
)->dev
;
1232 return cx23885_get_control(dev
, ctl
);
1235 static int vidioc_s_ctrl(struct file
*file
, void *priv
,
1236 struct v4l2_control
*ctl
)
1238 struct cx23885_dev
*dev
= ((struct cx23885_fh
*)priv
)->dev
;
1240 return cx23885_set_control(dev
, ctl
);
1243 static int vidioc_g_tuner(struct file
*file
, void *priv
,
1244 struct v4l2_tuner
*t
)
1246 struct cx23885_dev
*dev
= ((struct cx23885_fh
*)priv
)->dev
;
1248 if (unlikely(UNSET
== dev
->tuner_type
))
1253 strcpy(t
->name
, "Television");
1254 t
->type
= V4L2_TUNER_ANALOG_TV
;
1255 t
->capability
= V4L2_TUNER_CAP_NORM
;
1256 t
->rangehigh
= 0xffffffffUL
;
1257 t
->signal
= 0xffff ; /* LOCKED */
1261 static int vidioc_s_tuner(struct file
*file
, void *priv
,
1262 struct v4l2_tuner
*t
)
1264 struct cx23885_dev
*dev
= ((struct cx23885_fh
*)priv
)->dev
;
1266 if (UNSET
== dev
->tuner_type
)
1273 static int vidioc_g_frequency(struct file
*file
, void *priv
,
1274 struct v4l2_frequency
*f
)
1276 struct cx23885_fh
*fh
= priv
;
1277 struct cx23885_dev
*dev
= fh
->dev
;
1279 if (unlikely(UNSET
== dev
->tuner_type
))
1282 /* f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; */
1283 f
->type
= fh
->radio
? V4L2_TUNER_RADIO
: V4L2_TUNER_ANALOG_TV
;
1284 f
->frequency
= dev
->freq
;
1286 cx23885_call_i2c_clients(&dev
->i2c_bus
[1], VIDIOC_G_FREQUENCY
, f
);
1291 int cx23885_set_freq(struct cx23885_dev
*dev
, struct v4l2_frequency
*f
)
1293 if (unlikely(UNSET
== dev
->tuner_type
))
1295 if (unlikely(f
->tuner
!= 0))
1298 mutex_lock(&dev
->lock
);
1299 dev
->freq
= f
->frequency
;
1301 cx23885_call_i2c_clients(&dev
->i2c_bus
[1], VIDIOC_S_FREQUENCY
, f
);
1303 /* When changing channels it is required to reset TVAUDIO */
1306 mutex_unlock(&dev
->lock
);
1310 EXPORT_SYMBOL(cx23885_set_freq
);
1312 static int vidioc_s_frequency(struct file
*file
, void *priv
,
1313 struct v4l2_frequency
*f
)
1315 struct cx23885_fh
*fh
= priv
;
1316 struct cx23885_dev
*dev
= fh
->dev
;
1318 if (unlikely(0 == fh
->radio
&& f
->type
!= V4L2_TUNER_ANALOG_TV
))
1320 if (unlikely(1 == fh
->radio
&& f
->type
!= V4L2_TUNER_RADIO
))
1324 cx23885_set_freq(dev
, f
);
1327 #ifdef CONFIG_VIDEO_ADV_DEBUG
1328 static int vidioc_g_register(struct file
*file
, void *fh
,
1329 struct v4l2_register
*reg
)
1331 struct cx23885_dev
*dev
= ((struct cx23885_fh
*)fh
)->dev
;
1333 if (!v4l2_chip_match_host(reg
->match_type
, reg
->match_chip
))
1336 cx23885_call_i2c_clients(&dev
->i2c_bus
[2], VIDIOC_DBG_G_REGISTER
, reg
);
1341 static int vidioc_s_register(struct file
*file
, void *fh
,
1342 struct v4l2_register
*reg
)
1344 struct cx23885_dev
*dev
= ((struct cx23885_fh
*)fh
)->dev
;
1346 if (!v4l2_chip_match_host(reg
->match_type
, reg
->match_chip
))
1349 cx23885_call_i2c_clients(&dev
->i2c_bus
[2], VIDIOC_DBG_S_REGISTER
, reg
);
1355 /* ----------------------------------------------------------- */
1357 static void cx23885_vid_timeout(unsigned long data
)
1359 struct cx23885_dev
*dev
= (struct cx23885_dev
*)data
;
1360 struct cx23885_dmaqueue
*q
= &dev
->vidq
;
1361 struct cx23885_buffer
*buf
;
1362 unsigned long flags
;
1364 cx23885_sram_channel_dump(dev
, &dev
->sram_channels
[SRAM_CH01
]);
1366 cx_clear(VID_A_DMA_CTL
, 0x11);
1368 spin_lock_irqsave(&dev
->slock
, flags
);
1369 while (!list_empty(&q
->active
)) {
1370 buf
= list_entry(q
->active
.next
,
1371 struct cx23885_buffer
, vb
.queue
);
1372 list_del(&buf
->vb
.queue
);
1373 buf
->vb
.state
= VIDEOBUF_ERROR
;
1374 wake_up(&buf
->vb
.done
);
1375 printk(KERN_ERR
"%s/0: [%p/%d] timeout - dma=0x%08lx\n",
1376 dev
->name
, buf
, buf
->vb
.i
,
1377 (unsigned long)buf
->risc
.dma
);
1379 cx23885_restart_video_queue(dev
, q
);
1380 spin_unlock_irqrestore(&dev
->slock
, flags
);
1383 int cx23885_video_irq(struct cx23885_dev
*dev
, u32 status
)
1388 mask
= cx_read(VID_A_INT_MSK
);
1389 if (0 == (status
& mask
))
1391 cx_write(VID_A_INT_STAT
, status
);
1393 dprintk(2, "%s() status = 0x%08x\n", __func__
, status
);
1394 /* risc op code error */
1395 if (status
& (1 << 16)) {
1396 printk(KERN_WARNING
"%s/0: video risc op code error\n",
1398 cx_clear(VID_A_DMA_CTL
, 0x11);
1399 cx23885_sram_channel_dump(dev
, &dev
->sram_channels
[SRAM_CH01
]);
1403 if (status
& 0x01) {
1404 spin_lock(&dev
->slock
);
1405 count
= cx_read(VID_A_GPCNT
);
1406 cx23885_video_wakeup(dev
, &dev
->vidq
, count
);
1407 spin_unlock(&dev
->slock
);
1411 if (status
& 0x10) {
1412 dprintk(2, "stopper video\n");
1413 spin_lock(&dev
->slock
);
1414 cx23885_restart_video_queue(dev
, &dev
->vidq
);
1415 spin_unlock(&dev
->slock
);
1422 /* ----------------------------------------------------------- */
1423 /* exported stuff */
1425 static const struct file_operations video_fops
= {
1426 .owner
= THIS_MODULE
,
1428 .release
= video_release
,
1432 .ioctl
= video_ioctl2
,
1433 .compat_ioctl
= v4l_compat_ioctl32
,
1434 .llseek
= no_llseek
,
1437 static const struct v4l2_ioctl_ops video_ioctl_ops
= {
1438 .vidioc_querycap
= vidioc_querycap
,
1439 .vidioc_enum_fmt_vid_cap
= vidioc_enum_fmt_vid_cap
,
1440 .vidioc_g_fmt_vid_cap
= vidioc_g_fmt_vid_cap
,
1441 .vidioc_try_fmt_vid_cap
= vidioc_try_fmt_vid_cap
,
1442 .vidioc_s_fmt_vid_cap
= vidioc_s_fmt_vid_cap
,
1443 .vidioc_g_fmt_vbi_cap
= cx23885_vbi_fmt
,
1444 .vidioc_try_fmt_vbi_cap
= cx23885_vbi_fmt
,
1445 .vidioc_s_fmt_vbi_cap
= cx23885_vbi_fmt
,
1446 .vidioc_reqbufs
= vidioc_reqbufs
,
1447 .vidioc_querybuf
= vidioc_querybuf
,
1448 .vidioc_qbuf
= vidioc_qbuf
,
1449 .vidioc_dqbuf
= vidioc_dqbuf
,
1450 .vidioc_s_std
= vidioc_s_std
,
1451 .vidioc_enum_input
= vidioc_enum_input
,
1452 .vidioc_g_input
= vidioc_g_input
,
1453 .vidioc_s_input
= vidioc_s_input
,
1454 .vidioc_queryctrl
= vidioc_queryctrl
,
1455 .vidioc_g_ctrl
= vidioc_g_ctrl
,
1456 .vidioc_s_ctrl
= vidioc_s_ctrl
,
1457 .vidioc_streamon
= vidioc_streamon
,
1458 .vidioc_streamoff
= vidioc_streamoff
,
1459 #ifdef CONFIG_VIDEO_V4L1_COMPAT
1460 .vidiocgmbuf
= vidiocgmbuf
,
1462 .vidioc_g_tuner
= vidioc_g_tuner
,
1463 .vidioc_s_tuner
= vidioc_s_tuner
,
1464 .vidioc_g_frequency
= vidioc_g_frequency
,
1465 .vidioc_s_frequency
= vidioc_s_frequency
,
1466 #ifdef CONFIG_VIDEO_ADV_DEBUG
1467 .vidioc_g_register
= vidioc_g_register
,
1468 .vidioc_s_register
= vidioc_s_register
,
1472 static struct video_device cx23885_vbi_template
;
1473 static struct video_device cx23885_video_template
= {
1474 .name
= "cx23885-video",
1475 .type
= VID_TYPE_CAPTURE
|VID_TYPE_TUNER
|VID_TYPE_SCALES
,
1476 .fops
= &video_fops
,
1478 .ioctl_ops
= &video_ioctl_ops
,
1479 .tvnorms
= CX23885_NORMS
,
1480 .current_norm
= V4L2_STD_NTSC_M
,
1483 static const struct file_operations radio_fops
= {
1484 .owner
= THIS_MODULE
,
1486 .release
= video_release
,
1487 .ioctl
= video_ioctl2
,
1488 .compat_ioctl
= v4l_compat_ioctl32
,
1489 .llseek
= no_llseek
,
1493 void cx23885_video_unregister(struct cx23885_dev
*dev
)
1495 dprintk(1, "%s()\n", __func__
);
1496 cx_clear(PCI_INT_MSK
, 1);
1498 if (dev
->video_dev
) {
1499 if (-1 != dev
->video_dev
->minor
)
1500 video_unregister_device(dev
->video_dev
);
1502 video_device_release(dev
->video_dev
);
1503 dev
->video_dev
= NULL
;
1505 btcx_riscmem_free(dev
->pci
, &dev
->vidq
.stopper
);
1509 int cx23885_video_register(struct cx23885_dev
*dev
)
1513 dprintk(1, "%s()\n", __func__
);
1514 spin_lock_init(&dev
->slock
);
1516 /* Initialize VBI template */
1517 memcpy(&cx23885_vbi_template
, &cx23885_video_template
,
1518 sizeof(cx23885_vbi_template
));
1519 strcpy(cx23885_vbi_template
.name
, "cx23885-vbi");
1520 cx23885_vbi_template
.type
= VID_TYPE_TELETEXT
|VID_TYPE_TUNER
;
1522 dev
->tvnorm
= cx23885_video_template
.current_norm
;
1524 /* init video dma queues */
1525 INIT_LIST_HEAD(&dev
->vidq
.active
);
1526 INIT_LIST_HEAD(&dev
->vidq
.queued
);
1527 dev
->vidq
.timeout
.function
= cx23885_vid_timeout
;
1528 dev
->vidq
.timeout
.data
= (unsigned long)dev
;
1529 init_timer(&dev
->vidq
.timeout
);
1530 cx23885_risc_stopper(dev
->pci
, &dev
->vidq
.stopper
,
1531 VID_A_DMA_CTL
, 0x11, 0x00);
1533 /* Don't enable VBI yet */
1534 cx_set(PCI_INT_MSK
, 1);
1537 /* register v4l devices */
1538 dev
->video_dev
= cx23885_vdev_init(dev
, dev
->pci
,
1539 &cx23885_video_template
, "video");
1540 err
= video_register_device(dev
->video_dev
, VFL_TYPE_GRABBER
,
1543 printk(KERN_INFO
"%s: can't register video device\n",
1547 printk(KERN_INFO
"%s/0: registered device video%d [v4l2]\n",
1548 dev
->name
, dev
->video_dev
->minor
& 0x1f);
1549 /* initial device configuration */
1550 mutex_lock(&dev
->lock
);
1551 cx23885_set_tvnorm(dev
, dev
->tvnorm
);
1553 cx23885_video_mux(dev
, 0);
1554 mutex_unlock(&dev
->lock
);
1559 cx23885_video_unregister(dev
);