2 * Driver for the Conexant CX25821 PCIe bridge
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 * Parts adapted/taken from Eduardo Moscoso Rubino
8 * Copyright (C) 2009 Eduardo Moscoso Rubino <moscoso@TopoLogica.com>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
29 #include "cx25821-video.h"
31 MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
32 MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
33 MODULE_LICENSE("GPL");
35 static unsigned int video_nr
[] = {[0 ... (CX25821_MAXBOARDS
- 1)] = UNSET
};
37 module_param_array(video_nr
, int, NULL
, 0444);
39 MODULE_PARM_DESC(video_nr
, "video device numbers");
41 static unsigned int video_debug
= VIDEO_DEBUG
;
42 module_param(video_debug
, int, 0644);
43 MODULE_PARM_DESC(video_debug
, "enable debug messages [video]");
45 static unsigned int irq_debug
;
46 module_param(irq_debug
, int, 0644);
47 MODULE_PARM_DESC(irq_debug
, "enable debug messages [IRQ handler]");
49 static unsigned int vid_limit
= 16;
50 module_param(vid_limit
, int, 0644);
51 MODULE_PARM_DESC(vid_limit
, "capture memory limit in megabytes");
53 #define FORMAT_FLAGS_PACKED 0x01
55 static const struct cx25821_fmt formats
[] = {
57 .name
= "4:1:1, packed, Y41P",
58 .fourcc
= V4L2_PIX_FMT_Y41P
,
60 .flags
= FORMAT_FLAGS_PACKED
,
62 .name
= "4:2:2, packed, YUYV",
63 .fourcc
= V4L2_PIX_FMT_YUYV
,
65 .flags
= FORMAT_FLAGS_PACKED
,
69 static const struct cx25821_fmt
*cx25821_format_by_fourcc(unsigned int fourcc
)
73 for (i
= 0; i
< ARRAY_SIZE(formats
); i
++)
74 if (formats
[i
].fourcc
== fourcc
)
79 void cx25821_video_wakeup(struct cx25821_dev
*dev
, struct cx25821_dmaqueue
*q
,
82 struct cx25821_buffer
*buf
;
86 if (list_empty(&q
->active
)) {
87 dprintk(1, "bc=%d (=0: active empty)\n", bc
);
91 buf
= list_entry(q
->active
.next
, struct cx25821_buffer
,
94 /* count comes from the hw and it is 16bit wide --
95 * this trick handles wrap-arounds correctly for
96 * up to 32767 buffers in flight... */
97 if ((s16
) (count
- buf
->count
) < 0)
100 v4l2_get_timestamp(&buf
->vb
.ts
);
101 buf
->vb
.state
= VIDEOBUF_DONE
;
102 list_del(&buf
->vb
.queue
);
103 wake_up(&buf
->vb
.done
);
106 if (list_empty(&q
->active
))
107 del_timer(&q
->timeout
);
109 mod_timer(&q
->timeout
, jiffies
+ BUFFER_TIMEOUT
);
111 pr_err("%s: %d buffers handled (should be 1)\n", __func__
, bc
);
114 int cx25821_start_video_dma(struct cx25821_dev
*dev
,
115 struct cx25821_dmaqueue
*q
,
116 struct cx25821_buffer
*buf
,
117 const struct sram_channel
*channel
)
121 /* setup fifo + format */
122 cx25821_sram_channel_setup(dev
, channel
, buf
->bpl
, buf
->risc
.dma
);
125 cx_write(channel
->gpcnt_ctl
, 3);
129 cx_set(PCI_INT_MSK
, cx_read(PCI_INT_MSK
) | (1 << channel
->i
));
130 cx_set(channel
->int_msk
, 0x11);
133 cx_write(channel
->dma_ctl
, 0x11); /* FIFO and RISC enable */
135 /* make sure upstream setting if any is reversed */
136 tmp
= cx_read(VID_CH_MODE_SEL
);
137 cx_write(VID_CH_MODE_SEL
, tmp
& 0xFFFFFE00);
142 static int cx25821_restart_video_queue(struct cx25821_dev
*dev
,
143 struct cx25821_dmaqueue
*q
,
144 const struct sram_channel
*channel
)
146 struct cx25821_buffer
*buf
, *prev
;
147 struct list_head
*item
;
149 if (!list_empty(&q
->active
)) {
150 buf
= list_entry(q
->active
.next
, struct cx25821_buffer
,
153 cx25821_start_video_dma(dev
, q
, buf
, channel
);
155 list_for_each(item
, &q
->active
) {
156 buf
= list_entry(item
, struct cx25821_buffer
, vb
.queue
);
157 buf
->count
= q
->count
++;
160 mod_timer(&q
->timeout
, jiffies
+ BUFFER_TIMEOUT
);
166 if (list_empty(&q
->queued
))
169 buf
= list_entry(q
->queued
.next
, struct cx25821_buffer
,
173 list_move_tail(&buf
->vb
.queue
, &q
->active
);
174 cx25821_start_video_dma(dev
, q
, buf
, channel
);
175 buf
->vb
.state
= VIDEOBUF_ACTIVE
;
176 buf
->count
= q
->count
++;
177 mod_timer(&q
->timeout
, jiffies
+ BUFFER_TIMEOUT
);
178 } else if (prev
->vb
.width
== buf
->vb
.width
&&
179 prev
->vb
.height
== buf
->vb
.height
&&
180 prev
->fmt
== buf
->fmt
) {
181 list_move_tail(&buf
->vb
.queue
, &q
->active
);
182 buf
->vb
.state
= VIDEOBUF_ACTIVE
;
183 buf
->count
= q
->count
++;
184 prev
->risc
.jmp
[1] = cpu_to_le32(buf
->risc
.dma
);
185 prev
->risc
.jmp
[2] = cpu_to_le32(0); /* Bits 63 - 32 */
193 static void cx25821_vid_timeout(unsigned long data
)
195 struct cx25821_data
*timeout_data
= (struct cx25821_data
*)data
;
196 struct cx25821_dev
*dev
= timeout_data
->dev
;
197 const struct sram_channel
*channel
= timeout_data
->channel
;
198 struct cx25821_dmaqueue
*q
= &dev
->channels
[channel
->i
].dma_vidq
;
199 struct cx25821_buffer
*buf
;
202 /* cx25821_sram_channel_dump(dev, channel); */
203 cx_clear(channel
->dma_ctl
, 0x11);
205 spin_lock_irqsave(&dev
->slock
, flags
);
206 while (!list_empty(&q
->active
)) {
207 buf
= list_entry(q
->active
.next
, struct cx25821_buffer
,
209 list_del(&buf
->vb
.queue
);
211 buf
->vb
.state
= VIDEOBUF_ERROR
;
212 wake_up(&buf
->vb
.done
);
215 cx25821_restart_video_queue(dev
, q
, channel
);
216 spin_unlock_irqrestore(&dev
->slock
, flags
);
219 int cx25821_video_irq(struct cx25821_dev
*dev
, int chan_num
, u32 status
)
224 const struct sram_channel
*channel
= dev
->channels
[chan_num
].sram_channels
;
226 mask
= cx_read(channel
->int_msk
);
227 if (0 == (status
& mask
))
230 cx_write(channel
->int_stat
, status
);
232 /* risc op code error */
233 if (status
& (1 << 16)) {
234 pr_warn("%s, %s: video risc op code error\n",
235 dev
->name
, channel
->name
);
236 cx_clear(channel
->dma_ctl
, 0x11);
237 cx25821_sram_channel_dump(dev
, channel
);
241 if (status
& FLD_VID_DST_RISC1
) {
242 spin_lock(&dev
->slock
);
243 count
= cx_read(channel
->gpcnt
);
244 cx25821_video_wakeup(dev
, &dev
->channels
[channel
->i
].dma_vidq
,
246 spin_unlock(&dev
->slock
);
252 dprintk(2, "stopper video\n");
253 spin_lock(&dev
->slock
);
254 cx25821_restart_video_queue(dev
,
255 &dev
->channels
[channel
->i
].dma_vidq
, channel
);
256 spin_unlock(&dev
->slock
);
262 static int cx25821_buffer_setup(struct videobuf_queue
*q
, unsigned int *count
,
265 struct cx25821_channel
*chan
= q
->priv_data
;
267 *size
= chan
->fmt
->depth
* chan
->width
* chan
->height
>> 3;
272 if (*size
* *count
> vid_limit
* 1024 * 1024)
273 *count
= (vid_limit
* 1024 * 1024) / *size
;
278 static int cx25821_buffer_prepare(struct videobuf_queue
*q
, struct videobuf_buffer
*vb
,
279 enum v4l2_field field
)
281 struct cx25821_channel
*chan
= q
->priv_data
;
282 struct cx25821_dev
*dev
= chan
->dev
;
283 struct cx25821_buffer
*buf
=
284 container_of(vb
, struct cx25821_buffer
, vb
);
285 int rc
, init_buffer
= 0;
287 struct videobuf_dmabuf
*dma
= videobuf_to_dma(&buf
->vb
);
288 int bpl_local
= LINE_SIZE_D1
;
290 BUG_ON(NULL
== chan
->fmt
);
291 if (chan
->width
< 48 || chan
->width
> 720 ||
292 chan
->height
< 32 || chan
->height
> 576)
295 buf
->vb
.size
= (chan
->width
* chan
->height
* chan
->fmt
->depth
) >> 3;
297 if (0 != buf
->vb
.baddr
&& buf
->vb
.bsize
< buf
->vb
.size
)
300 if (buf
->fmt
!= chan
->fmt
||
301 buf
->vb
.width
!= chan
->width
||
302 buf
->vb
.height
!= chan
->height
|| buf
->vb
.field
!= field
) {
303 buf
->fmt
= chan
->fmt
;
304 buf
->vb
.width
= chan
->width
;
305 buf
->vb
.height
= chan
->height
;
306 buf
->vb
.field
= field
;
310 if (VIDEOBUF_NEEDS_INIT
== buf
->vb
.state
) {
312 rc
= videobuf_iolock(q
, &buf
->vb
, NULL
);
314 printk(KERN_DEBUG
pr_fmt("videobuf_iolock failed!\n"));
319 dprintk(1, "init_buffer=%d\n", init_buffer
);
322 if (chan
->pixel_formats
== PIXEL_FRMT_411
)
323 buf
->bpl
= (buf
->fmt
->depth
* buf
->vb
.width
) >> 3;
325 buf
->bpl
= (buf
->fmt
->depth
>> 3) * (buf
->vb
.width
);
327 if (chan
->pixel_formats
== PIXEL_FRMT_411
) {
328 bpl_local
= buf
->bpl
;
330 bpl_local
= buf
->bpl
; /* Default */
332 if (chan
->use_cif_resolution
) {
333 if (dev
->tvnorm
& V4L2_STD_625_50
)
334 bpl_local
= 352 << 1;
336 bpl_local
= chan
->cif_width
<< 1;
340 switch (buf
->vb
.field
) {
342 cx25821_risc_buffer(dev
->pci
, &buf
->risc
,
343 dma
->sglist
, 0, UNSET
,
344 buf
->bpl
, 0, buf
->vb
.height
);
346 case V4L2_FIELD_BOTTOM
:
347 cx25821_risc_buffer(dev
->pci
, &buf
->risc
,
348 dma
->sglist
, UNSET
, 0,
349 buf
->bpl
, 0, buf
->vb
.height
);
351 case V4L2_FIELD_INTERLACED
:
352 /* All other formats are top field first */
354 dprintk(1, "top field first\n");
356 cx25821_risc_buffer(dev
->pci
, &buf
->risc
,
357 dma
->sglist
, line0_offset
,
358 bpl_local
, bpl_local
, bpl_local
,
359 buf
->vb
.height
>> 1);
361 case V4L2_FIELD_SEQ_TB
:
362 cx25821_risc_buffer(dev
->pci
, &buf
->risc
,
364 0, buf
->bpl
* (buf
->vb
.height
>> 1),
365 buf
->bpl
, 0, buf
->vb
.height
>> 1);
367 case V4L2_FIELD_SEQ_BT
:
368 cx25821_risc_buffer(dev
->pci
, &buf
->risc
,
370 buf
->bpl
* (buf
->vb
.height
>> 1), 0,
371 buf
->bpl
, 0, buf
->vb
.height
>> 1);
378 dprintk(2, "[%p/%d] buffer_prep - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
379 buf
, buf
->vb
.i
, chan
->width
, chan
->height
, chan
->fmt
->depth
,
380 chan
->fmt
->name
, (unsigned long)buf
->risc
.dma
);
382 buf
->vb
.state
= VIDEOBUF_PREPARED
;
387 cx25821_free_buffer(q
, buf
);
391 static void cx25821_buffer_release(struct videobuf_queue
*q
,
392 struct videobuf_buffer
*vb
)
394 struct cx25821_buffer
*buf
=
395 container_of(vb
, struct cx25821_buffer
, vb
);
397 cx25821_free_buffer(q
, buf
);
400 static int cx25821_video_mmap(struct file
*file
, struct vm_area_struct
*vma
)
402 struct cx25821_channel
*chan
= video_drvdata(file
);
404 return videobuf_mmap_mapper(&chan
->vidq
, vma
);
408 static void buffer_queue(struct videobuf_queue
*vq
, struct videobuf_buffer
*vb
)
410 struct cx25821_buffer
*buf
=
411 container_of(vb
, struct cx25821_buffer
, vb
);
412 struct cx25821_buffer
*prev
;
413 struct cx25821_channel
*chan
= vq
->priv_data
;
414 struct cx25821_dev
*dev
= chan
->dev
;
415 struct cx25821_dmaqueue
*q
= &dev
->channels
[chan
->id
].dma_vidq
;
417 /* add jump to stopper */
418 buf
->risc
.jmp
[0] = cpu_to_le32(RISC_JUMP
| RISC_IRQ1
| RISC_CNT_INC
);
419 buf
->risc
.jmp
[1] = cpu_to_le32(q
->stopper
.dma
);
420 buf
->risc
.jmp
[2] = cpu_to_le32(0); /* bits 63-32 */
422 dprintk(2, "jmp to stopper (0x%x)\n", buf
->risc
.jmp
[1]);
424 if (!list_empty(&q
->queued
)) {
425 list_add_tail(&buf
->vb
.queue
, &q
->queued
);
426 buf
->vb
.state
= VIDEOBUF_QUEUED
;
427 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf
,
430 } else if (list_empty(&q
->active
)) {
431 list_add_tail(&buf
->vb
.queue
, &q
->active
);
432 cx25821_start_video_dma(dev
, q
, buf
, chan
->sram_channels
);
433 buf
->vb
.state
= VIDEOBUF_ACTIVE
;
434 buf
->count
= q
->count
++;
435 mod_timer(&q
->timeout
, jiffies
+ BUFFER_TIMEOUT
);
436 dprintk(2, "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
437 buf
, buf
->vb
.i
, buf
->count
, q
->count
);
439 prev
= list_entry(q
->active
.prev
, struct cx25821_buffer
,
441 if (prev
->vb
.width
== buf
->vb
.width
442 && prev
->vb
.height
== buf
->vb
.height
443 && prev
->fmt
== buf
->fmt
) {
444 list_add_tail(&buf
->vb
.queue
, &q
->active
);
445 buf
->vb
.state
= VIDEOBUF_ACTIVE
;
446 buf
->count
= q
->count
++;
447 prev
->risc
.jmp
[1] = cpu_to_le32(buf
->risc
.dma
);
449 /* 64 bit bits 63-32 */
450 prev
->risc
.jmp
[2] = cpu_to_le32(0);
451 dprintk(2, "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
452 buf
, buf
->vb
.i
, buf
->count
);
455 list_add_tail(&buf
->vb
.queue
, &q
->queued
);
456 buf
->vb
.state
= VIDEOBUF_QUEUED
;
457 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf
,
462 if (list_empty(&q
->active
))
463 dprintk(2, "active queue empty!\n");
466 static struct videobuf_queue_ops cx25821_video_qops
= {
467 .buf_setup
= cx25821_buffer_setup
,
468 .buf_prepare
= cx25821_buffer_prepare
,
469 .buf_queue
= buffer_queue
,
470 .buf_release
= cx25821_buffer_release
,
473 static ssize_t
video_read(struct file
*file
, char __user
* data
, size_t count
,
476 struct v4l2_fh
*fh
= file
->private_data
;
477 struct cx25821_channel
*chan
= video_drvdata(file
);
478 struct cx25821_dev
*dev
= chan
->dev
;
481 if (mutex_lock_interruptible(&dev
->lock
))
483 if (chan
->streaming_fh
&& chan
->streaming_fh
!= fh
) {
487 chan
->streaming_fh
= fh
;
489 err
= videobuf_read_one(&chan
->vidq
, data
, count
, ppos
,
490 file
->f_flags
& O_NONBLOCK
);
492 mutex_unlock(&dev
->lock
);
496 static unsigned int video_poll(struct file
*file
,
497 struct poll_table_struct
*wait
)
499 struct cx25821_channel
*chan
= video_drvdata(file
);
500 unsigned long req_events
= poll_requested_events(wait
);
501 unsigned int res
= v4l2_ctrl_poll(file
, wait
);
503 if (req_events
& (POLLIN
| POLLRDNORM
))
504 res
|= videobuf_poll_stream(file
, &chan
->vidq
, wait
);
507 /* This doesn't belong in poll(). This can be done
508 * much better with vb2. We keep this code here as a
510 if ((res & POLLIN) && buf->vb.state == VIDEOBUF_DONE) {
511 struct cx25821_dev *dev = chan->dev;
513 if (dev && chan->use_cif_resolution) {
514 u8 cam_id = *((char *)buf->vb.baddr + 3);
515 memcpy((char *)buf->vb.baddr,
516 (char *)buf->vb.baddr + (chan->width * 2),
518 *((char *)buf->vb.baddr + 3) = cam_id;
524 static int video_release(struct file
*file
)
526 struct cx25821_channel
*chan
= video_drvdata(file
);
527 struct v4l2_fh
*fh
= file
->private_data
;
528 struct cx25821_dev
*dev
= chan
->dev
;
529 const struct sram_channel
*sram_ch
=
530 dev
->channels
[0].sram_channels
;
532 mutex_lock(&dev
->lock
);
533 /* stop the risc engine and fifo */
534 cx_write(sram_ch
->dma_ctl
, 0); /* FIFO and RISC disable */
536 /* stop video capture */
537 if (chan
->streaming_fh
== fh
) {
538 videobuf_queue_cancel(&chan
->vidq
);
539 chan
->streaming_fh
= NULL
;
542 if (chan
->vidq
.read_buf
) {
543 cx25821_buffer_release(&chan
->vidq
, chan
->vidq
.read_buf
);
544 kfree(chan
->vidq
.read_buf
);
547 videobuf_mmap_free(&chan
->vidq
);
548 mutex_unlock(&dev
->lock
);
550 return v4l2_fh_release(file
);
555 static int cx25821_vidioc_enum_fmt_vid_cap(struct file
*file
, void *priv
,
556 struct v4l2_fmtdesc
*f
)
558 if (unlikely(f
->index
>= ARRAY_SIZE(formats
)))
561 strlcpy(f
->description
, formats
[f
->index
].name
, sizeof(f
->description
));
562 f
->pixelformat
= formats
[f
->index
].fourcc
;
567 static int cx25821_vidioc_g_fmt_vid_cap(struct file
*file
, void *priv
,
568 struct v4l2_format
*f
)
570 struct cx25821_channel
*chan
= video_drvdata(file
);
572 f
->fmt
.pix
.width
= chan
->width
;
573 f
->fmt
.pix
.height
= chan
->height
;
574 f
->fmt
.pix
.field
= chan
->vidq
.field
;
575 f
->fmt
.pix
.pixelformat
= chan
->fmt
->fourcc
;
576 f
->fmt
.pix
.bytesperline
= (chan
->width
* chan
->fmt
->depth
) >> 3;
577 f
->fmt
.pix
.sizeimage
= chan
->height
* f
->fmt
.pix
.bytesperline
;
578 f
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_SMPTE170M
;
584 static int cx25821_vidioc_try_fmt_vid_cap(struct file
*file
, void *priv
,
585 struct v4l2_format
*f
)
587 struct cx25821_channel
*chan
= video_drvdata(file
);
588 struct cx25821_dev
*dev
= chan
->dev
;
589 const struct cx25821_fmt
*fmt
;
590 enum v4l2_field field
= f
->fmt
.pix
.field
;
594 fmt
= cx25821_format_by_fourcc(f
->fmt
.pix
.pixelformat
);
597 maxh
= (dev
->tvnorm
& V4L2_STD_625_50
) ? 576 : 480;
599 w
= f
->fmt
.pix
.width
;
600 if (field
!= V4L2_FIELD_BOTTOM
)
601 field
= V4L2_FIELD_TOP
;
604 f
->fmt
.pix
.height
= maxh
/ 4;
605 } else if (w
< 720) {
607 f
->fmt
.pix
.height
= maxh
/ 2;
610 f
->fmt
.pix
.height
= maxh
;
611 field
= V4L2_FIELD_INTERLACED
;
613 f
->fmt
.pix
.field
= field
;
614 f
->fmt
.pix
.width
= w
;
615 f
->fmt
.pix
.bytesperline
= (f
->fmt
.pix
.width
* fmt
->depth
) >> 3;
616 f
->fmt
.pix
.sizeimage
= f
->fmt
.pix
.height
* f
->fmt
.pix
.bytesperline
;
617 f
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_SMPTE170M
;
623 static int vidioc_s_fmt_vid_cap(struct file
*file
, void *priv
,
624 struct v4l2_format
*f
)
626 struct cx25821_channel
*chan
= video_drvdata(file
);
627 struct cx25821_dev
*dev
= chan
->dev
;
628 int pix_format
= PIXEL_FRMT_422
;
631 err
= cx25821_vidioc_try_fmt_vid_cap(file
, priv
, f
);
636 chan
->fmt
= cx25821_format_by_fourcc(f
->fmt
.pix
.pixelformat
);
637 chan
->vidq
.field
= f
->fmt
.pix
.field
;
638 chan
->width
= f
->fmt
.pix
.width
;
639 chan
->height
= f
->fmt
.pix
.height
;
641 if (f
->fmt
.pix
.pixelformat
== V4L2_PIX_FMT_Y41P
)
642 pix_format
= PIXEL_FRMT_411
;
644 pix_format
= PIXEL_FRMT_422
;
646 cx25821_set_pixel_format(dev
, SRAM_CH00
, pix_format
);
648 /* check if cif resolution */
649 if (chan
->width
== 320 || chan
->width
== 352)
650 chan
->use_cif_resolution
= 1;
652 chan
->use_cif_resolution
= 0;
654 chan
->cif_width
= chan
->width
;
655 medusa_set_resolution(dev
, chan
->width
, SRAM_CH00
);
659 static int vidioc_streamon(struct file
*file
, void *priv
, enum v4l2_buf_type i
)
661 struct cx25821_channel
*chan
= video_drvdata(file
);
663 if (i
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
666 if (chan
->streaming_fh
&& chan
->streaming_fh
!= priv
)
668 chan
->streaming_fh
= priv
;
670 return videobuf_streamon(&chan
->vidq
);
673 static int vidioc_streamoff(struct file
*file
, void *priv
, enum v4l2_buf_type i
)
675 struct cx25821_channel
*chan
= video_drvdata(file
);
677 if (i
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
680 if (chan
->streaming_fh
&& chan
->streaming_fh
!= priv
)
682 if (chan
->streaming_fh
== NULL
)
685 chan
->streaming_fh
= NULL
;
686 return videobuf_streamoff(&chan
->vidq
);
689 static int vidioc_dqbuf(struct file
*file
, void *priv
, struct v4l2_buffer
*p
)
692 struct cx25821_channel
*chan
= video_drvdata(file
);
694 ret_val
= videobuf_dqbuf(&chan
->vidq
, p
, file
->f_flags
& O_NONBLOCK
);
695 p
->sequence
= chan
->dma_vidq
.count
;
700 static int vidioc_log_status(struct file
*file
, void *priv
)
702 struct cx25821_channel
*chan
= video_drvdata(file
);
703 struct cx25821_dev
*dev
= chan
->dev
;
704 const struct sram_channel
*sram_ch
= chan
->sram_channels
;
707 tmp
= cx_read(sram_ch
->dma_ctl
);
708 pr_info("Video input 0 is %s\n",
709 (tmp
& 0x11) ? "streaming" : "stopped");
714 static int cx25821_vidioc_querycap(struct file
*file
, void *priv
,
715 struct v4l2_capability
*cap
)
717 struct cx25821_channel
*chan
= video_drvdata(file
);
718 struct cx25821_dev
*dev
= chan
->dev
;
719 const u32 cap_input
= V4L2_CAP_VIDEO_CAPTURE
|
720 V4L2_CAP_READWRITE
| V4L2_CAP_STREAMING
;
721 const u32 cap_output
= V4L2_CAP_VIDEO_OUTPUT
| V4L2_CAP_READWRITE
;
723 strcpy(cap
->driver
, "cx25821");
724 strlcpy(cap
->card
, cx25821_boards
[dev
->board
].name
, sizeof(cap
->card
));
725 sprintf(cap
->bus_info
, "PCIe:%s", pci_name(dev
->pci
));
726 if (chan
->id
>= VID_CHANNEL_NUM
)
727 cap
->device_caps
= cap_output
;
729 cap
->device_caps
= cap_input
;
730 cap
->capabilities
= cap_input
| cap_output
| V4L2_CAP_DEVICE_CAPS
;
734 static int cx25821_vidioc_reqbufs(struct file
*file
, void *priv
,
735 struct v4l2_requestbuffers
*p
)
737 struct cx25821_channel
*chan
= video_drvdata(file
);
739 return videobuf_reqbufs(&chan
->vidq
, p
);
742 static int cx25821_vidioc_querybuf(struct file
*file
, void *priv
,
743 struct v4l2_buffer
*p
)
745 struct cx25821_channel
*chan
= video_drvdata(file
);
747 return videobuf_querybuf(&chan
->vidq
, p
);
750 static int cx25821_vidioc_qbuf(struct file
*file
, void *priv
, struct v4l2_buffer
*p
)
752 struct cx25821_channel
*chan
= video_drvdata(file
);
754 return videobuf_qbuf(&chan
->vidq
, p
);
757 static int cx25821_vidioc_g_std(struct file
*file
, void *priv
, v4l2_std_id
*tvnorms
)
759 struct cx25821_channel
*chan
= video_drvdata(file
);
761 *tvnorms
= chan
->dev
->tvnorm
;
765 static int cx25821_vidioc_s_std(struct file
*file
, void *priv
,
768 struct cx25821_channel
*chan
= video_drvdata(file
);
769 struct cx25821_dev
*dev
= chan
->dev
;
771 if (dev
->tvnorm
== tvnorms
)
774 dev
->tvnorm
= tvnorms
;
776 chan
->height
= (dev
->tvnorm
& V4L2_STD_625_50
) ? 576 : 480;
778 medusa_set_videostandard(dev
);
783 static int cx25821_vidioc_enum_input(struct file
*file
, void *priv
,
784 struct v4l2_input
*i
)
789 i
->type
= V4L2_INPUT_TYPE_CAMERA
;
790 i
->std
= CX25821_NORMS
;
791 strcpy(i
->name
, "Composite");
795 static int cx25821_vidioc_g_input(struct file
*file
, void *priv
, unsigned int *i
)
801 static int cx25821_vidioc_s_input(struct file
*file
, void *priv
, unsigned int i
)
803 return i
? -EINVAL
: 0;
806 static int cx25821_s_ctrl(struct v4l2_ctrl
*ctrl
)
808 struct cx25821_channel
*chan
=
809 container_of(ctrl
->handler
, struct cx25821_channel
, hdl
);
810 struct cx25821_dev
*dev
= chan
->dev
;
813 case V4L2_CID_BRIGHTNESS
:
814 medusa_set_brightness(dev
, ctrl
->val
, chan
->id
);
817 medusa_set_hue(dev
, ctrl
->val
, chan
->id
);
819 case V4L2_CID_CONTRAST
:
820 medusa_set_contrast(dev
, ctrl
->val
, chan
->id
);
822 case V4L2_CID_SATURATION
:
823 medusa_set_saturation(dev
, ctrl
->val
, chan
->id
);
831 static int cx25821_vidioc_enum_output(struct file
*file
, void *priv
,
832 struct v4l2_output
*o
)
837 o
->type
= V4L2_INPUT_TYPE_CAMERA
;
838 o
->std
= CX25821_NORMS
;
839 strcpy(o
->name
, "Composite");
843 static int cx25821_vidioc_g_output(struct file
*file
, void *priv
, unsigned int *o
)
849 static int cx25821_vidioc_s_output(struct file
*file
, void *priv
, unsigned int o
)
851 return o
? -EINVAL
: 0;
854 static int cx25821_vidioc_try_fmt_vid_out(struct file
*file
, void *priv
,
855 struct v4l2_format
*f
)
857 struct cx25821_channel
*chan
= video_drvdata(file
);
858 struct cx25821_dev
*dev
= chan
->dev
;
859 const struct cx25821_fmt
*fmt
;
861 fmt
= cx25821_format_by_fourcc(f
->fmt
.pix
.pixelformat
);
864 f
->fmt
.pix
.width
= 720;
865 f
->fmt
.pix
.height
= (dev
->tvnorm
& V4L2_STD_625_50
) ? 576 : 480;
866 f
->fmt
.pix
.field
= V4L2_FIELD_INTERLACED
;
867 f
->fmt
.pix
.bytesperline
= (f
->fmt
.pix
.width
* fmt
->depth
) >> 3;
868 f
->fmt
.pix
.sizeimage
= f
->fmt
.pix
.height
* f
->fmt
.pix
.bytesperline
;
869 f
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_SMPTE170M
;
874 static int vidioc_s_fmt_vid_out(struct file
*file
, void *priv
,
875 struct v4l2_format
*f
)
877 struct cx25821_channel
*chan
= video_drvdata(file
);
880 err
= cx25821_vidioc_try_fmt_vid_out(file
, priv
, f
);
885 chan
->fmt
= cx25821_format_by_fourcc(f
->fmt
.pix
.pixelformat
);
886 chan
->vidq
.field
= f
->fmt
.pix
.field
;
887 chan
->width
= f
->fmt
.pix
.width
;
888 chan
->height
= f
->fmt
.pix
.height
;
889 if (f
->fmt
.pix
.pixelformat
== V4L2_PIX_FMT_Y41P
)
890 chan
->pixel_formats
= PIXEL_FRMT_411
;
892 chan
->pixel_formats
= PIXEL_FRMT_422
;
896 static ssize_t
video_write(struct file
*file
, const char __user
*data
, size_t count
,
899 struct cx25821_channel
*chan
= video_drvdata(file
);
900 struct cx25821_dev
*dev
= chan
->dev
;
901 struct v4l2_fh
*fh
= file
->private_data
;
904 if (mutex_lock_interruptible(&dev
->lock
))
906 if (chan
->streaming_fh
&& chan
->streaming_fh
!= fh
) {
910 if (!chan
->streaming_fh
) {
911 err
= cx25821_vidupstream_init(chan
, chan
->pixel_formats
);
914 chan
->streaming_fh
= fh
;
917 err
= cx25821_write_frame(chan
, data
, count
);
922 mutex_unlock(&dev
->lock
);
926 static int video_out_release(struct file
*file
)
928 struct cx25821_channel
*chan
= video_drvdata(file
);
929 struct cx25821_dev
*dev
= chan
->dev
;
930 struct v4l2_fh
*fh
= file
->private_data
;
932 mutex_lock(&dev
->lock
);
933 if (chan
->streaming_fh
== fh
) {
934 cx25821_stop_upstream_video(chan
);
935 chan
->streaming_fh
= NULL
;
937 mutex_unlock(&dev
->lock
);
939 return v4l2_fh_release(file
);
942 static const struct v4l2_ctrl_ops cx25821_ctrl_ops
= {
943 .s_ctrl
= cx25821_s_ctrl
,
946 static const struct v4l2_file_operations video_fops
= {
947 .owner
= THIS_MODULE
,
948 .open
= v4l2_fh_open
,
949 .release
= video_release
,
952 .mmap
= cx25821_video_mmap
,
953 .unlocked_ioctl
= video_ioctl2
,
956 static const struct v4l2_ioctl_ops video_ioctl_ops
= {
957 .vidioc_querycap
= cx25821_vidioc_querycap
,
958 .vidioc_enum_fmt_vid_cap
= cx25821_vidioc_enum_fmt_vid_cap
,
959 .vidioc_g_fmt_vid_cap
= cx25821_vidioc_g_fmt_vid_cap
,
960 .vidioc_try_fmt_vid_cap
= cx25821_vidioc_try_fmt_vid_cap
,
961 .vidioc_s_fmt_vid_cap
= vidioc_s_fmt_vid_cap
,
962 .vidioc_reqbufs
= cx25821_vidioc_reqbufs
,
963 .vidioc_querybuf
= cx25821_vidioc_querybuf
,
964 .vidioc_qbuf
= cx25821_vidioc_qbuf
,
965 .vidioc_dqbuf
= vidioc_dqbuf
,
966 .vidioc_g_std
= cx25821_vidioc_g_std
,
967 .vidioc_s_std
= cx25821_vidioc_s_std
,
968 .vidioc_enum_input
= cx25821_vidioc_enum_input
,
969 .vidioc_g_input
= cx25821_vidioc_g_input
,
970 .vidioc_s_input
= cx25821_vidioc_s_input
,
971 .vidioc_streamon
= vidioc_streamon
,
972 .vidioc_streamoff
= vidioc_streamoff
,
973 .vidioc_log_status
= vidioc_log_status
,
974 .vidioc_subscribe_event
= v4l2_ctrl_subscribe_event
,
975 .vidioc_unsubscribe_event
= v4l2_event_unsubscribe
,
978 static const struct video_device cx25821_video_device
= {
979 .name
= "cx25821-video",
981 .release
= video_device_release_empty
,
983 .ioctl_ops
= &video_ioctl_ops
,
984 .tvnorms
= CX25821_NORMS
,
987 static const struct v4l2_file_operations video_out_fops
= {
988 .owner
= THIS_MODULE
,
989 .open
= v4l2_fh_open
,
990 .write
= video_write
,
991 .release
= video_out_release
,
992 .unlocked_ioctl
= video_ioctl2
,
995 static const struct v4l2_ioctl_ops video_out_ioctl_ops
= {
996 .vidioc_querycap
= cx25821_vidioc_querycap
,
997 .vidioc_enum_fmt_vid_out
= cx25821_vidioc_enum_fmt_vid_cap
,
998 .vidioc_g_fmt_vid_out
= cx25821_vidioc_g_fmt_vid_cap
,
999 .vidioc_try_fmt_vid_out
= cx25821_vidioc_try_fmt_vid_out
,
1000 .vidioc_s_fmt_vid_out
= vidioc_s_fmt_vid_out
,
1001 .vidioc_g_std
= cx25821_vidioc_g_std
,
1002 .vidioc_s_std
= cx25821_vidioc_s_std
,
1003 .vidioc_enum_output
= cx25821_vidioc_enum_output
,
1004 .vidioc_g_output
= cx25821_vidioc_g_output
,
1005 .vidioc_s_output
= cx25821_vidioc_s_output
,
1006 .vidioc_log_status
= vidioc_log_status
,
1009 static const struct video_device cx25821_video_out_device
= {
1010 .name
= "cx25821-video",
1011 .fops
= &video_out_fops
,
1012 .release
= video_device_release_empty
,
1014 .ioctl_ops
= &video_out_ioctl_ops
,
1015 .tvnorms
= CX25821_NORMS
,
1018 void cx25821_video_unregister(struct cx25821_dev
*dev
, int chan_num
)
1020 cx_clear(PCI_INT_MSK
, 1);
1022 if (video_is_registered(&dev
->channels
[chan_num
].vdev
)) {
1023 video_unregister_device(&dev
->channels
[chan_num
].vdev
);
1024 v4l2_ctrl_handler_free(&dev
->channels
[chan_num
].hdl
);
1026 btcx_riscmem_free(dev
->pci
,
1027 &dev
->channels
[chan_num
].dma_vidq
.stopper
);
1031 int cx25821_video_register(struct cx25821_dev
*dev
)
1036 /* initial device configuration */
1037 dev
->tvnorm
= V4L2_STD_NTSC_M
;
1039 spin_lock_init(&dev
->slock
);
1041 for (i
= 0; i
< MAX_VID_CHANNEL_NUM
- 1; ++i
) {
1042 struct cx25821_channel
*chan
= &dev
->channels
[i
];
1043 struct video_device
*vdev
= &chan
->vdev
;
1044 struct v4l2_ctrl_handler
*hdl
= &chan
->hdl
;
1045 bool is_output
= i
> SRAM_CH08
;
1047 if (i
== SRAM_CH08
) /* audio channel */
1051 v4l2_ctrl_handler_init(hdl
, 4);
1052 v4l2_ctrl_new_std(hdl
, &cx25821_ctrl_ops
,
1053 V4L2_CID_BRIGHTNESS
, 0, 10000, 1, 6200);
1054 v4l2_ctrl_new_std(hdl
, &cx25821_ctrl_ops
,
1055 V4L2_CID_CONTRAST
, 0, 10000, 1, 5000);
1056 v4l2_ctrl_new_std(hdl
, &cx25821_ctrl_ops
,
1057 V4L2_CID_SATURATION
, 0, 10000, 1, 5000);
1058 v4l2_ctrl_new_std(hdl
, &cx25821_ctrl_ops
,
1059 V4L2_CID_HUE
, 0, 10000, 1, 5000);
1064 err
= v4l2_ctrl_handler_setup(hdl
);
1068 chan
->out
= &dev
->vid_out_data
[i
- SRAM_CH09
];
1069 chan
->out
->chan
= chan
;
1072 cx25821_risc_stopper(dev
->pci
, &chan
->dma_vidq
.stopper
,
1073 chan
->sram_channels
->dma_ctl
, 0x11, 0);
1075 chan
->sram_channels
= &cx25821_sram_channels
[i
];
1077 if (dev
->tvnorm
& V4L2_STD_625_50
)
1082 if (chan
->pixel_formats
== PIXEL_FRMT_411
)
1083 chan
->fmt
= cx25821_format_by_fourcc(V4L2_PIX_FMT_Y41P
);
1085 chan
->fmt
= cx25821_format_by_fourcc(V4L2_PIX_FMT_YUYV
);
1087 cx_write(chan
->sram_channels
->int_stat
, 0xffffffff);
1089 INIT_LIST_HEAD(&chan
->dma_vidq
.active
);
1090 INIT_LIST_HEAD(&chan
->dma_vidq
.queued
);
1092 chan
->timeout_data
.dev
= dev
;
1093 chan
->timeout_data
.channel
= &cx25821_sram_channels
[i
];
1094 chan
->dma_vidq
.timeout
.function
= cx25821_vid_timeout
;
1095 chan
->dma_vidq
.timeout
.data
= (unsigned long)&chan
->timeout_data
;
1096 init_timer(&chan
->dma_vidq
.timeout
);
1099 videobuf_queue_sg_init(&chan
->vidq
, &cx25821_video_qops
, &dev
->pci
->dev
,
1100 &dev
->slock
, V4L2_BUF_TYPE_VIDEO_CAPTURE
,
1101 V4L2_FIELD_INTERLACED
, sizeof(struct cx25821_buffer
),
1104 /* register v4l devices */
1105 *vdev
= is_output
? cx25821_video_out_device
: cx25821_video_device
;
1106 vdev
->v4l2_dev
= &dev
->v4l2_dev
;
1108 vdev
->ctrl_handler
= hdl
;
1110 vdev
->vfl_dir
= VFL_DIR_TX
;
1111 vdev
->lock
= &dev
->lock
;
1112 set_bit(V4L2_FL_USE_FH_PRIO
, &vdev
->flags
);
1113 snprintf(vdev
->name
, sizeof(vdev
->name
), "%s #%d", dev
->name
, i
);
1114 video_set_drvdata(vdev
, chan
);
1116 err
= video_register_device(vdev
, VFL_TYPE_GRABBER
,
1123 /* set PCI interrupt */
1124 cx_set(PCI_INT_MSK
, 0xff);
1130 cx25821_video_unregister(dev
, i
--);