treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 157
[linux-2.6-block.git] / drivers / media / pci / tw68 / tw68-video.c
CommitLineData
c942fddf 1// SPDX-License-Identifier: GPL-2.0-or-later
5740f4e7
HV
2/*
3 * tw68 functions to handle video data
4 *
5 * Much of this code is derived from the cx88 and sa7134 drivers, which
6 * were in turn derived from the bt87x driver. The original work was by
7 * Gerd Knorr; more recently the code was enhanced by Mauro Carvalho Chehab,
8 * Hans Verkuil, Andy Walls and many others. Their work is gratefully
9 * acknowledged. Full credit goes to them - any problems within this code
10 * are mine.
11 *
e15d1c12
HV
12 * Copyright (C) 2009 William M. Brack
13 *
14 * Refactored and updated to the latest v4l core frameworks:
15 *
16 * Copyright (C) 2014 Hans Verkuil <hverkuil@xs4all.nl>
5740f4e7
HV
17 */
18
19#include <linux/module.h>
20#include <media/v4l2-common.h>
e15d1c12
HV
21#include <media/v4l2-event.h>
22#include <media/videobuf2-dma-sg.h>
5740f4e7
HV
23
24#include "tw68.h"
25#include "tw68-reg.h"
26
5740f4e7
HV
27/* ------------------------------------------------------------------ */
28/* data structs for video */
29/*
30 * FIXME -
31 * Note that the saa7134 has formats, e.g. YUV420, which are classified
32 * as "planar". These affect overlay mode, and are flagged with a field
33 * ".planar" in the format. Do we need to implement this in this driver?
34 */
e15d1c12 35static const struct tw68_format formats[] = {
5740f4e7
HV
36 {
37 .name = "15 bpp RGB, le",
38 .fourcc = V4L2_PIX_FMT_RGB555,
39 .depth = 16,
40 .twformat = ColorFormatRGB15,
41 }, {
42 .name = "15 bpp RGB, be",
43 .fourcc = V4L2_PIX_FMT_RGB555X,
44 .depth = 16,
45 .twformat = ColorFormatRGB15 | ColorFormatBSWAP,
46 }, {
47 .name = "16 bpp RGB, le",
48 .fourcc = V4L2_PIX_FMT_RGB565,
49 .depth = 16,
50 .twformat = ColorFormatRGB16,
51 }, {
52 .name = "16 bpp RGB, be",
53 .fourcc = V4L2_PIX_FMT_RGB565X,
54 .depth = 16,
55 .twformat = ColorFormatRGB16 | ColorFormatBSWAP,
56 }, {
57 .name = "24 bpp RGB, le",
58 .fourcc = V4L2_PIX_FMT_BGR24,
59 .depth = 24,
60 .twformat = ColorFormatRGB24,
61 }, {
62 .name = "24 bpp RGB, be",
63 .fourcc = V4L2_PIX_FMT_RGB24,
64 .depth = 24,
65 .twformat = ColorFormatRGB24 | ColorFormatBSWAP,
66 }, {
67 .name = "32 bpp RGB, le",
68 .fourcc = V4L2_PIX_FMT_BGR32,
69 .depth = 32,
70 .twformat = ColorFormatRGB32,
71 }, {
72 .name = "32 bpp RGB, be",
73 .fourcc = V4L2_PIX_FMT_RGB32,
74 .depth = 32,
75 .twformat = ColorFormatRGB32 | ColorFormatBSWAP |
76 ColorFormatWSWAP,
77 }, {
78 .name = "4:2:2 packed, YUYV",
79 .fourcc = V4L2_PIX_FMT_YUYV,
80 .depth = 16,
81 .twformat = ColorFormatYUY2,
82 }, {
83 .name = "4:2:2 packed, UYVY",
84 .fourcc = V4L2_PIX_FMT_UYVY,
85 .depth = 16,
86 .twformat = ColorFormatYUY2 | ColorFormatBSWAP,
87 }
88};
89#define FORMATS ARRAY_SIZE(formats)
90
91#define NORM_625_50 \
92 .h_delay = 3, \
93 .h_delay0 = 133, \
94 .h_start = 0, \
95 .h_stop = 719, \
96 .v_delay = 24, \
97 .vbi_v_start_0 = 7, \
98 .vbi_v_stop_0 = 22, \
99 .video_v_start = 24, \
100 .video_v_stop = 311, \
101 .vbi_v_start_1 = 319
102
103#define NORM_525_60 \
104 .h_delay = 8, \
105 .h_delay0 = 138, \
106 .h_start = 0, \
107 .h_stop = 719, \
108 .v_delay = 22, \
109 .vbi_v_start_0 = 10, \
110 .vbi_v_stop_0 = 21, \
111 .video_v_start = 22, \
112 .video_v_stop = 262, \
113 .vbi_v_start_1 = 273
114
115/*
116 * The following table is searched by tw68_s_std, first for a specific
117 * match, then for an entry which contains the desired id. The table
118 * entries should therefore be ordered in ascending order of specificity.
119 */
e15d1c12 120static const struct tw68_tvnorm tvnorms[] = {
5740f4e7 121 {
5740f4e7
HV
122 .name = "PAL", /* autodetect */
123 .id = V4L2_STD_PAL,
124 NORM_625_50,
125
126 .sync_control = 0x18,
127 .luma_control = 0x40,
128 .chroma_ctrl1 = 0x81,
129 .chroma_gain = 0x2a,
130 .chroma_ctrl2 = 0x06,
131 .vgate_misc = 0x1c,
132 .format = VideoFormatPALBDGHI,
5740f4e7
HV
133 }, {
134 .name = "NTSC",
135 .id = V4L2_STD_NTSC,
136 NORM_525_60,
137
138 .sync_control = 0x59,
139 .luma_control = 0x40,
140 .chroma_ctrl1 = 0x89,
141 .chroma_gain = 0x2a,
142 .chroma_ctrl2 = 0x0e,
143 .vgate_misc = 0x18,
144 .format = VideoFormatNTSC,
5740f4e7
HV
145 }, {
146 .name = "SECAM",
147 .id = V4L2_STD_SECAM,
148 NORM_625_50,
149
150 .sync_control = 0x18,
151 .luma_control = 0x1b,
152 .chroma_ctrl1 = 0xd1,
153 .chroma_gain = 0x80,
154 .chroma_ctrl2 = 0x00,
155 .vgate_misc = 0x1c,
156 .format = VideoFormatSECAM,
5740f4e7
HV
157 }, {
158 .name = "PAL-M",
159 .id = V4L2_STD_PAL_M,
160 NORM_525_60,
161
162 .sync_control = 0x59,
163 .luma_control = 0x40,
164 .chroma_ctrl1 = 0xb9,
165 .chroma_gain = 0x2a,
166 .chroma_ctrl2 = 0x0e,
167 .vgate_misc = 0x18,
168 .format = VideoFormatPALM,
5740f4e7
HV
169 }, {
170 .name = "PAL-Nc",
171 .id = V4L2_STD_PAL_Nc,
172 NORM_625_50,
173
174 .sync_control = 0x18,
175 .luma_control = 0x40,
176 .chroma_ctrl1 = 0xa1,
177 .chroma_gain = 0x2a,
178 .chroma_ctrl2 = 0x06,
179 .vgate_misc = 0x1c,
180 .format = VideoFormatPALNC,
5740f4e7
HV
181 }, {
182 .name = "PAL-60",
183 .id = V4L2_STD_PAL_60,
184 .h_delay = 186,
185 .h_start = 0,
186 .h_stop = 719,
187 .v_delay = 26,
188 .video_v_start = 23,
189 .video_v_stop = 262,
190 .vbi_v_start_0 = 10,
191 .vbi_v_stop_0 = 21,
192 .vbi_v_start_1 = 273,
193
194 .sync_control = 0x18,
195 .luma_control = 0x40,
196 .chroma_ctrl1 = 0x81,
197 .chroma_gain = 0x2a,
198 .chroma_ctrl2 = 0x06,
199 .vgate_misc = 0x1c,
200 .format = VideoFormatPAL60,
5740f4e7
HV
201 }
202};
203#define TVNORMS ARRAY_SIZE(tvnorms)
204
e15d1c12 205static const struct tw68_format *format_by_fourcc(unsigned int fourcc)
5740f4e7
HV
206{
207 unsigned int i;
208
209 for (i = 0; i < FORMATS; i++)
210 if (formats[i].fourcc == fourcc)
211 return formats+i;
212 return NULL;
213}
214
5740f4e7
HV
215
216/* ------------------------------------------------------------------ */
217/*
218 * Note that the cropping rectangles are described in terms of a single
219 * frame, i.e. line positions are only 1/2 the interlaced equivalent
220 */
e15d1c12 221static void set_tvnorm(struct tw68_dev *dev, const struct tw68_tvnorm *norm)
5740f4e7 222{
5740f4e7 223 if (norm != dev->tvnorm) {
e15d1c12
HV
224 dev->width = 720;
225 dev->height = (norm->id & V4L2_STD_525_60) ? 480 : 576;
5740f4e7
HV
226 dev->tvnorm = norm;
227 tw68_set_tvnorm_hw(dev);
228 }
229}
230
5740f4e7
HV
231/*
232 * tw68_set_scale
233 *
234 * Scaling and Cropping for video decoding
235 *
236 * We are working with 3 values for horizontal and vertical - scale,
237 * delay and active.
238 *
239 * HACTIVE represent the actual number of pixels in the "usable" image,
240 * before scaling. HDELAY represents the number of pixels skipped
241 * between the start of the horizontal sync and the start of the image.
242 * HSCALE is calculated using the formula
e15d1c12 243 * HSCALE = (HACTIVE / (#pixels desired)) * 256
5740f4e7
HV
244 *
245 * The vertical registers are similar, except based upon the total number
246 * of lines in the image, and the first line of the image (i.e. ignoring
247 * vertical sync and VBI).
248 *
249 * Note that the number of bytes reaching the FIFO (and hence needing
250 * to be processed by the DMAP program) is completely dependent upon
251 * these values, especially HSCALE.
252 *
253 * Parameters:
e15d1c12
HV
254 * @dev pointer to the device structure, needed for
255 * getting current norm (as well as debug print)
256 * @width actual image width (from user buffer)
257 * @height actual image height
258 * @field indicates Top, Bottom or Interlaced
5740f4e7
HV
259 */
260static int tw68_set_scale(struct tw68_dev *dev, unsigned int width,
261 unsigned int height, enum v4l2_field field)
262{
e15d1c12 263 const struct tw68_tvnorm *norm = dev->tvnorm;
5740f4e7
HV
264 /* set individually for debugging clarity */
265 int hactive, hdelay, hscale;
266 int vactive, vdelay, vscale;
267 int comb;
268
269 if (V4L2_FIELD_HAS_BOTH(field)) /* if field is interlaced */
270 height /= 2; /* we must set for 1-frame */
271
e15d1c12 272 pr_debug("%s: width=%d, height=%d, both=%d\n"
db6d8d5f
MCC
273 " tvnorm h_delay=%d, h_start=%d, h_stop=%d, v_delay=%d, v_start=%d, v_stop=%d\n",
274 __func__, width, height, V4L2_FIELD_HAS_BOTH(field),
e15d1c12
HV
275 norm->h_delay, norm->h_start, norm->h_stop,
276 norm->v_delay, norm->video_v_start,
277 norm->video_v_stop);
5740f4e7
HV
278
279 switch (dev->vdecoder) {
280 case TW6800:
e15d1c12 281 hdelay = norm->h_delay0;
5740f4e7
HV
282 break;
283 default:
e15d1c12 284 hdelay = norm->h_delay;
5740f4e7
HV
285 break;
286 }
e15d1c12
HV
287
288 hdelay += norm->h_start;
289 hactive = norm->h_stop - norm->h_start + 1;
5740f4e7
HV
290
291 hscale = (hactive * 256) / (width);
292
e15d1c12
HV
293 vdelay = norm->v_delay;
294 vactive = ((norm->id & V4L2_STD_525_60) ? 524 : 624) / 2 - norm->video_v_start;
5740f4e7
HV
295 vscale = (vactive * 256) / height;
296
e15d1c12 297 pr_debug("%s: %dx%d [%s%s,%s]\n", __func__,
5740f4e7
HV
298 width, height,
299 V4L2_FIELD_HAS_TOP(field) ? "T" : "",
300 V4L2_FIELD_HAS_BOTTOM(field) ? "B" : "",
301 v4l2_norm_to_name(dev->tvnorm->id));
db6d8d5f
MCC
302 pr_debug("%s: hactive=%d, hdelay=%d, hscale=%d; vactive=%d, vdelay=%d, vscale=%d\n",
303 __func__,
5740f4e7
HV
304 hactive, hdelay, hscale, vactive, vdelay, vscale);
305
306 comb = ((vdelay & 0x300) >> 2) |
307 ((vactive & 0x300) >> 4) |
308 ((hdelay & 0x300) >> 6) |
309 ((hactive & 0x300) >> 8);
db6d8d5f 310 pr_debug("%s: setting CROP_HI=%02x, VDELAY_LO=%02x, VACTIVE_LO=%02x, HDELAY_LO=%02x, HACTIVE_LO=%02x\n",
5740f4e7
HV
311 __func__, comb, vdelay, vactive, hdelay, hactive);
312 tw_writeb(TW68_CROP_HI, comb);
313 tw_writeb(TW68_VDELAY_LO, vdelay & 0xff);
314 tw_writeb(TW68_VACTIVE_LO, vactive & 0xff);
315 tw_writeb(TW68_HDELAY_LO, hdelay & 0xff);
316 tw_writeb(TW68_HACTIVE_LO, hactive & 0xff);
317
318 comb = ((vscale & 0xf00) >> 4) | ((hscale & 0xf00) >> 8);
db6d8d5f
MCC
319 pr_debug("%s: setting SCALE_HI=%02x, VSCALE_LO=%02x, HSCALE_LO=%02x\n",
320 __func__, comb, vscale, hscale);
5740f4e7
HV
321 tw_writeb(TW68_SCALE_HI, comb);
322 tw_writeb(TW68_VSCALE_LO, vscale);
323 tw_writeb(TW68_HSCALE_LO, hscale);
324
325 return 0;
326}
327
328/* ------------------------------------------------------------------ */
329
e15d1c12
HV
330int tw68_video_start_dma(struct tw68_dev *dev, struct tw68_buf *buf)
331{
5740f4e7 332 /* Set cropping and scaling */
e15d1c12 333 tw68_set_scale(dev, dev->width, dev->height, dev->field);
5740f4e7
HV
334 /*
335 * Set start address for RISC program. Note that if the DMAP
336 * processor is currently running, it must be stopped before
337 * a new address can be set.
338 */
339 tw_clearl(TW68_DMAC, TW68_DMAP_EN);
91f96e8b 340 tw_writel(TW68_DMAP_SA, buf->dma);
5740f4e7
HV
341 /* Clear any pending interrupts */
342 tw_writel(TW68_INTSTAT, dev->board_virqmask);
343 /* Enable the risc engine and the fifo */
e15d1c12 344 tw_andorl(TW68_DMAC, 0xff, dev->fmt->twformat |
5740f4e7
HV
345 ColorFormatGamma | TW68_DMAP_EN | TW68_FIFO_EN);
346 dev->pci_irqmask |= dev->board_virqmask;
347 tw_setl(TW68_INTMASK, dev->pci_irqmask);
348 return 0;
349}
350
351/* ------------------------------------------------------------------ */
5740f4e7 352
e15d1c12
HV
353/* calc max # of buffers from size (must not exceed the 4MB virtual
354 * address space per DMA channel) */
355static int tw68_buffer_count(unsigned int size, unsigned int count)
5740f4e7 356{
e15d1c12 357 unsigned int maxcount;
5740f4e7 358
947b38bb 359 maxcount = (4 * 1024 * 1024) / roundup(size, PAGE_SIZE);
e15d1c12
HV
360 if (count > maxcount)
361 count = maxcount;
362 return count;
5740f4e7
HV
363}
364
e15d1c12
HV
365/* ------------------------------------------------------------- */
366/* vb2 queue operations */
5740f4e7 367
df9ecb0c 368static int tw68_queue_setup(struct vb2_queue *q,
e15d1c12 369 unsigned int *num_buffers, unsigned int *num_planes,
36c0f8b3 370 unsigned int sizes[], struct device *alloc_devs[])
5740f4e7 371{
e15d1c12
HV
372 struct tw68_dev *dev = vb2_get_drv_priv(q);
373 unsigned tot_bufs = q->num_buffers + *num_buffers;
df9ecb0c 374 unsigned size = (dev->fmt->depth * dev->width * dev->height) >> 3;
5740f4e7 375
df9ecb0c
HV
376 if (tot_bufs < 2)
377 tot_bufs = 2;
378 tot_bufs = tw68_buffer_count(size, tot_bufs);
379 *num_buffers = tot_bufs - q->num_buffers;
e15d1c12 380 /*
df9ecb0c 381 * We allow create_bufs, but only if the sizeimage is >= as the
e15d1c12
HV
382 * current sizeimage. The tw68_buffer_count calculation becomes quite
383 * difficult otherwise.
384 */
df9ecb0c
HV
385 if (*num_planes)
386 return sizes[0] < size ? -EINVAL : 0;
e15d1c12 387 *num_planes = 1;
df9ecb0c 388 sizes[0] = size;
5740f4e7 389
5740f4e7 390 return 0;
5740f4e7
HV
391}
392
393/*
e15d1c12
HV
394 * The risc program for each buffers works as follows: it starts with a simple
395 * 'JUMP to addr + 8', which is effectively a NOP. Then the program to DMA the
396 * buffer follows and at the end we have a JUMP back to the start + 8 (skipping
397 * the initial JUMP).
398 *
399 * This is the program of the first buffer to be queued if the active list is
400 * empty and it just keeps DMAing this buffer without generating any interrupts.
401 *
402 * If a new buffer is added then the initial JUMP in the program generates an
403 * interrupt as well which signals that the previous buffer has been DMAed
404 * successfully and that it can be returned to userspace.
405 *
406 * It also sets the final jump of the previous buffer to the start of the new
407 * buffer, thus chaining the new buffer into the DMA chain. This is a single
408 * atomic u32 write, so there is no race condition.
5740f4e7 409 *
e15d1c12
HV
410 * The end-result of all this that you only get an interrupt when a buffer
411 * is ready, so the control flow is very easy.
5740f4e7 412 */
e15d1c12 413static void tw68_buf_queue(struct vb2_buffer *vb)
5740f4e7 414{
2d700715 415 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
e15d1c12
HV
416 struct vb2_queue *vq = vb->vb2_queue;
417 struct tw68_dev *dev = vb2_get_drv_priv(vq);
2d700715 418 struct tw68_buf *buf = container_of(vbuf, struct tw68_buf, vb);
e15d1c12
HV
419 struct tw68_buf *prev;
420 unsigned long flags;
421
422 spin_lock_irqsave(&dev->slock, flags);
5740f4e7 423
e15d1c12
HV
424 /* append a 'JUMP to start of buffer' to the buffer risc program */
425 buf->jmp[0] = cpu_to_le32(RISC_JUMP);
426 buf->jmp[1] = cpu_to_le32(buf->dma + 8);
427
428 if (!list_empty(&dev->active)) {
429 prev = list_entry(dev->active.prev, struct tw68_buf, list);
430 buf->cpu[0] |= cpu_to_le32(RISC_INT_BIT);
431 prev->jmp[1] = cpu_to_le32(buf->dma);
432 }
433 list_add_tail(&buf->list, &dev->active);
434 spin_unlock_irqrestore(&dev->slock, flags);
5740f4e7
HV
435}
436
437/*
e15d1c12 438 * buffer_prepare
5740f4e7 439 *
16790554 440 * Set the ancillary information into the buffer structure. This
e15d1c12
HV
441 * includes generating the necessary risc program if it hasn't already
442 * been done for the current buffer format.
443 * The structure fh contains the details of the format requested by the
444 * user - type, width, height and #fields. This is compared with the
445 * last format set for the current buffer. If they differ, the risc
446 * code (which controls the filling of the buffer) is (re-)generated.
5740f4e7 447 */
e15d1c12 448static int tw68_buf_prepare(struct vb2_buffer *vb)
5740f4e7 449{
2d700715 450 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
e15d1c12
HV
451 struct vb2_queue *vq = vb->vb2_queue;
452 struct tw68_dev *dev = vb2_get_drv_priv(vq);
2d700715 453 struct tw68_buf *buf = container_of(vbuf, struct tw68_buf, vb);
e15d1c12
HV
454 struct sg_table *dma = vb2_dma_sg_plane_desc(vb, 0);
455 unsigned size, bpl;
5740f4e7 456
e15d1c12
HV
457 size = (dev->width * dev->height * dev->fmt->depth) >> 3;
458 if (vb2_plane_size(vb, 0) < size)
459 return -EINVAL;
460 vb2_set_plane_payload(vb, 0, size);
5740f4e7 461
e15d1c12
HV
462 bpl = (dev->width * dev->fmt->depth) >> 3;
463 switch (dev->field) {
464 case V4L2_FIELD_TOP:
465 tw68_risc_buffer(dev->pci, buf, dma->sgl,
466 0, UNSET, bpl, 0, dev->height);
5740f4e7 467 break;
e15d1c12
HV
468 case V4L2_FIELD_BOTTOM:
469 tw68_risc_buffer(dev->pci, buf, dma->sgl,
470 UNSET, 0, bpl, 0, dev->height);
5740f4e7 471 break;
e15d1c12
HV
472 case V4L2_FIELD_SEQ_TB:
473 tw68_risc_buffer(dev->pci, buf, dma->sgl,
474 0, bpl * (dev->height >> 1),
475 bpl, 0, dev->height >> 1);
5740f4e7 476 break;
e15d1c12
HV
477 case V4L2_FIELD_SEQ_BT:
478 tw68_risc_buffer(dev->pci, buf, dma->sgl,
479 bpl * (dev->height >> 1), 0,
480 bpl, 0, dev->height >> 1);
5740f4e7 481 break;
e15d1c12 482 case V4L2_FIELD_INTERLACED:
5740f4e7 483 default:
e15d1c12
HV
484 tw68_risc_buffer(dev->pci, buf, dma->sgl,
485 0, bpl, bpl, bpl, dev->height >> 1);
486 break;
5740f4e7
HV
487 }
488 return 0;
489}
490
e15d1c12
HV
491static void tw68_buf_finish(struct vb2_buffer *vb)
492{
2d700715 493 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
e15d1c12
HV
494 struct vb2_queue *vq = vb->vb2_queue;
495 struct tw68_dev *dev = vb2_get_drv_priv(vq);
2d700715 496 struct tw68_buf *buf = container_of(vbuf, struct tw68_buf, vb);
e15d1c12 497
e15d1c12
HV
498 pci_free_consistent(dev->pci, buf->size, buf->cpu, buf->dma);
499}
500
501static int tw68_start_streaming(struct vb2_queue *q, unsigned int count)
502{
503 struct tw68_dev *dev = vb2_get_drv_priv(q);
504 struct tw68_buf *buf =
505 container_of(dev->active.next, struct tw68_buf, list);
506
507 dev->seqnr = 0;
508 tw68_video_start_dma(dev, buf);
509 return 0;
510}
511
512static void tw68_stop_streaming(struct vb2_queue *q)
5740f4e7 513{
e15d1c12
HV
514 struct tw68_dev *dev = vb2_get_drv_priv(q);
515
516 /* Stop risc & fifo */
517 tw_clearl(TW68_DMAC, TW68_DMAP_EN | TW68_FIFO_EN);
518 while (!list_empty(&dev->active)) {
519 struct tw68_buf *buf =
520 container_of(dev->active.next, struct tw68_buf, list);
5740f4e7 521
e15d1c12 522 list_del(&buf->list);
2d700715 523 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
e15d1c12 524 }
5740f4e7
HV
525}
526
10accd2e 527static const struct vb2_ops tw68_video_qops = {
e15d1c12
HV
528 .queue_setup = tw68_queue_setup,
529 .buf_queue = tw68_buf_queue,
530 .buf_prepare = tw68_buf_prepare,
531 .buf_finish = tw68_buf_finish,
532 .start_streaming = tw68_start_streaming,
533 .stop_streaming = tw68_stop_streaming,
534 .wait_prepare = vb2_ops_wait_prepare,
535 .wait_finish = vb2_ops_wait_finish,
536};
537
538/* ------------------------------------------------------------------ */
539
540static int tw68_s_ctrl(struct v4l2_ctrl *ctrl)
5740f4e7 541{
e15d1c12
HV
542 struct tw68_dev *dev =
543 container_of(ctrl->handler, struct tw68_dev, hdl);
5740f4e7 544
e15d1c12 545 switch (ctrl->id) {
5740f4e7 546 case V4L2_CID_BRIGHTNESS:
e15d1c12 547 tw_writeb(TW68_BRIGHT, ctrl->val);
5740f4e7
HV
548 break;
549 case V4L2_CID_HUE:
e15d1c12 550 tw_writeb(TW68_HUE, ctrl->val);
5740f4e7
HV
551 break;
552 case V4L2_CID_CONTRAST:
e15d1c12 553 tw_writeb(TW68_CONTRAST, ctrl->val);
5740f4e7
HV
554 break;
555 case V4L2_CID_SATURATION:
e15d1c12
HV
556 tw_writeb(TW68_SAT_U, ctrl->val);
557 tw_writeb(TW68_SAT_V, ctrl->val);
5740f4e7
HV
558 break;
559 case V4L2_CID_COLOR_KILLER:
e15d1c12 560 if (ctrl->val)
5740f4e7
HV
561 tw_andorb(TW68_MISC2, 0xe0, 0xe0);
562 else
563 tw_andorb(TW68_MISC2, 0xe0, 0x00);
564 break;
565 case V4L2_CID_CHROMA_AGC:
e15d1c12 566 if (ctrl->val)
5740f4e7
HV
567 tw_andorb(TW68_LOOP, 0x30, 0x20);
568 else
569 tw_andorb(TW68_LOOP, 0x30, 0x00);
570 break;
5740f4e7 571 }
e15d1c12 572 return 0;
5740f4e7
HV
573}
574
e15d1c12 575/* ------------------------------------------------------------------ */
5740f4e7 576
e15d1c12
HV
577/*
578 * Note that this routine returns what is stored in the fh structure, and
579 * does not interrogate any of the device registers.
580 */
581static int tw68_g_fmt_vid_cap(struct file *file, void *priv,
582 struct v4l2_format *f)
583{
584 struct tw68_dev *dev = video_drvdata(file);
5740f4e7 585
e15d1c12
HV
586 f->fmt.pix.width = dev->width;
587 f->fmt.pix.height = dev->height;
588 f->fmt.pix.field = dev->field;
589 f->fmt.pix.pixelformat = dev->fmt->fourcc;
5740f4e7 590 f->fmt.pix.bytesperline =
e15d1c12 591 (f->fmt.pix.width * (dev->fmt->depth)) >> 3;
5740f4e7
HV
592 f->fmt.pix.sizeimage =
593 f->fmt.pix.height * f->fmt.pix.bytesperline;
594 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
e15d1c12 595 f->fmt.pix.priv = 0;
5740f4e7
HV
596 return 0;
597}
598
599static int tw68_try_fmt_vid_cap(struct file *file, void *priv,
600 struct v4l2_format *f)
601{
e15d1c12
HV
602 struct tw68_dev *dev = video_drvdata(file);
603 const struct tw68_format *fmt;
5740f4e7 604 enum v4l2_field field;
e15d1c12 605 unsigned int maxh;
5740f4e7 606
5740f4e7
HV
607 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
608 if (NULL == fmt)
609 return -EINVAL;
610
611 field = f->fmt.pix.field;
e15d1c12 612 maxh = (dev->tvnorm->id & V4L2_STD_525_60) ? 480 : 576;
5740f4e7 613
5740f4e7
HV
614 switch (field) {
615 case V4L2_FIELD_TOP:
616 case V4L2_FIELD_BOTTOM:
617 break;
618 case V4L2_FIELD_INTERLACED:
e15d1c12
HV
619 case V4L2_FIELD_SEQ_BT:
620 case V4L2_FIELD_SEQ_TB:
5740f4e7
HV
621 maxh = maxh * 2;
622 break;
623 default:
e15d1c12
HV
624 field = (f->fmt.pix.height > maxh / 2)
625 ? V4L2_FIELD_INTERLACED
626 : V4L2_FIELD_BOTTOM;
627 break;
5740f4e7
HV
628 }
629
630 f->fmt.pix.field = field;
631 if (f->fmt.pix.width < 48)
632 f->fmt.pix.width = 48;
633 if (f->fmt.pix.height < 32)
634 f->fmt.pix.height = 32;
e15d1c12
HV
635 if (f->fmt.pix.width > 720)
636 f->fmt.pix.width = 720;
5740f4e7
HV
637 if (f->fmt.pix.height > maxh)
638 f->fmt.pix.height = maxh;
639 f->fmt.pix.width &= ~0x03;
640 f->fmt.pix.bytesperline =
641 (f->fmt.pix.width * (fmt->depth)) >> 3;
642 f->fmt.pix.sizeimage =
643 f->fmt.pix.height * f->fmt.pix.bytesperline;
e15d1c12 644 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
5740f4e7
HV
645 return 0;
646}
647
648/*
649 * Note that tw68_s_fmt_vid_cap sets the information into the fh structure,
650 * and it will be used for all future new buffers. However, there could be
651 * some number of buffers on the "active" chain which will be filled before
652 * the change takes place.
653 */
654static int tw68_s_fmt_vid_cap(struct file *file, void *priv,
655 struct v4l2_format *f)
656{
e15d1c12 657 struct tw68_dev *dev = video_drvdata(file);
5740f4e7
HV
658 int err;
659
5740f4e7
HV
660 err = tw68_try_fmt_vid_cap(file, priv, f);
661 if (0 != err)
662 return err;
663
e15d1c12
HV
664 dev->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
665 dev->width = f->fmt.pix.width;
666 dev->height = f->fmt.pix.height;
667 dev->field = f->fmt.pix.field;
5740f4e7
HV
668 return 0;
669}
670
671static int tw68_enum_input(struct file *file, void *priv,
672 struct v4l2_input *i)
673{
e15d1c12 674 struct tw68_dev *dev = video_drvdata(file);
5740f4e7
HV
675 unsigned int n;
676
677 n = i->index;
e15d1c12 678 if (n >= TW68_INPUT_MAX)
5740f4e7 679 return -EINVAL;
5740f4e7 680 i->index = n;
e15d1c12
HV
681 i->type = V4L2_INPUT_TYPE_CAMERA;
682 snprintf(i->name, sizeof(i->name), "Composite %d", n);
683
5740f4e7 684 /* If the query is for the current input, get live data */
e15d1c12 685 if (n == dev->input) {
5740f4e7
HV
686 int v1 = tw_readb(TW68_STATUS1);
687 int v2 = tw_readb(TW68_MVSN);
688
689 if (0 != (v1 & (1 << 7)))
690 i->status |= V4L2_IN_ST_NO_SYNC;
691 if (0 != (v1 & (1 << 6)))
692 i->status |= V4L2_IN_ST_NO_H_LOCK;
693 if (0 != (v1 & (1 << 2)))
694 i->status |= V4L2_IN_ST_NO_SIGNAL;
695 if (0 != (v1 & 1 << 1))
696 i->status |= V4L2_IN_ST_NO_COLOR;
697 if (0 != (v2 & (1 << 2)))
698 i->status |= V4L2_IN_ST_MACROVISION;
699 }
e15d1c12 700 i->std = video_devdata(file)->tvnorms;
5740f4e7
HV
701 return 0;
702}
703
704static int tw68_g_input(struct file *file, void *priv, unsigned int *i)
705{
e15d1c12 706 struct tw68_dev *dev = video_drvdata(file);
5740f4e7 707
e15d1c12 708 *i = dev->input;
5740f4e7
HV
709 return 0;
710}
711
712static int tw68_s_input(struct file *file, void *priv, unsigned int i)
713{
e15d1c12 714 struct tw68_dev *dev = video_drvdata(file);
5740f4e7 715
e15d1c12 716 if (i >= TW68_INPUT_MAX)
5740f4e7 717 return -EINVAL;
e15d1c12
HV
718 dev->input = i;
719 tw_andorb(TW68_INFORM, 0x03 << 2, dev->input << 2);
5740f4e7
HV
720 return 0;
721}
722
723static int tw68_querycap(struct file *file, void *priv,
724 struct v4l2_capability *cap)
725{
e15d1c12 726 struct tw68_dev *dev = video_drvdata(file);
5740f4e7 727
cc1e6315 728 strscpy(cap->driver, "tw68", sizeof(cap->driver));
c0decac1 729 strscpy(cap->card, "Techwell Capture Card",
5740f4e7
HV
730 sizeof(cap->card));
731 sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
e15d1c12 732 cap->device_caps =
5740f4e7 733 V4L2_CAP_VIDEO_CAPTURE |
5740f4e7 734 V4L2_CAP_READWRITE |
e15d1c12 735 V4L2_CAP_STREAMING;
5740f4e7 736
e15d1c12 737 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
5740f4e7
HV
738 return 0;
739}
740
e15d1c12 741static int tw68_s_std(struct file *file, void *priv, v4l2_std_id id)
5740f4e7 742{
e15d1c12 743 struct tw68_dev *dev = video_drvdata(file);
5740f4e7 744 unsigned int i;
5740f4e7 745
e15d1c12
HV
746 if (vb2_is_busy(&dev->vidq))
747 return -EBUSY;
5740f4e7
HV
748
749 /* Look for match on complete norm id (may have mult bits) */
750 for (i = 0; i < TVNORMS; i++) {
e15d1c12 751 if (id == tvnorms[i].id)
5740f4e7
HV
752 break;
753 }
754
755 /* If no exact match, look for norm which contains this one */
e15d1c12
HV
756 if (i == TVNORMS) {
757 for (i = 0; i < TVNORMS; i++)
758 if (id & tvnorms[i].id)
5740f4e7 759 break;
e15d1c12 760 }
5740f4e7
HV
761 /* If still not matched, give up */
762 if (i == TVNORMS)
763 return -EINVAL;
764
5740f4e7 765 set_tvnorm(dev, &tvnorms[i]); /* do the actual setting */
5740f4e7
HV
766 return 0;
767}
768
5740f4e7
HV
769static int tw68_g_std(struct file *file, void *priv, v4l2_std_id *id)
770{
e15d1c12 771 struct tw68_dev *dev = video_drvdata(file);
5740f4e7 772
5740f4e7
HV
773 *id = dev->tvnorm->id;
774 return 0;
775}
776
5740f4e7
HV
777static int tw68_enum_fmt_vid_cap(struct file *file, void *priv,
778 struct v4l2_fmtdesc *f)
779{
5740f4e7
HV
780 if (f->index >= FORMATS)
781 return -EINVAL;
782
c0decac1 783 strscpy(f->description, formats[f->index].name,
5740f4e7
HV
784 sizeof(f->description));
785
786 f->pixelformat = formats[f->index].fourcc;
787
788 return 0;
789}
790
5740f4e7
HV
791/*
792 * Used strictly for internal development and debugging, this routine
793 * prints out the current register contents for the tw68xx device.
794 */
795static void tw68_dump_regs(struct tw68_dev *dev)
796{
797 unsigned char line[80];
798 int i, j, k;
799 unsigned char *cptr;
800
e15d1c12 801 pr_info("Full dump of TW68 registers:\n");
5740f4e7
HV
802 /* First we do the PCI regs, 8 4-byte regs per line */
803 for (i = 0; i < 0x100; i += 32) {
804 cptr = line;
805 cptr += sprintf(cptr, "%03x ", i);
806 /* j steps through the next 4 words */
807 for (j = i; j < i + 16; j += 4)
808 cptr += sprintf(cptr, "%08x ", tw_readl(j));
809 *cptr++ = ' ';
810 for (; j < i + 32; j += 4)
811 cptr += sprintf(cptr, "%08x ", tw_readl(j));
812 *cptr++ = '\n';
813 *cptr = 0;
e15d1c12 814 pr_info("%s", line);
5740f4e7
HV
815 }
816 /* Next the control regs, which are single-byte, address mod 4 */
817 while (i < 0x400) {
818 cptr = line;
819 cptr += sprintf(cptr, "%03x ", i);
820 /* Print out 4 groups of 4 bytes */
821 for (j = 0; j < 4; j++) {
822 for (k = 0; k < 4; k++) {
823 cptr += sprintf(cptr, "%02x ",
824 tw_readb(i));
825 i += 4;
826 }
827 *cptr++ = ' ';
828 }
829 *cptr++ = '\n';
830 *cptr = 0;
e15d1c12 831 pr_info("%s", line);
5740f4e7
HV
832 }
833}
834
835static int vidioc_log_status(struct file *file, void *priv)
836{
e15d1c12 837 struct tw68_dev *dev = video_drvdata(file);
5740f4e7
HV
838
839 tw68_dump_regs(dev);
e15d1c12 840 return v4l2_ctrl_log_status(file, priv);
5740f4e7
HV
841}
842
e15d1c12 843#ifdef CONFIG_VIDEO_ADV_DEBUG
5740f4e7
HV
844static int vidioc_g_register(struct file *file, void *priv,
845 struct v4l2_dbg_register *reg)
846{
e15d1c12 847 struct tw68_dev *dev = video_drvdata(file);
5740f4e7 848
5740f4e7
HV
849 if (reg->size == 1)
850 reg->val = tw_readb(reg->reg);
851 else
852 reg->val = tw_readl(reg->reg);
853 return 0;
854}
855
856static int vidioc_s_register(struct file *file, void *priv,
e15d1c12 857 const struct v4l2_dbg_register *reg)
5740f4e7 858{
e15d1c12 859 struct tw68_dev *dev = video_drvdata(file);
5740f4e7 860
5740f4e7
HV
861 if (reg->size == 1)
862 tw_writeb(reg->reg, reg->val);
863 else
864 tw_writel(reg->reg & 0xffff, reg->val);
865 return 0;
866}
867#endif
868
e15d1c12
HV
869static const struct v4l2_ctrl_ops tw68_ctrl_ops = {
870 .s_ctrl = tw68_s_ctrl,
871};
872
5740f4e7
HV
873static const struct v4l2_file_operations video_fops = {
874 .owner = THIS_MODULE,
e15d1c12
HV
875 .open = v4l2_fh_open,
876 .release = vb2_fop_release,
877 .read = vb2_fop_read,
878 .poll = vb2_fop_poll,
879 .mmap = vb2_fop_mmap,
880 .unlocked_ioctl = video_ioctl2,
5740f4e7
HV
881};
882
883static const struct v4l2_ioctl_ops video_ioctl_ops = {
884 .vidioc_querycap = tw68_querycap,
885 .vidioc_enum_fmt_vid_cap = tw68_enum_fmt_vid_cap,
e15d1c12
HV
886 .vidioc_reqbufs = vb2_ioctl_reqbufs,
887 .vidioc_create_bufs = vb2_ioctl_create_bufs,
888 .vidioc_querybuf = vb2_ioctl_querybuf,
889 .vidioc_qbuf = vb2_ioctl_qbuf,
890 .vidioc_dqbuf = vb2_ioctl_dqbuf,
5740f4e7
HV
891 .vidioc_s_std = tw68_s_std,
892 .vidioc_g_std = tw68_g_std,
893 .vidioc_enum_input = tw68_enum_input,
894 .vidioc_g_input = tw68_g_input,
895 .vidioc_s_input = tw68_s_input,
e15d1c12
HV
896 .vidioc_streamon = vb2_ioctl_streamon,
897 .vidioc_streamoff = vb2_ioctl_streamoff,
5740f4e7
HV
898 .vidioc_g_fmt_vid_cap = tw68_g_fmt_vid_cap,
899 .vidioc_try_fmt_vid_cap = tw68_try_fmt_vid_cap,
900 .vidioc_s_fmt_vid_cap = tw68_s_fmt_vid_cap,
5740f4e7 901 .vidioc_log_status = vidioc_log_status,
e15d1c12
HV
902 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
903 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
904#ifdef CONFIG_VIDEO_ADV_DEBUG
5740f4e7
HV
905 .vidioc_g_register = vidioc_g_register,
906 .vidioc_s_register = vidioc_s_register,
907#endif
908};
909
507e1909 910static const struct video_device tw68_video_template = {
5740f4e7
HV
911 .name = "tw68_video",
912 .fops = &video_fops,
913 .ioctl_ops = &video_ioctl_ops,
e15d1c12 914 .release = video_device_release_empty,
5740f4e7 915 .tvnorms = TW68_NORMS,
5740f4e7
HV
916};
917
e15d1c12
HV
918/* ------------------------------------------------------------------ */
919/* exported stuff */
5740f4e7
HV
920void tw68_set_tvnorm_hw(struct tw68_dev *dev)
921{
922 tw_andorb(TW68_SDT, 0x07, dev->tvnorm->format);
5740f4e7
HV
923}
924
925int tw68_video_init1(struct tw68_dev *dev)
926{
e15d1c12
HV
927 struct v4l2_ctrl_handler *hdl = &dev->hdl;
928
929 v4l2_ctrl_handler_init(hdl, 6);
930 v4l2_ctrl_new_std(hdl, &tw68_ctrl_ops,
931 V4L2_CID_BRIGHTNESS, -128, 127, 1, 20);
932 v4l2_ctrl_new_std(hdl, &tw68_ctrl_ops,
933 V4L2_CID_CONTRAST, 0, 255, 1, 100);
934 v4l2_ctrl_new_std(hdl, &tw68_ctrl_ops,
935 V4L2_CID_SATURATION, 0, 255, 1, 128);
936 /* NTSC only */
937 v4l2_ctrl_new_std(hdl, &tw68_ctrl_ops,
938 V4L2_CID_HUE, -128, 127, 1, 0);
939 v4l2_ctrl_new_std(hdl, &tw68_ctrl_ops,
940 V4L2_CID_COLOR_KILLER, 0, 1, 1, 0);
941 v4l2_ctrl_new_std(hdl, &tw68_ctrl_ops,
942 V4L2_CID_CHROMA_AGC, 0, 1, 1, 1);
943 if (hdl->error) {
944 v4l2_ctrl_handler_free(hdl);
945 return hdl->error;
946 }
947 dev->v4l2_dev.ctrl_handler = hdl;
948 v4l2_ctrl_handler_setup(hdl);
5740f4e7
HV
949 return 0;
950}
951
e15d1c12 952int tw68_video_init2(struct tw68_dev *dev, int video_nr)
5740f4e7 953{
e15d1c12
HV
954 int ret;
955
5740f4e7 956 set_tvnorm(dev, &tvnorms[0]);
5740f4e7 957
e15d1c12
HV
958 dev->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24);
959 dev->width = 720;
960 dev->height = 576;
961 dev->field = V4L2_FIELD_INTERLACED;
962
963 INIT_LIST_HEAD(&dev->active);
964 dev->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
965 dev->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
966 dev->vidq.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ | VB2_DMABUF;
967 dev->vidq.ops = &tw68_video_qops;
968 dev->vidq.mem_ops = &vb2_dma_sg_memops;
969 dev->vidq.drv_priv = dev;
d0164adc 970 dev->vidq.gfp_flags = __GFP_DMA32 | __GFP_KSWAPD_RECLAIM;
e15d1c12
HV
971 dev->vidq.buf_struct_size = sizeof(struct tw68_buf);
972 dev->vidq.lock = &dev->lock;
973 dev->vidq.min_buffers_needed = 2;
2bc46b3a 974 dev->vidq.dev = &dev->pci->dev;
e15d1c12
HV
975 ret = vb2_queue_init(&dev->vidq);
976 if (ret)
977 return ret;
978 dev->vdev = tw68_video_template;
979 dev->vdev.v4l2_dev = &dev->v4l2_dev;
980 dev->vdev.lock = &dev->lock;
981 dev->vdev.queue = &dev->vidq;
982 video_set_drvdata(&dev->vdev, dev);
983 return video_register_device(&dev->vdev, VFL_TYPE_GRABBER, video_nr);
5740f4e7
HV
984}
985
986/*
987 * tw68_irq_video_done
988 */
989void tw68_irq_video_done(struct tw68_dev *dev, unsigned long status)
990{
991 __u32 reg;
992
993 /* reset interrupts handled by this routine */
994 tw_writel(TW68_INTSTAT, status);
995 /*
996 * Check most likely first
997 *
998 * DMAPI shows we have reached the end of the risc code
999 * for the current buffer.
1000 */
1001 if (status & TW68_DMAPI) {
e15d1c12
HV
1002 struct tw68_buf *buf;
1003
5740f4e7 1004 spin_lock(&dev->slock);
e15d1c12
HV
1005 buf = list_entry(dev->active.next, struct tw68_buf, list);
1006 list_del(&buf->list);
5740f4e7 1007 spin_unlock(&dev->slock);
d6dd645e 1008 buf->vb.vb2_buf.timestamp = ktime_get_ns();
2d700715
JS
1009 buf->vb.field = dev->field;
1010 buf->vb.sequence = dev->seqnr++;
1011 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
5740f4e7
HV
1012 status &= ~(TW68_DMAPI);
1013 if (0 == status)
1014 return;
1015 }
e15d1c12
HV
1016 if (status & (TW68_VLOCK | TW68_HLOCK))
1017 dev_dbg(&dev->pci->dev, "Lost sync\n");
1018 if (status & TW68_PABORT)
1019 dev_err(&dev->pci->dev, "PABORT interrupt\n");
1020 if (status & TW68_DMAPERR)
1021 dev_err(&dev->pci->dev, "DMAPERR interrupt\n");
5740f4e7
HV
1022 /*
1023 * On TW6800, FDMIS is apparently generated if video input is switched
1024 * during operation. Therefore, it is not enabled for that chip.
1025 */
e15d1c12
HV
1026 if (status & TW68_FDMIS)
1027 dev_dbg(&dev->pci->dev, "FDMIS interrupt\n");
1028 if (status & TW68_FFOF) {
1029 /* probably a logic error */
5740f4e7
HV
1030 reg = tw_readl(TW68_DMAC) & TW68_FIFO_EN;
1031 tw_clearl(TW68_DMAC, TW68_FIFO_EN);
e15d1c12 1032 dev_dbg(&dev->pci->dev, "FFOF interrupt\n");
5740f4e7
HV
1033 tw_setl(TW68_DMAC, reg);
1034 }
1035 if (status & TW68_FFERR)
e15d1c12 1036 dev_dbg(&dev->pci->dev, "FFERR interrupt\n");
5740f4e7 1037}