2 * tw68 functions to handle video data
4 * Much of this code is derived from the cx88 and sa7134 drivers, which
5 * were in turn derived from the bt87x driver. The original work was by
6 * Gerd Knorr; more recently the code was enhanced by Mauro Carvalho Chehab,
7 * Hans Verkuil, Andy Walls and many others. Their work is gratefully
8 * acknowledged. Full credit goes to them - any problems within this code
11 * Copyright (C) 2009 William M. Brack
13 * Refactored and updated to the latest v4l core frameworks:
15 * Copyright (C) 2014 Hans Verkuil <hverkuil@xs4all.nl>
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
28 #include <linux/module.h>
29 #include <media/v4l2-common.h>
30 #include <media/v4l2-event.h>
31 #include <media/videobuf2-dma-sg.h>
36 /* ------------------------------------------------------------------ */
37 /* data structs for video */
40 * Note that the saa7134 has formats, e.g. YUV420, which are classified
41 * as "planar". These affect overlay mode, and are flagged with a field
42 * ".planar" in the format. Do we need to implement this in this driver?
44 static const struct tw68_format formats
[] = {
46 .name
= "15 bpp RGB, le",
47 .fourcc
= V4L2_PIX_FMT_RGB555
,
49 .twformat
= ColorFormatRGB15
,
51 .name
= "15 bpp RGB, be",
52 .fourcc
= V4L2_PIX_FMT_RGB555X
,
54 .twformat
= ColorFormatRGB15
| ColorFormatBSWAP
,
56 .name
= "16 bpp RGB, le",
57 .fourcc
= V4L2_PIX_FMT_RGB565
,
59 .twformat
= ColorFormatRGB16
,
61 .name
= "16 bpp RGB, be",
62 .fourcc
= V4L2_PIX_FMT_RGB565X
,
64 .twformat
= ColorFormatRGB16
| ColorFormatBSWAP
,
66 .name
= "24 bpp RGB, le",
67 .fourcc
= V4L2_PIX_FMT_BGR24
,
69 .twformat
= ColorFormatRGB24
,
71 .name
= "24 bpp RGB, be",
72 .fourcc
= V4L2_PIX_FMT_RGB24
,
74 .twformat
= ColorFormatRGB24
| ColorFormatBSWAP
,
76 .name
= "32 bpp RGB, le",
77 .fourcc
= V4L2_PIX_FMT_BGR32
,
79 .twformat
= ColorFormatRGB32
,
81 .name
= "32 bpp RGB, be",
82 .fourcc
= V4L2_PIX_FMT_RGB32
,
84 .twformat
= ColorFormatRGB32
| ColorFormatBSWAP
|
87 .name
= "4:2:2 packed, YUYV",
88 .fourcc
= V4L2_PIX_FMT_YUYV
,
90 .twformat
= ColorFormatYUY2
,
92 .name
= "4:2:2 packed, UYVY",
93 .fourcc
= V4L2_PIX_FMT_UYVY
,
95 .twformat
= ColorFormatYUY2
| ColorFormatBSWAP
,
98 #define FORMATS ARRAY_SIZE(formats)
100 #define NORM_625_50 \
106 .vbi_v_start_0 = 7, \
107 .vbi_v_stop_0 = 22, \
108 .video_v_start = 24, \
109 .video_v_stop = 311, \
112 #define NORM_525_60 \
118 .vbi_v_start_0 = 10, \
119 .vbi_v_stop_0 = 21, \
120 .video_v_start = 22, \
121 .video_v_stop = 262, \
125 * The following table is searched by tw68_s_std, first for a specific
126 * match, then for an entry which contains the desired id. The table
127 * entries should therefore be ordered in ascending order of specificity.
129 static const struct tw68_tvnorm tvnorms
[] = {
131 .name
= "PAL", /* autodetect */
135 .sync_control
= 0x18,
136 .luma_control
= 0x40,
137 .chroma_ctrl1
= 0x81,
139 .chroma_ctrl2
= 0x06,
141 .format
= VideoFormatPALBDGHI
,
147 .sync_control
= 0x59,
148 .luma_control
= 0x40,
149 .chroma_ctrl1
= 0x89,
151 .chroma_ctrl2
= 0x0e,
153 .format
= VideoFormatNTSC
,
156 .id
= V4L2_STD_SECAM
,
159 .sync_control
= 0x18,
160 .luma_control
= 0x1b,
161 .chroma_ctrl1
= 0xd1,
163 .chroma_ctrl2
= 0x00,
165 .format
= VideoFormatSECAM
,
168 .id
= V4L2_STD_PAL_M
,
171 .sync_control
= 0x59,
172 .luma_control
= 0x40,
173 .chroma_ctrl1
= 0xb9,
175 .chroma_ctrl2
= 0x0e,
177 .format
= VideoFormatPALM
,
180 .id
= V4L2_STD_PAL_Nc
,
183 .sync_control
= 0x18,
184 .luma_control
= 0x40,
185 .chroma_ctrl1
= 0xa1,
187 .chroma_ctrl2
= 0x06,
189 .format
= VideoFormatPALNC
,
192 .id
= V4L2_STD_PAL_60
,
201 .vbi_v_start_1
= 273,
203 .sync_control
= 0x18,
204 .luma_control
= 0x40,
205 .chroma_ctrl1
= 0x81,
207 .chroma_ctrl2
= 0x06,
209 .format
= VideoFormatPAL60
,
212 #define TVNORMS ARRAY_SIZE(tvnorms)
214 static const struct tw68_format
*format_by_fourcc(unsigned int fourcc
)
218 for (i
= 0; i
< FORMATS
; i
++)
219 if (formats
[i
].fourcc
== fourcc
)
225 /* ------------------------------------------------------------------ */
227 * Note that the cropping rectangles are described in terms of a single
228 * frame, i.e. line positions are only 1/2 the interlaced equivalent
230 static void set_tvnorm(struct tw68_dev
*dev
, const struct tw68_tvnorm
*norm
)
232 if (norm
!= dev
->tvnorm
) {
234 dev
->height
= (norm
->id
& V4L2_STD_525_60
) ? 480 : 576;
236 tw68_set_tvnorm_hw(dev
);
243 * Scaling and Cropping for video decoding
245 * We are working with 3 values for horizontal and vertical - scale,
248 * HACTIVE represent the actual number of pixels in the "usable" image,
249 * before scaling. HDELAY represents the number of pixels skipped
250 * between the start of the horizontal sync and the start of the image.
251 * HSCALE is calculated using the formula
252 * HSCALE = (HACTIVE / (#pixels desired)) * 256
254 * The vertical registers are similar, except based upon the total number
255 * of lines in the image, and the first line of the image (i.e. ignoring
256 * vertical sync and VBI).
258 * Note that the number of bytes reaching the FIFO (and hence needing
259 * to be processed by the DMAP program) is completely dependent upon
260 * these values, especially HSCALE.
263 * @dev pointer to the device structure, needed for
264 * getting current norm (as well as debug print)
265 * @width actual image width (from user buffer)
266 * @height actual image height
267 * @field indicates Top, Bottom or Interlaced
269 static int tw68_set_scale(struct tw68_dev
*dev
, unsigned int width
,
270 unsigned int height
, enum v4l2_field field
)
272 const struct tw68_tvnorm
*norm
= dev
->tvnorm
;
273 /* set individually for debugging clarity */
274 int hactive
, hdelay
, hscale
;
275 int vactive
, vdelay
, vscale
;
278 if (V4L2_FIELD_HAS_BOTH(field
)) /* if field is interlaced */
279 height
/= 2; /* we must set for 1-frame */
281 pr_debug("%s: width=%d, height=%d, both=%d\n"
282 " tvnorm h_delay=%d, h_start=%d, h_stop=%d, "
283 "v_delay=%d, v_start=%d, v_stop=%d\n" , __func__
,
284 width
, height
, V4L2_FIELD_HAS_BOTH(field
),
285 norm
->h_delay
, norm
->h_start
, norm
->h_stop
,
286 norm
->v_delay
, norm
->video_v_start
,
289 switch (dev
->vdecoder
) {
291 hdelay
= norm
->h_delay0
;
294 hdelay
= norm
->h_delay
;
298 hdelay
+= norm
->h_start
;
299 hactive
= norm
->h_stop
- norm
->h_start
+ 1;
301 hscale
= (hactive
* 256) / (width
);
303 vdelay
= norm
->v_delay
;
304 vactive
= ((norm
->id
& V4L2_STD_525_60
) ? 524 : 624) / 2 - norm
->video_v_start
;
305 vscale
= (vactive
* 256) / height
;
307 pr_debug("%s: %dx%d [%s%s,%s]\n", __func__
,
309 V4L2_FIELD_HAS_TOP(field
) ? "T" : "",
310 V4L2_FIELD_HAS_BOTTOM(field
) ? "B" : "",
311 v4l2_norm_to_name(dev
->tvnorm
->id
));
312 pr_debug("%s: hactive=%d, hdelay=%d, hscale=%d; "
313 "vactive=%d, vdelay=%d, vscale=%d\n", __func__
,
314 hactive
, hdelay
, hscale
, vactive
, vdelay
, vscale
);
316 comb
= ((vdelay
& 0x300) >> 2) |
317 ((vactive
& 0x300) >> 4) |
318 ((hdelay
& 0x300) >> 6) |
319 ((hactive
& 0x300) >> 8);
320 pr_debug("%s: setting CROP_HI=%02x, VDELAY_LO=%02x, "
321 "VACTIVE_LO=%02x, HDELAY_LO=%02x, HACTIVE_LO=%02x\n",
322 __func__
, comb
, vdelay
, vactive
, hdelay
, hactive
);
323 tw_writeb(TW68_CROP_HI
, comb
);
324 tw_writeb(TW68_VDELAY_LO
, vdelay
& 0xff);
325 tw_writeb(TW68_VACTIVE_LO
, vactive
& 0xff);
326 tw_writeb(TW68_HDELAY_LO
, hdelay
& 0xff);
327 tw_writeb(TW68_HACTIVE_LO
, hactive
& 0xff);
329 comb
= ((vscale
& 0xf00) >> 4) | ((hscale
& 0xf00) >> 8);
330 pr_debug("%s: setting SCALE_HI=%02x, VSCALE_LO=%02x, "
331 "HSCALE_LO=%02x\n", __func__
, comb
, vscale
, hscale
);
332 tw_writeb(TW68_SCALE_HI
, comb
);
333 tw_writeb(TW68_VSCALE_LO
, vscale
);
334 tw_writeb(TW68_HSCALE_LO
, hscale
);
339 /* ------------------------------------------------------------------ */
341 int tw68_video_start_dma(struct tw68_dev
*dev
, struct tw68_buf
*buf
)
343 /* Set cropping and scaling */
344 tw68_set_scale(dev
, dev
->width
, dev
->height
, dev
->field
);
346 * Set start address for RISC program. Note that if the DMAP
347 * processor is currently running, it must be stopped before
348 * a new address can be set.
350 tw_clearl(TW68_DMAC
, TW68_DMAP_EN
);
351 tw_writel(TW68_DMAP_SA
, buf
->dma
);
352 /* Clear any pending interrupts */
353 tw_writel(TW68_INTSTAT
, dev
->board_virqmask
);
354 /* Enable the risc engine and the fifo */
355 tw_andorl(TW68_DMAC
, 0xff, dev
->fmt
->twformat
|
356 ColorFormatGamma
| TW68_DMAP_EN
| TW68_FIFO_EN
);
357 dev
->pci_irqmask
|= dev
->board_virqmask
;
358 tw_setl(TW68_INTMASK
, dev
->pci_irqmask
);
362 /* ------------------------------------------------------------------ */
364 /* calc max # of buffers from size (must not exceed the 4MB virtual
365 * address space per DMA channel) */
366 static int tw68_buffer_count(unsigned int size
, unsigned int count
)
368 unsigned int maxcount
;
370 maxcount
= (4 * 1024 * 1024) / roundup(size
, PAGE_SIZE
);
371 if (count
> maxcount
)
376 /* ------------------------------------------------------------- */
377 /* vb2 queue operations */
379 static int tw68_queue_setup(struct vb2_queue
*q
,
380 unsigned int *num_buffers
, unsigned int *num_planes
,
381 unsigned int sizes
[], struct device
*alloc_devs
[])
383 struct tw68_dev
*dev
= vb2_get_drv_priv(q
);
384 unsigned tot_bufs
= q
->num_buffers
+ *num_buffers
;
385 unsigned size
= (dev
->fmt
->depth
* dev
->width
* dev
->height
) >> 3;
389 tot_bufs
= tw68_buffer_count(size
, tot_bufs
);
390 *num_buffers
= tot_bufs
- q
->num_buffers
;
392 * We allow create_bufs, but only if the sizeimage is >= as the
393 * current sizeimage. The tw68_buffer_count calculation becomes quite
394 * difficult otherwise.
397 return sizes
[0] < size
? -EINVAL
: 0;
405 * The risc program for each buffers works as follows: it starts with a simple
406 * 'JUMP to addr + 8', which is effectively a NOP. Then the program to DMA the
407 * buffer follows and at the end we have a JUMP back to the start + 8 (skipping
410 * This is the program of the first buffer to be queued if the active list is
411 * empty and it just keeps DMAing this buffer without generating any interrupts.
413 * If a new buffer is added then the initial JUMP in the program generates an
414 * interrupt as well which signals that the previous buffer has been DMAed
415 * successfully and that it can be returned to userspace.
417 * It also sets the final jump of the previous buffer to the start of the new
418 * buffer, thus chaining the new buffer into the DMA chain. This is a single
419 * atomic u32 write, so there is no race condition.
421 * The end-result of all this that you only get an interrupt when a buffer
422 * is ready, so the control flow is very easy.
424 static void tw68_buf_queue(struct vb2_buffer
*vb
)
426 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
427 struct vb2_queue
*vq
= vb
->vb2_queue
;
428 struct tw68_dev
*dev
= vb2_get_drv_priv(vq
);
429 struct tw68_buf
*buf
= container_of(vbuf
, struct tw68_buf
, vb
);
430 struct tw68_buf
*prev
;
433 spin_lock_irqsave(&dev
->slock
, flags
);
435 /* append a 'JUMP to start of buffer' to the buffer risc program */
436 buf
->jmp
[0] = cpu_to_le32(RISC_JUMP
);
437 buf
->jmp
[1] = cpu_to_le32(buf
->dma
+ 8);
439 if (!list_empty(&dev
->active
)) {
440 prev
= list_entry(dev
->active
.prev
, struct tw68_buf
, list
);
441 buf
->cpu
[0] |= cpu_to_le32(RISC_INT_BIT
);
442 prev
->jmp
[1] = cpu_to_le32(buf
->dma
);
444 list_add_tail(&buf
->list
, &dev
->active
);
445 spin_unlock_irqrestore(&dev
->slock
, flags
);
451 * Set the ancilliary information into the buffer structure. This
452 * includes generating the necessary risc program if it hasn't already
453 * been done for the current buffer format.
454 * The structure fh contains the details of the format requested by the
455 * user - type, width, height and #fields. This is compared with the
456 * last format set for the current buffer. If they differ, the risc
457 * code (which controls the filling of the buffer) is (re-)generated.
459 static int tw68_buf_prepare(struct vb2_buffer
*vb
)
461 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
462 struct vb2_queue
*vq
= vb
->vb2_queue
;
463 struct tw68_dev
*dev
= vb2_get_drv_priv(vq
);
464 struct tw68_buf
*buf
= container_of(vbuf
, struct tw68_buf
, vb
);
465 struct sg_table
*dma
= vb2_dma_sg_plane_desc(vb
, 0);
468 size
= (dev
->width
* dev
->height
* dev
->fmt
->depth
) >> 3;
469 if (vb2_plane_size(vb
, 0) < size
)
471 vb2_set_plane_payload(vb
, 0, size
);
473 bpl
= (dev
->width
* dev
->fmt
->depth
) >> 3;
474 switch (dev
->field
) {
476 tw68_risc_buffer(dev
->pci
, buf
, dma
->sgl
,
477 0, UNSET
, bpl
, 0, dev
->height
);
479 case V4L2_FIELD_BOTTOM
:
480 tw68_risc_buffer(dev
->pci
, buf
, dma
->sgl
,
481 UNSET
, 0, bpl
, 0, dev
->height
);
483 case V4L2_FIELD_SEQ_TB
:
484 tw68_risc_buffer(dev
->pci
, buf
, dma
->sgl
,
485 0, bpl
* (dev
->height
>> 1),
486 bpl
, 0, dev
->height
>> 1);
488 case V4L2_FIELD_SEQ_BT
:
489 tw68_risc_buffer(dev
->pci
, buf
, dma
->sgl
,
490 bpl
* (dev
->height
>> 1), 0,
491 bpl
, 0, dev
->height
>> 1);
493 case V4L2_FIELD_INTERLACED
:
495 tw68_risc_buffer(dev
->pci
, buf
, dma
->sgl
,
496 0, bpl
, bpl
, bpl
, dev
->height
>> 1);
502 static void tw68_buf_finish(struct vb2_buffer
*vb
)
504 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
505 struct vb2_queue
*vq
= vb
->vb2_queue
;
506 struct tw68_dev
*dev
= vb2_get_drv_priv(vq
);
507 struct tw68_buf
*buf
= container_of(vbuf
, struct tw68_buf
, vb
);
509 pci_free_consistent(dev
->pci
, buf
->size
, buf
->cpu
, buf
->dma
);
512 static int tw68_start_streaming(struct vb2_queue
*q
, unsigned int count
)
514 struct tw68_dev
*dev
= vb2_get_drv_priv(q
);
515 struct tw68_buf
*buf
=
516 container_of(dev
->active
.next
, struct tw68_buf
, list
);
519 tw68_video_start_dma(dev
, buf
);
523 static void tw68_stop_streaming(struct vb2_queue
*q
)
525 struct tw68_dev
*dev
= vb2_get_drv_priv(q
);
527 /* Stop risc & fifo */
528 tw_clearl(TW68_DMAC
, TW68_DMAP_EN
| TW68_FIFO_EN
);
529 while (!list_empty(&dev
->active
)) {
530 struct tw68_buf
*buf
=
531 container_of(dev
->active
.next
, struct tw68_buf
, list
);
533 list_del(&buf
->list
);
534 vb2_buffer_done(&buf
->vb
.vb2_buf
, VB2_BUF_STATE_ERROR
);
538 static struct vb2_ops tw68_video_qops
= {
539 .queue_setup
= tw68_queue_setup
,
540 .buf_queue
= tw68_buf_queue
,
541 .buf_prepare
= tw68_buf_prepare
,
542 .buf_finish
= tw68_buf_finish
,
543 .start_streaming
= tw68_start_streaming
,
544 .stop_streaming
= tw68_stop_streaming
,
545 .wait_prepare
= vb2_ops_wait_prepare
,
546 .wait_finish
= vb2_ops_wait_finish
,
549 /* ------------------------------------------------------------------ */
551 static int tw68_s_ctrl(struct v4l2_ctrl
*ctrl
)
553 struct tw68_dev
*dev
=
554 container_of(ctrl
->handler
, struct tw68_dev
, hdl
);
557 case V4L2_CID_BRIGHTNESS
:
558 tw_writeb(TW68_BRIGHT
, ctrl
->val
);
561 tw_writeb(TW68_HUE
, ctrl
->val
);
563 case V4L2_CID_CONTRAST
:
564 tw_writeb(TW68_CONTRAST
, ctrl
->val
);
566 case V4L2_CID_SATURATION
:
567 tw_writeb(TW68_SAT_U
, ctrl
->val
);
568 tw_writeb(TW68_SAT_V
, ctrl
->val
);
570 case V4L2_CID_COLOR_KILLER
:
572 tw_andorb(TW68_MISC2
, 0xe0, 0xe0);
574 tw_andorb(TW68_MISC2
, 0xe0, 0x00);
576 case V4L2_CID_CHROMA_AGC
:
578 tw_andorb(TW68_LOOP
, 0x30, 0x20);
580 tw_andorb(TW68_LOOP
, 0x30, 0x00);
586 /* ------------------------------------------------------------------ */
589 * Note that this routine returns what is stored in the fh structure, and
590 * does not interrogate any of the device registers.
592 static int tw68_g_fmt_vid_cap(struct file
*file
, void *priv
,
593 struct v4l2_format
*f
)
595 struct tw68_dev
*dev
= video_drvdata(file
);
597 f
->fmt
.pix
.width
= dev
->width
;
598 f
->fmt
.pix
.height
= dev
->height
;
599 f
->fmt
.pix
.field
= dev
->field
;
600 f
->fmt
.pix
.pixelformat
= dev
->fmt
->fourcc
;
601 f
->fmt
.pix
.bytesperline
=
602 (f
->fmt
.pix
.width
* (dev
->fmt
->depth
)) >> 3;
603 f
->fmt
.pix
.sizeimage
=
604 f
->fmt
.pix
.height
* f
->fmt
.pix
.bytesperline
;
605 f
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_SMPTE170M
;
610 static int tw68_try_fmt_vid_cap(struct file
*file
, void *priv
,
611 struct v4l2_format
*f
)
613 struct tw68_dev
*dev
= video_drvdata(file
);
614 const struct tw68_format
*fmt
;
615 enum v4l2_field field
;
618 fmt
= format_by_fourcc(f
->fmt
.pix
.pixelformat
);
622 field
= f
->fmt
.pix
.field
;
623 maxh
= (dev
->tvnorm
->id
& V4L2_STD_525_60
) ? 480 : 576;
627 case V4L2_FIELD_BOTTOM
:
629 case V4L2_FIELD_INTERLACED
:
630 case V4L2_FIELD_SEQ_BT
:
631 case V4L2_FIELD_SEQ_TB
:
635 field
= (f
->fmt
.pix
.height
> maxh
/ 2)
636 ? V4L2_FIELD_INTERLACED
641 f
->fmt
.pix
.field
= field
;
642 if (f
->fmt
.pix
.width
< 48)
643 f
->fmt
.pix
.width
= 48;
644 if (f
->fmt
.pix
.height
< 32)
645 f
->fmt
.pix
.height
= 32;
646 if (f
->fmt
.pix
.width
> 720)
647 f
->fmt
.pix
.width
= 720;
648 if (f
->fmt
.pix
.height
> maxh
)
649 f
->fmt
.pix
.height
= maxh
;
650 f
->fmt
.pix
.width
&= ~0x03;
651 f
->fmt
.pix
.bytesperline
=
652 (f
->fmt
.pix
.width
* (fmt
->depth
)) >> 3;
653 f
->fmt
.pix
.sizeimage
=
654 f
->fmt
.pix
.height
* f
->fmt
.pix
.bytesperline
;
655 f
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_SMPTE170M
;
660 * Note that tw68_s_fmt_vid_cap sets the information into the fh structure,
661 * and it will be used for all future new buffers. However, there could be
662 * some number of buffers on the "active" chain which will be filled before
663 * the change takes place.
665 static int tw68_s_fmt_vid_cap(struct file
*file
, void *priv
,
666 struct v4l2_format
*f
)
668 struct tw68_dev
*dev
= video_drvdata(file
);
671 err
= tw68_try_fmt_vid_cap(file
, priv
, f
);
675 dev
->fmt
= format_by_fourcc(f
->fmt
.pix
.pixelformat
);
676 dev
->width
= f
->fmt
.pix
.width
;
677 dev
->height
= f
->fmt
.pix
.height
;
678 dev
->field
= f
->fmt
.pix
.field
;
682 static int tw68_enum_input(struct file
*file
, void *priv
,
683 struct v4l2_input
*i
)
685 struct tw68_dev
*dev
= video_drvdata(file
);
689 if (n
>= TW68_INPUT_MAX
)
692 i
->type
= V4L2_INPUT_TYPE_CAMERA
;
693 snprintf(i
->name
, sizeof(i
->name
), "Composite %d", n
);
695 /* If the query is for the current input, get live data */
696 if (n
== dev
->input
) {
697 int v1
= tw_readb(TW68_STATUS1
);
698 int v2
= tw_readb(TW68_MVSN
);
700 if (0 != (v1
& (1 << 7)))
701 i
->status
|= V4L2_IN_ST_NO_SYNC
;
702 if (0 != (v1
& (1 << 6)))
703 i
->status
|= V4L2_IN_ST_NO_H_LOCK
;
704 if (0 != (v1
& (1 << 2)))
705 i
->status
|= V4L2_IN_ST_NO_SIGNAL
;
706 if (0 != (v1
& 1 << 1))
707 i
->status
|= V4L2_IN_ST_NO_COLOR
;
708 if (0 != (v2
& (1 << 2)))
709 i
->status
|= V4L2_IN_ST_MACROVISION
;
711 i
->std
= video_devdata(file
)->tvnorms
;
715 static int tw68_g_input(struct file
*file
, void *priv
, unsigned int *i
)
717 struct tw68_dev
*dev
= video_drvdata(file
);
723 static int tw68_s_input(struct file
*file
, void *priv
, unsigned int i
)
725 struct tw68_dev
*dev
= video_drvdata(file
);
727 if (i
>= TW68_INPUT_MAX
)
730 tw_andorb(TW68_INFORM
, 0x03 << 2, dev
->input
<< 2);
734 static int tw68_querycap(struct file
*file
, void *priv
,
735 struct v4l2_capability
*cap
)
737 struct tw68_dev
*dev
= video_drvdata(file
);
739 strcpy(cap
->driver
, "tw68");
740 strlcpy(cap
->card
, "Techwell Capture Card",
742 sprintf(cap
->bus_info
, "PCI:%s", pci_name(dev
->pci
));
744 V4L2_CAP_VIDEO_CAPTURE
|
748 cap
->capabilities
= cap
->device_caps
| V4L2_CAP_DEVICE_CAPS
;
752 static int tw68_s_std(struct file
*file
, void *priv
, v4l2_std_id id
)
754 struct tw68_dev
*dev
= video_drvdata(file
);
757 if (vb2_is_busy(&dev
->vidq
))
760 /* Look for match on complete norm id (may have mult bits) */
761 for (i
= 0; i
< TVNORMS
; i
++) {
762 if (id
== tvnorms
[i
].id
)
766 /* If no exact match, look for norm which contains this one */
768 for (i
= 0; i
< TVNORMS
; i
++)
769 if (id
& tvnorms
[i
].id
)
772 /* If still not matched, give up */
776 set_tvnorm(dev
, &tvnorms
[i
]); /* do the actual setting */
780 static int tw68_g_std(struct file
*file
, void *priv
, v4l2_std_id
*id
)
782 struct tw68_dev
*dev
= video_drvdata(file
);
784 *id
= dev
->tvnorm
->id
;
788 static int tw68_enum_fmt_vid_cap(struct file
*file
, void *priv
,
789 struct v4l2_fmtdesc
*f
)
791 if (f
->index
>= FORMATS
)
794 strlcpy(f
->description
, formats
[f
->index
].name
,
795 sizeof(f
->description
));
797 f
->pixelformat
= formats
[f
->index
].fourcc
;
803 * Used strictly for internal development and debugging, this routine
804 * prints out the current register contents for the tw68xx device.
806 static void tw68_dump_regs(struct tw68_dev
*dev
)
808 unsigned char line
[80];
812 pr_info("Full dump of TW68 registers:\n");
813 /* First we do the PCI regs, 8 4-byte regs per line */
814 for (i
= 0; i
< 0x100; i
+= 32) {
816 cptr
+= sprintf(cptr
, "%03x ", i
);
817 /* j steps through the next 4 words */
818 for (j
= i
; j
< i
+ 16; j
+= 4)
819 cptr
+= sprintf(cptr
, "%08x ", tw_readl(j
));
821 for (; j
< i
+ 32; j
+= 4)
822 cptr
+= sprintf(cptr
, "%08x ", tw_readl(j
));
827 /* Next the control regs, which are single-byte, address mod 4 */
830 cptr
+= sprintf(cptr
, "%03x ", i
);
831 /* Print out 4 groups of 4 bytes */
832 for (j
= 0; j
< 4; j
++) {
833 for (k
= 0; k
< 4; k
++) {
834 cptr
+= sprintf(cptr
, "%02x ",
846 static int vidioc_log_status(struct file
*file
, void *priv
)
848 struct tw68_dev
*dev
= video_drvdata(file
);
851 return v4l2_ctrl_log_status(file
, priv
);
854 #ifdef CONFIG_VIDEO_ADV_DEBUG
855 static int vidioc_g_register(struct file
*file
, void *priv
,
856 struct v4l2_dbg_register
*reg
)
858 struct tw68_dev
*dev
= video_drvdata(file
);
861 reg
->val
= tw_readb(reg
->reg
);
863 reg
->val
= tw_readl(reg
->reg
);
867 static int vidioc_s_register(struct file
*file
, void *priv
,
868 const struct v4l2_dbg_register
*reg
)
870 struct tw68_dev
*dev
= video_drvdata(file
);
873 tw_writeb(reg
->reg
, reg
->val
);
875 tw_writel(reg
->reg
& 0xffff, reg
->val
);
880 static const struct v4l2_ctrl_ops tw68_ctrl_ops
= {
881 .s_ctrl
= tw68_s_ctrl
,
884 static const struct v4l2_file_operations video_fops
= {
885 .owner
= THIS_MODULE
,
886 .open
= v4l2_fh_open
,
887 .release
= vb2_fop_release
,
888 .read
= vb2_fop_read
,
889 .poll
= vb2_fop_poll
,
890 .mmap
= vb2_fop_mmap
,
891 .unlocked_ioctl
= video_ioctl2
,
894 static const struct v4l2_ioctl_ops video_ioctl_ops
= {
895 .vidioc_querycap
= tw68_querycap
,
896 .vidioc_enum_fmt_vid_cap
= tw68_enum_fmt_vid_cap
,
897 .vidioc_reqbufs
= vb2_ioctl_reqbufs
,
898 .vidioc_create_bufs
= vb2_ioctl_create_bufs
,
899 .vidioc_querybuf
= vb2_ioctl_querybuf
,
900 .vidioc_qbuf
= vb2_ioctl_qbuf
,
901 .vidioc_dqbuf
= vb2_ioctl_dqbuf
,
902 .vidioc_s_std
= tw68_s_std
,
903 .vidioc_g_std
= tw68_g_std
,
904 .vidioc_enum_input
= tw68_enum_input
,
905 .vidioc_g_input
= tw68_g_input
,
906 .vidioc_s_input
= tw68_s_input
,
907 .vidioc_streamon
= vb2_ioctl_streamon
,
908 .vidioc_streamoff
= vb2_ioctl_streamoff
,
909 .vidioc_g_fmt_vid_cap
= tw68_g_fmt_vid_cap
,
910 .vidioc_try_fmt_vid_cap
= tw68_try_fmt_vid_cap
,
911 .vidioc_s_fmt_vid_cap
= tw68_s_fmt_vid_cap
,
912 .vidioc_log_status
= vidioc_log_status
,
913 .vidioc_subscribe_event
= v4l2_ctrl_subscribe_event
,
914 .vidioc_unsubscribe_event
= v4l2_event_unsubscribe
,
915 #ifdef CONFIG_VIDEO_ADV_DEBUG
916 .vidioc_g_register
= vidioc_g_register
,
917 .vidioc_s_register
= vidioc_s_register
,
921 static struct video_device tw68_video_template
= {
922 .name
= "tw68_video",
924 .ioctl_ops
= &video_ioctl_ops
,
925 .release
= video_device_release_empty
,
926 .tvnorms
= TW68_NORMS
,
929 /* ------------------------------------------------------------------ */
931 void tw68_set_tvnorm_hw(struct tw68_dev
*dev
)
933 tw_andorb(TW68_SDT
, 0x07, dev
->tvnorm
->format
);
936 int tw68_video_init1(struct tw68_dev
*dev
)
938 struct v4l2_ctrl_handler
*hdl
= &dev
->hdl
;
940 v4l2_ctrl_handler_init(hdl
, 6);
941 v4l2_ctrl_new_std(hdl
, &tw68_ctrl_ops
,
942 V4L2_CID_BRIGHTNESS
, -128, 127, 1, 20);
943 v4l2_ctrl_new_std(hdl
, &tw68_ctrl_ops
,
944 V4L2_CID_CONTRAST
, 0, 255, 1, 100);
945 v4l2_ctrl_new_std(hdl
, &tw68_ctrl_ops
,
946 V4L2_CID_SATURATION
, 0, 255, 1, 128);
948 v4l2_ctrl_new_std(hdl
, &tw68_ctrl_ops
,
949 V4L2_CID_HUE
, -128, 127, 1, 0);
950 v4l2_ctrl_new_std(hdl
, &tw68_ctrl_ops
,
951 V4L2_CID_COLOR_KILLER
, 0, 1, 1, 0);
952 v4l2_ctrl_new_std(hdl
, &tw68_ctrl_ops
,
953 V4L2_CID_CHROMA_AGC
, 0, 1, 1, 1);
955 v4l2_ctrl_handler_free(hdl
);
958 dev
->v4l2_dev
.ctrl_handler
= hdl
;
959 v4l2_ctrl_handler_setup(hdl
);
963 int tw68_video_init2(struct tw68_dev
*dev
, int video_nr
)
967 set_tvnorm(dev
, &tvnorms
[0]);
969 dev
->fmt
= format_by_fourcc(V4L2_PIX_FMT_BGR24
);
972 dev
->field
= V4L2_FIELD_INTERLACED
;
974 INIT_LIST_HEAD(&dev
->active
);
975 dev
->vidq
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
976 dev
->vidq
.timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC
;
977 dev
->vidq
.io_modes
= VB2_MMAP
| VB2_USERPTR
| VB2_READ
| VB2_DMABUF
;
978 dev
->vidq
.ops
= &tw68_video_qops
;
979 dev
->vidq
.mem_ops
= &vb2_dma_sg_memops
;
980 dev
->vidq
.drv_priv
= dev
;
981 dev
->vidq
.gfp_flags
= __GFP_DMA32
| __GFP_KSWAPD_RECLAIM
;
982 dev
->vidq
.buf_struct_size
= sizeof(struct tw68_buf
);
983 dev
->vidq
.lock
= &dev
->lock
;
984 dev
->vidq
.min_buffers_needed
= 2;
985 dev
->vidq
.dev
= &dev
->pci
->dev
;
986 ret
= vb2_queue_init(&dev
->vidq
);
989 dev
->vdev
= tw68_video_template
;
990 dev
->vdev
.v4l2_dev
= &dev
->v4l2_dev
;
991 dev
->vdev
.lock
= &dev
->lock
;
992 dev
->vdev
.queue
= &dev
->vidq
;
993 video_set_drvdata(&dev
->vdev
, dev
);
994 return video_register_device(&dev
->vdev
, VFL_TYPE_GRABBER
, video_nr
);
998 * tw68_irq_video_done
1000 void tw68_irq_video_done(struct tw68_dev
*dev
, unsigned long status
)
1004 /* reset interrupts handled by this routine */
1005 tw_writel(TW68_INTSTAT
, status
);
1007 * Check most likely first
1009 * DMAPI shows we have reached the end of the risc code
1010 * for the current buffer.
1012 if (status
& TW68_DMAPI
) {
1013 struct tw68_buf
*buf
;
1015 spin_lock(&dev
->slock
);
1016 buf
= list_entry(dev
->active
.next
, struct tw68_buf
, list
);
1017 list_del(&buf
->list
);
1018 spin_unlock(&dev
->slock
);
1019 buf
->vb
.vb2_buf
.timestamp
= ktime_get_ns();
1020 buf
->vb
.field
= dev
->field
;
1021 buf
->vb
.sequence
= dev
->seqnr
++;
1022 vb2_buffer_done(&buf
->vb
.vb2_buf
, VB2_BUF_STATE_DONE
);
1023 status
&= ~(TW68_DMAPI
);
1027 if (status
& (TW68_VLOCK
| TW68_HLOCK
))
1028 dev_dbg(&dev
->pci
->dev
, "Lost sync\n");
1029 if (status
& TW68_PABORT
)
1030 dev_err(&dev
->pci
->dev
, "PABORT interrupt\n");
1031 if (status
& TW68_DMAPERR
)
1032 dev_err(&dev
->pci
->dev
, "DMAPERR interrupt\n");
1034 * On TW6800, FDMIS is apparently generated if video input is switched
1035 * during operation. Therefore, it is not enabled for that chip.
1037 if (status
& TW68_FDMIS
)
1038 dev_dbg(&dev
->pci
->dev
, "FDMIS interrupt\n");
1039 if (status
& TW68_FFOF
) {
1040 /* probably a logic error */
1041 reg
= tw_readl(TW68_DMAC
) & TW68_FIFO_EN
;
1042 tw_clearl(TW68_DMAC
, TW68_FIFO_EN
);
1043 dev_dbg(&dev
->pci
->dev
, "FFOF interrupt\n");
1044 tw_setl(TW68_DMAC
, reg
);
1046 if (status
& TW68_FFERR
)
1047 dev_dbg(&dev
->pci
->dev
, "FFERR interrupt\n");