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
[], void *alloc_ctxs
[])
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
;
391 alloc_ctxs
[0] = dev
->alloc_ctx
;
393 * We allow create_bufs, but only if the sizeimage is >= as the
394 * current sizeimage. The tw68_buffer_count calculation becomes quite
395 * difficult otherwise.
398 return sizes
[0] < size
? -EINVAL
: 0;
406 * The risc program for each buffers works as follows: it starts with a simple
407 * 'JUMP to addr + 8', which is effectively a NOP. Then the program to DMA the
408 * buffer follows and at the end we have a JUMP back to the start + 8 (skipping
411 * This is the program of the first buffer to be queued if the active list is
412 * empty and it just keeps DMAing this buffer without generating any interrupts.
414 * If a new buffer is added then the initial JUMP in the program generates an
415 * interrupt as well which signals that the previous buffer has been DMAed
416 * successfully and that it can be returned to userspace.
418 * It also sets the final jump of the previous buffer to the start of the new
419 * buffer, thus chaining the new buffer into the DMA chain. This is a single
420 * atomic u32 write, so there is no race condition.
422 * The end-result of all this that you only get an interrupt when a buffer
423 * is ready, so the control flow is very easy.
425 static void tw68_buf_queue(struct vb2_buffer
*vb
)
427 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
428 struct vb2_queue
*vq
= vb
->vb2_queue
;
429 struct tw68_dev
*dev
= vb2_get_drv_priv(vq
);
430 struct tw68_buf
*buf
= container_of(vbuf
, struct tw68_buf
, vb
);
431 struct tw68_buf
*prev
;
434 spin_lock_irqsave(&dev
->slock
, flags
);
436 /* append a 'JUMP to start of buffer' to the buffer risc program */
437 buf
->jmp
[0] = cpu_to_le32(RISC_JUMP
);
438 buf
->jmp
[1] = cpu_to_le32(buf
->dma
+ 8);
440 if (!list_empty(&dev
->active
)) {
441 prev
= list_entry(dev
->active
.prev
, struct tw68_buf
, list
);
442 buf
->cpu
[0] |= cpu_to_le32(RISC_INT_BIT
);
443 prev
->jmp
[1] = cpu_to_le32(buf
->dma
);
445 list_add_tail(&buf
->list
, &dev
->active
);
446 spin_unlock_irqrestore(&dev
->slock
, flags
);
452 * Set the ancilliary information into the buffer structure. This
453 * includes generating the necessary risc program if it hasn't already
454 * been done for the current buffer format.
455 * The structure fh contains the details of the format requested by the
456 * user - type, width, height and #fields. This is compared with the
457 * last format set for the current buffer. If they differ, the risc
458 * code (which controls the filling of the buffer) is (re-)generated.
460 static int tw68_buf_prepare(struct vb2_buffer
*vb
)
462 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
463 struct vb2_queue
*vq
= vb
->vb2_queue
;
464 struct tw68_dev
*dev
= vb2_get_drv_priv(vq
);
465 struct tw68_buf
*buf
= container_of(vbuf
, struct tw68_buf
, vb
);
466 struct sg_table
*dma
= vb2_dma_sg_plane_desc(vb
, 0);
469 size
= (dev
->width
* dev
->height
* dev
->fmt
->depth
) >> 3;
470 if (vb2_plane_size(vb
, 0) < size
)
472 vb2_set_plane_payload(vb
, 0, size
);
474 bpl
= (dev
->width
* dev
->fmt
->depth
) >> 3;
475 switch (dev
->field
) {
477 tw68_risc_buffer(dev
->pci
, buf
, dma
->sgl
,
478 0, UNSET
, bpl
, 0, dev
->height
);
480 case V4L2_FIELD_BOTTOM
:
481 tw68_risc_buffer(dev
->pci
, buf
, dma
->sgl
,
482 UNSET
, 0, bpl
, 0, dev
->height
);
484 case V4L2_FIELD_SEQ_TB
:
485 tw68_risc_buffer(dev
->pci
, buf
, dma
->sgl
,
486 0, bpl
* (dev
->height
>> 1),
487 bpl
, 0, dev
->height
>> 1);
489 case V4L2_FIELD_SEQ_BT
:
490 tw68_risc_buffer(dev
->pci
, buf
, dma
->sgl
,
491 bpl
* (dev
->height
>> 1), 0,
492 bpl
, 0, dev
->height
>> 1);
494 case V4L2_FIELD_INTERLACED
:
496 tw68_risc_buffer(dev
->pci
, buf
, dma
->sgl
,
497 0, bpl
, bpl
, bpl
, dev
->height
>> 1);
503 static void tw68_buf_finish(struct vb2_buffer
*vb
)
505 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
506 struct vb2_queue
*vq
= vb
->vb2_queue
;
507 struct tw68_dev
*dev
= vb2_get_drv_priv(vq
);
508 struct tw68_buf
*buf
= container_of(vbuf
, struct tw68_buf
, vb
);
510 pci_free_consistent(dev
->pci
, buf
->size
, buf
->cpu
, buf
->dma
);
513 static int tw68_start_streaming(struct vb2_queue
*q
, unsigned int count
)
515 struct tw68_dev
*dev
= vb2_get_drv_priv(q
);
516 struct tw68_buf
*buf
=
517 container_of(dev
->active
.next
, struct tw68_buf
, list
);
520 tw68_video_start_dma(dev
, buf
);
524 static void tw68_stop_streaming(struct vb2_queue
*q
)
526 struct tw68_dev
*dev
= vb2_get_drv_priv(q
);
528 /* Stop risc & fifo */
529 tw_clearl(TW68_DMAC
, TW68_DMAP_EN
| TW68_FIFO_EN
);
530 while (!list_empty(&dev
->active
)) {
531 struct tw68_buf
*buf
=
532 container_of(dev
->active
.next
, struct tw68_buf
, list
);
534 list_del(&buf
->list
);
535 vb2_buffer_done(&buf
->vb
.vb2_buf
, VB2_BUF_STATE_ERROR
);
539 static struct vb2_ops tw68_video_qops
= {
540 .queue_setup
= tw68_queue_setup
,
541 .buf_queue
= tw68_buf_queue
,
542 .buf_prepare
= tw68_buf_prepare
,
543 .buf_finish
= tw68_buf_finish
,
544 .start_streaming
= tw68_start_streaming
,
545 .stop_streaming
= tw68_stop_streaming
,
546 .wait_prepare
= vb2_ops_wait_prepare
,
547 .wait_finish
= vb2_ops_wait_finish
,
550 /* ------------------------------------------------------------------ */
552 static int tw68_s_ctrl(struct v4l2_ctrl
*ctrl
)
554 struct tw68_dev
*dev
=
555 container_of(ctrl
->handler
, struct tw68_dev
, hdl
);
558 case V4L2_CID_BRIGHTNESS
:
559 tw_writeb(TW68_BRIGHT
, ctrl
->val
);
562 tw_writeb(TW68_HUE
, ctrl
->val
);
564 case V4L2_CID_CONTRAST
:
565 tw_writeb(TW68_CONTRAST
, ctrl
->val
);
567 case V4L2_CID_SATURATION
:
568 tw_writeb(TW68_SAT_U
, ctrl
->val
);
569 tw_writeb(TW68_SAT_V
, ctrl
->val
);
571 case V4L2_CID_COLOR_KILLER
:
573 tw_andorb(TW68_MISC2
, 0xe0, 0xe0);
575 tw_andorb(TW68_MISC2
, 0xe0, 0x00);
577 case V4L2_CID_CHROMA_AGC
:
579 tw_andorb(TW68_LOOP
, 0x30, 0x20);
581 tw_andorb(TW68_LOOP
, 0x30, 0x00);
587 /* ------------------------------------------------------------------ */
590 * Note that this routine returns what is stored in the fh structure, and
591 * does not interrogate any of the device registers.
593 static int tw68_g_fmt_vid_cap(struct file
*file
, void *priv
,
594 struct v4l2_format
*f
)
596 struct tw68_dev
*dev
= video_drvdata(file
);
598 f
->fmt
.pix
.width
= dev
->width
;
599 f
->fmt
.pix
.height
= dev
->height
;
600 f
->fmt
.pix
.field
= dev
->field
;
601 f
->fmt
.pix
.pixelformat
= dev
->fmt
->fourcc
;
602 f
->fmt
.pix
.bytesperline
=
603 (f
->fmt
.pix
.width
* (dev
->fmt
->depth
)) >> 3;
604 f
->fmt
.pix
.sizeimage
=
605 f
->fmt
.pix
.height
* f
->fmt
.pix
.bytesperline
;
606 f
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_SMPTE170M
;
611 static int tw68_try_fmt_vid_cap(struct file
*file
, void *priv
,
612 struct v4l2_format
*f
)
614 struct tw68_dev
*dev
= video_drvdata(file
);
615 const struct tw68_format
*fmt
;
616 enum v4l2_field field
;
619 fmt
= format_by_fourcc(f
->fmt
.pix
.pixelformat
);
623 field
= f
->fmt
.pix
.field
;
624 maxh
= (dev
->tvnorm
->id
& V4L2_STD_525_60
) ? 480 : 576;
628 case V4L2_FIELD_BOTTOM
:
630 case V4L2_FIELD_INTERLACED
:
631 case V4L2_FIELD_SEQ_BT
:
632 case V4L2_FIELD_SEQ_TB
:
636 field
= (f
->fmt
.pix
.height
> maxh
/ 2)
637 ? V4L2_FIELD_INTERLACED
642 f
->fmt
.pix
.field
= field
;
643 if (f
->fmt
.pix
.width
< 48)
644 f
->fmt
.pix
.width
= 48;
645 if (f
->fmt
.pix
.height
< 32)
646 f
->fmt
.pix
.height
= 32;
647 if (f
->fmt
.pix
.width
> 720)
648 f
->fmt
.pix
.width
= 720;
649 if (f
->fmt
.pix
.height
> maxh
)
650 f
->fmt
.pix
.height
= maxh
;
651 f
->fmt
.pix
.width
&= ~0x03;
652 f
->fmt
.pix
.bytesperline
=
653 (f
->fmt
.pix
.width
* (fmt
->depth
)) >> 3;
654 f
->fmt
.pix
.sizeimage
=
655 f
->fmt
.pix
.height
* f
->fmt
.pix
.bytesperline
;
656 f
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_SMPTE170M
;
661 * Note that tw68_s_fmt_vid_cap sets the information into the fh structure,
662 * and it will be used for all future new buffers. However, there could be
663 * some number of buffers on the "active" chain which will be filled before
664 * the change takes place.
666 static int tw68_s_fmt_vid_cap(struct file
*file
, void *priv
,
667 struct v4l2_format
*f
)
669 struct tw68_dev
*dev
= video_drvdata(file
);
672 err
= tw68_try_fmt_vid_cap(file
, priv
, f
);
676 dev
->fmt
= format_by_fourcc(f
->fmt
.pix
.pixelformat
);
677 dev
->width
= f
->fmt
.pix
.width
;
678 dev
->height
= f
->fmt
.pix
.height
;
679 dev
->field
= f
->fmt
.pix
.field
;
683 static int tw68_enum_input(struct file
*file
, void *priv
,
684 struct v4l2_input
*i
)
686 struct tw68_dev
*dev
= video_drvdata(file
);
690 if (n
>= TW68_INPUT_MAX
)
693 i
->type
= V4L2_INPUT_TYPE_CAMERA
;
694 snprintf(i
->name
, sizeof(i
->name
), "Composite %d", n
);
696 /* If the query is for the current input, get live data */
697 if (n
== dev
->input
) {
698 int v1
= tw_readb(TW68_STATUS1
);
699 int v2
= tw_readb(TW68_MVSN
);
701 if (0 != (v1
& (1 << 7)))
702 i
->status
|= V4L2_IN_ST_NO_SYNC
;
703 if (0 != (v1
& (1 << 6)))
704 i
->status
|= V4L2_IN_ST_NO_H_LOCK
;
705 if (0 != (v1
& (1 << 2)))
706 i
->status
|= V4L2_IN_ST_NO_SIGNAL
;
707 if (0 != (v1
& 1 << 1))
708 i
->status
|= V4L2_IN_ST_NO_COLOR
;
709 if (0 != (v2
& (1 << 2)))
710 i
->status
|= V4L2_IN_ST_MACROVISION
;
712 i
->std
= video_devdata(file
)->tvnorms
;
716 static int tw68_g_input(struct file
*file
, void *priv
, unsigned int *i
)
718 struct tw68_dev
*dev
= video_drvdata(file
);
724 static int tw68_s_input(struct file
*file
, void *priv
, unsigned int i
)
726 struct tw68_dev
*dev
= video_drvdata(file
);
728 if (i
>= TW68_INPUT_MAX
)
731 tw_andorb(TW68_INFORM
, 0x03 << 2, dev
->input
<< 2);
735 static int tw68_querycap(struct file
*file
, void *priv
,
736 struct v4l2_capability
*cap
)
738 struct tw68_dev
*dev
= video_drvdata(file
);
740 strcpy(cap
->driver
, "tw68");
741 strlcpy(cap
->card
, "Techwell Capture Card",
743 sprintf(cap
->bus_info
, "PCI:%s", pci_name(dev
->pci
));
745 V4L2_CAP_VIDEO_CAPTURE
|
749 cap
->capabilities
= cap
->device_caps
| V4L2_CAP_DEVICE_CAPS
;
753 static int tw68_s_std(struct file
*file
, void *priv
, v4l2_std_id id
)
755 struct tw68_dev
*dev
= video_drvdata(file
);
758 if (vb2_is_busy(&dev
->vidq
))
761 /* Look for match on complete norm id (may have mult bits) */
762 for (i
= 0; i
< TVNORMS
; i
++) {
763 if (id
== tvnorms
[i
].id
)
767 /* If no exact match, look for norm which contains this one */
769 for (i
= 0; i
< TVNORMS
; i
++)
770 if (id
& tvnorms
[i
].id
)
773 /* If still not matched, give up */
777 set_tvnorm(dev
, &tvnorms
[i
]); /* do the actual setting */
781 static int tw68_g_std(struct file
*file
, void *priv
, v4l2_std_id
*id
)
783 struct tw68_dev
*dev
= video_drvdata(file
);
785 *id
= dev
->tvnorm
->id
;
789 static int tw68_enum_fmt_vid_cap(struct file
*file
, void *priv
,
790 struct v4l2_fmtdesc
*f
)
792 if (f
->index
>= FORMATS
)
795 strlcpy(f
->description
, formats
[f
->index
].name
,
796 sizeof(f
->description
));
798 f
->pixelformat
= formats
[f
->index
].fourcc
;
804 * Used strictly for internal development and debugging, this routine
805 * prints out the current register contents for the tw68xx device.
807 static void tw68_dump_regs(struct tw68_dev
*dev
)
809 unsigned char line
[80];
813 pr_info("Full dump of TW68 registers:\n");
814 /* First we do the PCI regs, 8 4-byte regs per line */
815 for (i
= 0; i
< 0x100; i
+= 32) {
817 cptr
+= sprintf(cptr
, "%03x ", i
);
818 /* j steps through the next 4 words */
819 for (j
= i
; j
< i
+ 16; j
+= 4)
820 cptr
+= sprintf(cptr
, "%08x ", tw_readl(j
));
822 for (; j
< i
+ 32; j
+= 4)
823 cptr
+= sprintf(cptr
, "%08x ", tw_readl(j
));
828 /* Next the control regs, which are single-byte, address mod 4 */
831 cptr
+= sprintf(cptr
, "%03x ", i
);
832 /* Print out 4 groups of 4 bytes */
833 for (j
= 0; j
< 4; j
++) {
834 for (k
= 0; k
< 4; k
++) {
835 cptr
+= sprintf(cptr
, "%02x ",
847 static int vidioc_log_status(struct file
*file
, void *priv
)
849 struct tw68_dev
*dev
= video_drvdata(file
);
852 return v4l2_ctrl_log_status(file
, priv
);
855 #ifdef CONFIG_VIDEO_ADV_DEBUG
856 static int vidioc_g_register(struct file
*file
, void *priv
,
857 struct v4l2_dbg_register
*reg
)
859 struct tw68_dev
*dev
= video_drvdata(file
);
862 reg
->val
= tw_readb(reg
->reg
);
864 reg
->val
= tw_readl(reg
->reg
);
868 static int vidioc_s_register(struct file
*file
, void *priv
,
869 const struct v4l2_dbg_register
*reg
)
871 struct tw68_dev
*dev
= video_drvdata(file
);
874 tw_writeb(reg
->reg
, reg
->val
);
876 tw_writel(reg
->reg
& 0xffff, reg
->val
);
881 static const struct v4l2_ctrl_ops tw68_ctrl_ops
= {
882 .s_ctrl
= tw68_s_ctrl
,
885 static const struct v4l2_file_operations video_fops
= {
886 .owner
= THIS_MODULE
,
887 .open
= v4l2_fh_open
,
888 .release
= vb2_fop_release
,
889 .read
= vb2_fop_read
,
890 .poll
= vb2_fop_poll
,
891 .mmap
= vb2_fop_mmap
,
892 .unlocked_ioctl
= video_ioctl2
,
895 static const struct v4l2_ioctl_ops video_ioctl_ops
= {
896 .vidioc_querycap
= tw68_querycap
,
897 .vidioc_enum_fmt_vid_cap
= tw68_enum_fmt_vid_cap
,
898 .vidioc_reqbufs
= vb2_ioctl_reqbufs
,
899 .vidioc_create_bufs
= vb2_ioctl_create_bufs
,
900 .vidioc_querybuf
= vb2_ioctl_querybuf
,
901 .vidioc_qbuf
= vb2_ioctl_qbuf
,
902 .vidioc_dqbuf
= vb2_ioctl_dqbuf
,
903 .vidioc_s_std
= tw68_s_std
,
904 .vidioc_g_std
= tw68_g_std
,
905 .vidioc_enum_input
= tw68_enum_input
,
906 .vidioc_g_input
= tw68_g_input
,
907 .vidioc_s_input
= tw68_s_input
,
908 .vidioc_streamon
= vb2_ioctl_streamon
,
909 .vidioc_streamoff
= vb2_ioctl_streamoff
,
910 .vidioc_g_fmt_vid_cap
= tw68_g_fmt_vid_cap
,
911 .vidioc_try_fmt_vid_cap
= tw68_try_fmt_vid_cap
,
912 .vidioc_s_fmt_vid_cap
= tw68_s_fmt_vid_cap
,
913 .vidioc_log_status
= vidioc_log_status
,
914 .vidioc_subscribe_event
= v4l2_ctrl_subscribe_event
,
915 .vidioc_unsubscribe_event
= v4l2_event_unsubscribe
,
916 #ifdef CONFIG_VIDEO_ADV_DEBUG
917 .vidioc_g_register
= vidioc_g_register
,
918 .vidioc_s_register
= vidioc_s_register
,
922 static struct video_device tw68_video_template
= {
923 .name
= "tw68_video",
925 .ioctl_ops
= &video_ioctl_ops
,
926 .release
= video_device_release_empty
,
927 .tvnorms
= TW68_NORMS
,
930 /* ------------------------------------------------------------------ */
932 void tw68_set_tvnorm_hw(struct tw68_dev
*dev
)
934 tw_andorb(TW68_SDT
, 0x07, dev
->tvnorm
->format
);
937 int tw68_video_init1(struct tw68_dev
*dev
)
939 struct v4l2_ctrl_handler
*hdl
= &dev
->hdl
;
941 v4l2_ctrl_handler_init(hdl
, 6);
942 v4l2_ctrl_new_std(hdl
, &tw68_ctrl_ops
,
943 V4L2_CID_BRIGHTNESS
, -128, 127, 1, 20);
944 v4l2_ctrl_new_std(hdl
, &tw68_ctrl_ops
,
945 V4L2_CID_CONTRAST
, 0, 255, 1, 100);
946 v4l2_ctrl_new_std(hdl
, &tw68_ctrl_ops
,
947 V4L2_CID_SATURATION
, 0, 255, 1, 128);
949 v4l2_ctrl_new_std(hdl
, &tw68_ctrl_ops
,
950 V4L2_CID_HUE
, -128, 127, 1, 0);
951 v4l2_ctrl_new_std(hdl
, &tw68_ctrl_ops
,
952 V4L2_CID_COLOR_KILLER
, 0, 1, 1, 0);
953 v4l2_ctrl_new_std(hdl
, &tw68_ctrl_ops
,
954 V4L2_CID_CHROMA_AGC
, 0, 1, 1, 1);
956 v4l2_ctrl_handler_free(hdl
);
959 dev
->v4l2_dev
.ctrl_handler
= hdl
;
960 v4l2_ctrl_handler_setup(hdl
);
964 int tw68_video_init2(struct tw68_dev
*dev
, int video_nr
)
968 set_tvnorm(dev
, &tvnorms
[0]);
970 dev
->fmt
= format_by_fourcc(V4L2_PIX_FMT_BGR24
);
973 dev
->field
= V4L2_FIELD_INTERLACED
;
975 INIT_LIST_HEAD(&dev
->active
);
976 dev
->vidq
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
977 dev
->vidq
.timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC
;
978 dev
->vidq
.io_modes
= VB2_MMAP
| VB2_USERPTR
| VB2_READ
| VB2_DMABUF
;
979 dev
->vidq
.ops
= &tw68_video_qops
;
980 dev
->vidq
.mem_ops
= &vb2_dma_sg_memops
;
981 dev
->vidq
.drv_priv
= dev
;
982 dev
->vidq
.gfp_flags
= __GFP_DMA32
| __GFP_KSWAPD_RECLAIM
;
983 dev
->vidq
.buf_struct_size
= sizeof(struct tw68_buf
);
984 dev
->vidq
.lock
= &dev
->lock
;
985 dev
->vidq
.min_buffers_needed
= 2;
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");