blob: c0d2a9bd5414eb1105c7ad6100784809d14928c0 [file] [log] [blame]
Ezequiel Garcia704a84c2016-03-02 11:30:16 -03001/*
2 * Copyright (C) 2015 VanguardiaSur - www.vanguardiasur.com.ar
3 *
4 * Based on original driver by Krzysztof Ha?asa:
5 * Copyright (C) 2015 Industrial Research Institute for Automation
6 * and Measurements PIAP
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of version 2 of the GNU General Public License
10 * as published by the Free Software Foundation.
11 *
12 */
13
14#include <linux/init.h>
15#include <linux/delay.h>
16#include <linux/list.h>
17#include <linux/module.h>
18#include <linux/kernel.h>
19#include <linux/slab.h>
20#include <media/v4l2-common.h>
21#include <media/v4l2-event.h>
22#include <media/videobuf2-vmalloc.h>
23#include "tw686x.h"
24#include "tw686x-regs.h"
25
26#define TW686X_INPUTS_PER_CH 4
27#define TW686X_VIDEO_WIDTH 720
Hans Verkuilbde56982016-04-21 03:23:58 -030028#define TW686X_VIDEO_HEIGHT(id) ((id & V4L2_STD_525_60) ? 480 : 576)
Ezequiel Garcia704a84c2016-03-02 11:30:16 -030029
30static const struct tw686x_format formats[] = {
31 {
32 .fourcc = V4L2_PIX_FMT_UYVY,
33 .mode = 0,
34 .depth = 16,
35 }, {
36 .fourcc = V4L2_PIX_FMT_RGB565,
37 .mode = 5,
38 .depth = 16,
39 }, {
40 .fourcc = V4L2_PIX_FMT_YUYV,
41 .mode = 6,
42 .depth = 16,
43 }
44};
45
Ezequiel Garciaf8afaa82016-06-04 20:47:15 -030046static void tw686x_buf_done(struct tw686x_video_channel *vc,
47 unsigned int pb)
48{
49 struct tw686x_dma_desc *desc = &vc->dma_descs[pb];
50 struct tw686x_dev *dev = vc->dev;
51 struct vb2_v4l2_buffer *vb;
52 struct vb2_buffer *vb2_buf;
53
54 if (vc->curr_bufs[pb]) {
55 vb = &vc->curr_bufs[pb]->vb;
56
57 vb->field = dev->dma_ops->field;
58 vb->sequence = vc->sequence++;
59 vb2_buf = &vb->vb2_buf;
60
61 if (dev->dma_mode == TW686X_DMA_MODE_MEMCPY)
62 memcpy(vb2_plane_vaddr(vb2_buf, 0), desc->virt,
63 desc->size);
64 vb2_buf->timestamp = ktime_get_ns();
65 vb2_buffer_done(vb2_buf, VB2_BUF_STATE_DONE);
66 }
67
68 vc->pb = !pb;
69}
70
71/*
72 * We can call this even when alloc_dma failed for the given channel
73 */
74static void tw686x_memcpy_dma_free(struct tw686x_video_channel *vc,
75 unsigned int pb)
76{
77 struct tw686x_dma_desc *desc = &vc->dma_descs[pb];
78 struct tw686x_dev *dev = vc->dev;
79 struct pci_dev *pci_dev;
80 unsigned long flags;
81
82 /* Check device presence. Shouldn't really happen! */
83 spin_lock_irqsave(&dev->lock, flags);
84 pci_dev = dev->pci_dev;
85 spin_unlock_irqrestore(&dev->lock, flags);
86 if (!pci_dev) {
87 WARN(1, "trying to deallocate on missing device\n");
88 return;
89 }
90
91 if (desc->virt) {
92 pci_free_consistent(dev->pci_dev, desc->size,
93 desc->virt, desc->phys);
94 desc->virt = NULL;
95 }
96}
97
98static int tw686x_memcpy_dma_alloc(struct tw686x_video_channel *vc,
99 unsigned int pb)
100{
101 struct tw686x_dev *dev = vc->dev;
102 u32 reg = pb ? VDMA_B_ADDR[vc->ch] : VDMA_P_ADDR[vc->ch];
103 unsigned int len;
104 void *virt;
105
106 WARN(vc->dma_descs[pb].virt,
107 "Allocating buffer but previous still here\n");
108
109 len = (vc->width * vc->height * vc->format->depth) >> 3;
110 virt = pci_alloc_consistent(dev->pci_dev, len,
111 &vc->dma_descs[pb].phys);
112 if (!virt) {
113 v4l2_err(&dev->v4l2_dev,
114 "dma%d: unable to allocate %s-buffer\n",
115 vc->ch, pb ? "B" : "P");
116 return -ENOMEM;
117 }
118 vc->dma_descs[pb].size = len;
119 vc->dma_descs[pb].virt = virt;
120 reg_write(dev, reg, vc->dma_descs[pb].phys);
121
122 return 0;
123}
124
125static void tw686x_memcpy_buf_refill(struct tw686x_video_channel *vc,
126 unsigned int pb)
127{
128 struct tw686x_v4l2_buf *buf;
129
130 while (!list_empty(&vc->vidq_queued)) {
131
132 buf = list_first_entry(&vc->vidq_queued,
133 struct tw686x_v4l2_buf, list);
134 list_del(&buf->list);
135
136 vc->curr_bufs[pb] = buf;
137 return;
138 }
139 vc->curr_bufs[pb] = NULL;
140}
141
142const struct tw686x_dma_ops memcpy_dma_ops = {
143 .alloc = tw686x_memcpy_dma_alloc,
144 .free = tw686x_memcpy_dma_free,
145 .buf_refill = tw686x_memcpy_buf_refill,
146 .mem_ops = &vb2_vmalloc_memops,
147 .hw_dma_mode = TW686X_FRAME_MODE,
148 .field = V4L2_FIELD_INTERLACED,
149};
150
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300151static unsigned int tw686x_fields_map(v4l2_std_id std, unsigned int fps)
152{
153 static const unsigned int map[15] = {
154 0x00000000, 0x00000001, 0x00004001, 0x00104001, 0x00404041,
155 0x01041041, 0x01104411, 0x01111111, 0x04444445, 0x04511445,
156 0x05145145, 0x05151515, 0x05515455, 0x05551555, 0x05555555
157 };
158
159 static const unsigned int std_625_50[26] = {
160 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7,
161 8, 8, 9, 10, 10, 11, 11, 12, 13, 13, 14, 14, 0
162 };
163
164 static const unsigned int std_525_60[31] = {
165 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
166 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 0, 0
167 };
168
Mauro Carvalho Chehab363d79f2016-04-23 06:21:09 -0300169 unsigned int i;
170
171 if (std & V4L2_STD_525_60) {
Mauro Carvalho Chehab45c175c2016-04-26 06:33:06 -0300172 if (fps >= ARRAY_SIZE(std_525_60))
Mauro Carvalho Chehab363d79f2016-04-23 06:21:09 -0300173 fps = 30;
174 i = std_525_60[fps];
175 } else {
Mauro Carvalho Chehab45c175c2016-04-26 06:33:06 -0300176 if (fps >= ARRAY_SIZE(std_625_50))
Mauro Carvalho Chehab363d79f2016-04-23 06:21:09 -0300177 fps = 25;
178 i = std_625_50[fps];
179 }
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300180
181 return map[i];
182}
183
184static void tw686x_set_framerate(struct tw686x_video_channel *vc,
185 unsigned int fps)
186{
187 unsigned int map;
188
189 if (vc->fps == fps)
190 return;
191
192 map = tw686x_fields_map(vc->video_standard, fps) << 1;
193 map |= map << 1;
194 if (map > 0)
195 map |= BIT(31);
196 reg_write(vc->dev, VIDEO_FIELD_CTRL[vc->ch], map);
197 vc->fps = fps;
198}
199
200static const struct tw686x_format *format_by_fourcc(unsigned int fourcc)
201{
202 unsigned int cnt;
203
204 for (cnt = 0; cnt < ARRAY_SIZE(formats); cnt++)
205 if (formats[cnt].fourcc == fourcc)
206 return &formats[cnt];
207 return NULL;
208}
209
210static int tw686x_queue_setup(struct vb2_queue *vq,
211 unsigned int *nbuffers, unsigned int *nplanes,
212 unsigned int sizes[], void *alloc_ctxs[])
213{
214 struct tw686x_video_channel *vc = vb2_get_drv_priv(vq);
215 unsigned int szimage =
216 (vc->width * vc->height * vc->format->depth) >> 3;
217
218 /*
219 * Let's request at least three buffers: two for the
220 * DMA engine and one for userspace.
221 */
222 if (vq->num_buffers + *nbuffers < 3)
223 *nbuffers = 3 - vq->num_buffers;
224
225 if (*nplanes) {
226 if (*nplanes != 1 || sizes[0] < szimage)
227 return -EINVAL;
228 return 0;
229 }
230
Ezequiel Garciaf8afaa82016-06-04 20:47:15 -0300231 alloc_ctxs[0] = vc->dev->alloc_ctx;
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300232 sizes[0] = szimage;
233 *nplanes = 1;
234 return 0;
235}
236
237static void tw686x_buf_queue(struct vb2_buffer *vb)
238{
239 struct tw686x_video_channel *vc = vb2_get_drv_priv(vb->vb2_queue);
240 struct tw686x_dev *dev = vc->dev;
241 struct pci_dev *pci_dev;
242 unsigned long flags;
243 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
244 struct tw686x_v4l2_buf *buf =
245 container_of(vbuf, struct tw686x_v4l2_buf, vb);
246
247 /* Check device presence */
248 spin_lock_irqsave(&dev->lock, flags);
249 pci_dev = dev->pci_dev;
250 spin_unlock_irqrestore(&dev->lock, flags);
251 if (!pci_dev) {
252 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
253 return;
254 }
255
256 spin_lock_irqsave(&vc->qlock, flags);
257 list_add_tail(&buf->list, &vc->vidq_queued);
258 spin_unlock_irqrestore(&vc->qlock, flags);
259}
260
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300261static void tw686x_clear_queue(struct tw686x_video_channel *vc,
262 enum vb2_buffer_state state)
263{
264 unsigned int pb;
265
266 while (!list_empty(&vc->vidq_queued)) {
267 struct tw686x_v4l2_buf *buf;
268
269 buf = list_first_entry(&vc->vidq_queued,
270 struct tw686x_v4l2_buf, list);
271 list_del(&buf->list);
272 vb2_buffer_done(&buf->vb.vb2_buf, state);
273 }
274
275 for (pb = 0; pb < 2; pb++) {
276 if (vc->curr_bufs[pb])
277 vb2_buffer_done(&vc->curr_bufs[pb]->vb.vb2_buf, state);
278 vc->curr_bufs[pb] = NULL;
279 }
280}
281
282static int tw686x_start_streaming(struct vb2_queue *vq, unsigned int count)
283{
284 struct tw686x_video_channel *vc = vb2_get_drv_priv(vq);
285 struct tw686x_dev *dev = vc->dev;
286 struct pci_dev *pci_dev;
287 unsigned long flags;
288 int pb, err;
289
290 /* Check device presence */
291 spin_lock_irqsave(&dev->lock, flags);
292 pci_dev = dev->pci_dev;
293 spin_unlock_irqrestore(&dev->lock, flags);
294 if (!pci_dev) {
295 err = -ENODEV;
296 goto err_clear_queue;
297 }
298
299 spin_lock_irqsave(&vc->qlock, flags);
300
301 /* Sanity check */
Ezequiel Garciaf8afaa82016-06-04 20:47:15 -0300302 if (dev->dma_mode == TW686X_DMA_MODE_MEMCPY &&
303 (!vc->dma_descs[0].virt || !vc->dma_descs[1].virt)) {
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300304 spin_unlock_irqrestore(&vc->qlock, flags);
305 v4l2_err(&dev->v4l2_dev,
306 "video%d: refusing to start without DMA buffers\n",
307 vc->num);
308 err = -ENOMEM;
309 goto err_clear_queue;
310 }
311
312 for (pb = 0; pb < 2; pb++)
Ezequiel Garciaf8afaa82016-06-04 20:47:15 -0300313 dev->dma_ops->buf_refill(vc, pb);
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300314 spin_unlock_irqrestore(&vc->qlock, flags);
315
316 vc->sequence = 0;
317 vc->pb = 0;
318
319 spin_lock_irqsave(&dev->lock, flags);
320 tw686x_enable_channel(dev, vc->ch);
321 spin_unlock_irqrestore(&dev->lock, flags);
322
323 mod_timer(&dev->dma_delay_timer, jiffies + msecs_to_jiffies(100));
324
325 return 0;
326
327err_clear_queue:
328 spin_lock_irqsave(&vc->qlock, flags);
329 tw686x_clear_queue(vc, VB2_BUF_STATE_QUEUED);
330 spin_unlock_irqrestore(&vc->qlock, flags);
331 return err;
332}
333
334static void tw686x_stop_streaming(struct vb2_queue *vq)
335{
336 struct tw686x_video_channel *vc = vb2_get_drv_priv(vq);
337 struct tw686x_dev *dev = vc->dev;
338 struct pci_dev *pci_dev;
339 unsigned long flags;
340
341 /* Check device presence */
342 spin_lock_irqsave(&dev->lock, flags);
343 pci_dev = dev->pci_dev;
344 spin_unlock_irqrestore(&dev->lock, flags);
345 if (pci_dev)
346 tw686x_disable_channel(dev, vc->ch);
347
348 spin_lock_irqsave(&vc->qlock, flags);
349 tw686x_clear_queue(vc, VB2_BUF_STATE_ERROR);
350 spin_unlock_irqrestore(&vc->qlock, flags);
351}
352
353static int tw686x_buf_prepare(struct vb2_buffer *vb)
354{
355 struct tw686x_video_channel *vc = vb2_get_drv_priv(vb->vb2_queue);
356 unsigned int size =
357 (vc->width * vc->height * vc->format->depth) >> 3;
358
359 if (vb2_plane_size(vb, 0) < size)
360 return -EINVAL;
361 vb2_set_plane_payload(vb, 0, size);
362 return 0;
363}
364
365static struct vb2_ops tw686x_video_qops = {
366 .queue_setup = tw686x_queue_setup,
367 .buf_queue = tw686x_buf_queue,
368 .buf_prepare = tw686x_buf_prepare,
369 .start_streaming = tw686x_start_streaming,
370 .stop_streaming = tw686x_stop_streaming,
371 .wait_prepare = vb2_ops_wait_prepare,
372 .wait_finish = vb2_ops_wait_finish,
373};
374
375static int tw686x_s_ctrl(struct v4l2_ctrl *ctrl)
376{
377 struct tw686x_video_channel *vc;
378 struct tw686x_dev *dev;
379 unsigned int ch;
380
381 vc = container_of(ctrl->handler, struct tw686x_video_channel,
382 ctrl_handler);
383 dev = vc->dev;
384 ch = vc->ch;
385
386 switch (ctrl->id) {
387 case V4L2_CID_BRIGHTNESS:
388 reg_write(dev, BRIGHT[ch], ctrl->val & 0xff);
389 return 0;
390
391 case V4L2_CID_CONTRAST:
392 reg_write(dev, CONTRAST[ch], ctrl->val);
393 return 0;
394
395 case V4L2_CID_SATURATION:
396 reg_write(dev, SAT_U[ch], ctrl->val);
397 reg_write(dev, SAT_V[ch], ctrl->val);
398 return 0;
399
400 case V4L2_CID_HUE:
401 reg_write(dev, HUE[ch], ctrl->val & 0xff);
402 return 0;
403 }
404
405 return -EINVAL;
406}
407
408static const struct v4l2_ctrl_ops ctrl_ops = {
409 .s_ctrl = tw686x_s_ctrl,
410};
411
412static int tw686x_g_fmt_vid_cap(struct file *file, void *priv,
413 struct v4l2_format *f)
414{
415 struct tw686x_video_channel *vc = video_drvdata(file);
Ezequiel Garciaf8afaa82016-06-04 20:47:15 -0300416 struct tw686x_dev *dev = vc->dev;
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300417
418 f->fmt.pix.width = vc->width;
419 f->fmt.pix.height = vc->height;
Ezequiel Garciaf8afaa82016-06-04 20:47:15 -0300420 f->fmt.pix.field = dev->dma_ops->field;
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300421 f->fmt.pix.pixelformat = vc->format->fourcc;
422 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
423 f->fmt.pix.bytesperline = (f->fmt.pix.width * vc->format->depth) / 8;
424 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
425 return 0;
426}
427
428static int tw686x_try_fmt_vid_cap(struct file *file, void *priv,
429 struct v4l2_format *f)
430{
431 struct tw686x_video_channel *vc = video_drvdata(file);
Ezequiel Garciaf8afaa82016-06-04 20:47:15 -0300432 struct tw686x_dev *dev = vc->dev;
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300433 unsigned int video_height = TW686X_VIDEO_HEIGHT(vc->video_standard);
434 const struct tw686x_format *format;
435
436 format = format_by_fourcc(f->fmt.pix.pixelformat);
437 if (!format) {
438 format = &formats[0];
439 f->fmt.pix.pixelformat = format->fourcc;
440 }
441
442 if (f->fmt.pix.width <= TW686X_VIDEO_WIDTH / 2)
443 f->fmt.pix.width = TW686X_VIDEO_WIDTH / 2;
444 else
445 f->fmt.pix.width = TW686X_VIDEO_WIDTH;
446
447 if (f->fmt.pix.height <= video_height / 2)
448 f->fmt.pix.height = video_height / 2;
449 else
450 f->fmt.pix.height = video_height;
451
452 f->fmt.pix.bytesperline = (f->fmt.pix.width * format->depth) / 8;
453 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
454 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
Ezequiel Garciaf8afaa82016-06-04 20:47:15 -0300455 f->fmt.pix.field = dev->dma_ops->field;
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300456
457 return 0;
458}
459
460static int tw686x_s_fmt_vid_cap(struct file *file, void *priv,
461 struct v4l2_format *f)
462{
463 struct tw686x_video_channel *vc = video_drvdata(file);
Ezequiel Garciaf8afaa82016-06-04 20:47:15 -0300464 struct tw686x_dev *dev = vc->dev;
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300465 u32 val, width, line_width, height;
466 unsigned long bitsperframe;
467 int err, pb;
468
469 if (vb2_is_busy(&vc->vidq))
470 return -EBUSY;
471
472 bitsperframe = vc->width * vc->height * vc->format->depth;
473 err = tw686x_try_fmt_vid_cap(file, priv, f);
474 if (err)
475 return err;
476
477 vc->format = format_by_fourcc(f->fmt.pix.pixelformat);
478 vc->width = f->fmt.pix.width;
479 vc->height = f->fmt.pix.height;
480
481 /* We need new DMA buffers if the framesize has changed */
Ezequiel Garciaf8afaa82016-06-04 20:47:15 -0300482 if (dev->dma_ops->alloc &&
483 bitsperframe != vc->width * vc->height * vc->format->depth) {
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300484 for (pb = 0; pb < 2; pb++)
Ezequiel Garciaf8afaa82016-06-04 20:47:15 -0300485 dev->dma_ops->free(vc, pb);
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300486
487 for (pb = 0; pb < 2; pb++) {
Ezequiel Garciaf8afaa82016-06-04 20:47:15 -0300488 err = dev->dma_ops->alloc(vc, pb);
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300489 if (err) {
490 if (pb > 0)
Ezequiel Garciaf8afaa82016-06-04 20:47:15 -0300491 dev->dma_ops->free(vc, 0);
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300492 return err;
493 }
494 }
495 }
496
497 val = reg_read(vc->dev, VDMA_CHANNEL_CONFIG[vc->ch]);
498
499 if (vc->width <= TW686X_VIDEO_WIDTH / 2)
500 val |= BIT(23);
501 else
502 val &= ~BIT(23);
503
504 if (vc->height <= TW686X_VIDEO_HEIGHT(vc->video_standard) / 2)
505 val |= BIT(24);
506 else
507 val &= ~BIT(24);
508
509 val &= ~(0x7 << 20);
510 val |= vc->format->mode << 20;
511 reg_write(vc->dev, VDMA_CHANNEL_CONFIG[vc->ch], val);
512
513 /* Program the DMA frame size */
514 width = (vc->width * 2) & 0x7ff;
515 height = vc->height / 2;
516 line_width = (vc->width * 2) & 0x7ff;
517 val = (height << 22) | (line_width << 11) | width;
518 reg_write(vc->dev, VDMA_WHP[vc->ch], val);
519 return 0;
520}
521
522static int tw686x_querycap(struct file *file, void *priv,
523 struct v4l2_capability *cap)
524{
525 struct tw686x_video_channel *vc = video_drvdata(file);
526 struct tw686x_dev *dev = vc->dev;
527
528 strlcpy(cap->driver, "tw686x", sizeof(cap->driver));
529 strlcpy(cap->card, dev->name, sizeof(cap->card));
530 snprintf(cap->bus_info, sizeof(cap->bus_info),
531 "PCI:%s", pci_name(dev->pci_dev));
532 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING |
533 V4L2_CAP_READWRITE;
534 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
535 return 0;
536}
537
538static int tw686x_s_std(struct file *file, void *priv, v4l2_std_id id)
539{
540 struct tw686x_video_channel *vc = video_drvdata(file);
541 struct v4l2_format f;
542 u32 val, ret;
543
544 if (vc->video_standard == id)
545 return 0;
546
547 if (vb2_is_busy(&vc->vidq))
548 return -EBUSY;
549
550 if (id & V4L2_STD_NTSC)
551 val = 0;
552 else if (id & V4L2_STD_PAL)
553 val = 1;
554 else if (id & V4L2_STD_SECAM)
555 val = 2;
556 else if (id & V4L2_STD_NTSC_443)
557 val = 3;
558 else if (id & V4L2_STD_PAL_M)
559 val = 4;
560 else if (id & V4L2_STD_PAL_Nc)
561 val = 5;
562 else if (id & V4L2_STD_PAL_60)
563 val = 6;
564 else
565 return -EINVAL;
566
567 vc->video_standard = id;
568 reg_write(vc->dev, SDT[vc->ch], val);
569
570 val = reg_read(vc->dev, VIDEO_CONTROL1);
Hans Verkuilbde56982016-04-21 03:23:58 -0300571 if (id & V4L2_STD_525_60)
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300572 val &= ~(1 << (SYS_MODE_DMA_SHIFT + vc->ch));
Hans Verkuilbde56982016-04-21 03:23:58 -0300573 else
574 val |= (1 << (SYS_MODE_DMA_SHIFT + vc->ch));
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300575 reg_write(vc->dev, VIDEO_CONTROL1, val);
576
577 /*
578 * Adjust format after V4L2_STD_525_60/V4L2_STD_625_50 change,
579 * calling g_fmt and s_fmt will sanitize the height
580 * according to the standard.
581 */
582 ret = tw686x_g_fmt_vid_cap(file, priv, &f);
583 if (!ret)
584 tw686x_s_fmt_vid_cap(file, priv, &f);
585 return 0;
586}
587
588static int tw686x_querystd(struct file *file, void *priv, v4l2_std_id *std)
589{
590 struct tw686x_video_channel *vc = video_drvdata(file);
591 struct tw686x_dev *dev = vc->dev;
592 unsigned int old_std, detected_std = 0;
593 unsigned long end;
594
595 if (vb2_is_streaming(&vc->vidq))
596 return -EBUSY;
597
598 /* Enable and start standard detection */
599 old_std = reg_read(dev, SDT[vc->ch]);
600 reg_write(dev, SDT[vc->ch], 0x7);
601 reg_write(dev, SDT_EN[vc->ch], 0xff);
602
603 end = jiffies + msecs_to_jiffies(500);
604 while (time_is_after_jiffies(end)) {
605
606 detected_std = reg_read(dev, SDT[vc->ch]);
607 if (!(detected_std & BIT(7)))
608 break;
609 msleep(100);
610 }
611 reg_write(dev, SDT[vc->ch], old_std);
612
613 /* Exit if still busy */
614 if (detected_std & BIT(7))
615 return 0;
616
617 detected_std = (detected_std >> 4) & 0x7;
618 switch (detected_std) {
619 case TW686X_STD_NTSC_M:
620 *std &= V4L2_STD_NTSC;
621 break;
622 case TW686X_STD_NTSC_443:
623 *std &= V4L2_STD_NTSC_443;
624 break;
625 case TW686X_STD_PAL_M:
626 *std &= V4L2_STD_PAL_M;
627 break;
628 case TW686X_STD_PAL_60:
629 *std &= V4L2_STD_PAL_60;
630 break;
631 case TW686X_STD_PAL:
632 *std &= V4L2_STD_PAL;
633 break;
634 case TW686X_STD_PAL_CN:
635 *std &= V4L2_STD_PAL_Nc;
636 break;
637 case TW686X_STD_SECAM:
638 *std &= V4L2_STD_SECAM;
639 break;
640 default:
641 *std = 0;
642 }
643 return 0;
644}
645
646static int tw686x_g_std(struct file *file, void *priv, v4l2_std_id *id)
647{
648 struct tw686x_video_channel *vc = video_drvdata(file);
649
650 *id = vc->video_standard;
651 return 0;
652}
653
654static int tw686x_enum_fmt_vid_cap(struct file *file, void *priv,
655 struct v4l2_fmtdesc *f)
656{
657 if (f->index >= ARRAY_SIZE(formats))
658 return -EINVAL;
659 f->pixelformat = formats[f->index].fourcc;
660 return 0;
661}
662
663static int tw686x_s_input(struct file *file, void *priv, unsigned int i)
664{
665 struct tw686x_video_channel *vc = video_drvdata(file);
666 u32 val;
667
668 if (i >= TW686X_INPUTS_PER_CH)
669 return -EINVAL;
670 if (i == vc->input)
671 return 0;
672 /*
673 * Not sure we are able to support on the fly input change
674 */
675 if (vb2_is_busy(&vc->vidq))
676 return -EBUSY;
677
678 vc->input = i;
679
680 val = reg_read(vc->dev, VDMA_CHANNEL_CONFIG[vc->ch]);
681 val &= ~(0x3 << 30);
682 val |= i << 30;
683 reg_write(vc->dev, VDMA_CHANNEL_CONFIG[vc->ch], val);
684 return 0;
685}
686
687static int tw686x_g_input(struct file *file, void *priv, unsigned int *i)
688{
689 struct tw686x_video_channel *vc = video_drvdata(file);
690
691 *i = vc->input;
692 return 0;
693}
694
695static int tw686x_enum_input(struct file *file, void *priv,
696 struct v4l2_input *i)
697{
698 struct tw686x_video_channel *vc = video_drvdata(file);
699 unsigned int vidstat;
700
701 if (i->index >= TW686X_INPUTS_PER_CH)
702 return -EINVAL;
703
704 snprintf(i->name, sizeof(i->name), "Composite%d", i->index);
705 i->type = V4L2_INPUT_TYPE_CAMERA;
706 i->std = vc->device->tvnorms;
707 i->capabilities = V4L2_IN_CAP_STD;
708
709 vidstat = reg_read(vc->dev, VIDSTAT[vc->ch]);
710 i->status = 0;
711 if (vidstat & TW686X_VIDSTAT_VDLOSS)
712 i->status |= V4L2_IN_ST_NO_SIGNAL;
713 if (!(vidstat & TW686X_VIDSTAT_HLOCK))
714 i->status |= V4L2_IN_ST_NO_H_LOCK;
715
716 return 0;
717}
718
Hans Verkuil2e2dedb2016-03-21 12:09:59 -0300719static const struct v4l2_file_operations tw686x_video_fops = {
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300720 .owner = THIS_MODULE,
721 .open = v4l2_fh_open,
722 .unlocked_ioctl = video_ioctl2,
723 .release = vb2_fop_release,
724 .poll = vb2_fop_poll,
725 .read = vb2_fop_read,
726 .mmap = vb2_fop_mmap,
727};
728
Hans Verkuil2e2dedb2016-03-21 12:09:59 -0300729static const struct v4l2_ioctl_ops tw686x_video_ioctl_ops = {
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300730 .vidioc_querycap = tw686x_querycap,
731 .vidioc_g_fmt_vid_cap = tw686x_g_fmt_vid_cap,
732 .vidioc_s_fmt_vid_cap = tw686x_s_fmt_vid_cap,
733 .vidioc_enum_fmt_vid_cap = tw686x_enum_fmt_vid_cap,
734 .vidioc_try_fmt_vid_cap = tw686x_try_fmt_vid_cap,
735
736 .vidioc_querystd = tw686x_querystd,
737 .vidioc_g_std = tw686x_g_std,
738 .vidioc_s_std = tw686x_s_std,
739
740 .vidioc_enum_input = tw686x_enum_input,
741 .vidioc_g_input = tw686x_g_input,
742 .vidioc_s_input = tw686x_s_input,
743
744 .vidioc_reqbufs = vb2_ioctl_reqbufs,
745 .vidioc_querybuf = vb2_ioctl_querybuf,
746 .vidioc_qbuf = vb2_ioctl_qbuf,
747 .vidioc_dqbuf = vb2_ioctl_dqbuf,
748 .vidioc_create_bufs = vb2_ioctl_create_bufs,
749 .vidioc_streamon = vb2_ioctl_streamon,
750 .vidioc_streamoff = vb2_ioctl_streamoff,
751 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
752
753 .vidioc_log_status = v4l2_ctrl_log_status,
754 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
755 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
756};
757
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300758void tw686x_video_irq(struct tw686x_dev *dev, unsigned long requests,
759 unsigned int pb_status, unsigned int fifo_status,
760 unsigned int *reset_ch)
761{
762 struct tw686x_video_channel *vc;
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300763 unsigned long flags;
764 unsigned int ch, pb;
765
766 for_each_set_bit(ch, &requests, max_channels(dev)) {
767 vc = &dev->video_channels[ch];
768
769 /*
770 * This can either be a blue frame (with signal-lost bit set)
771 * or a good frame (with signal-lost bit clear). If we have just
772 * got signal, then this channel needs resetting.
773 */
774 if (vc->no_signal && !(fifo_status & BIT(ch))) {
775 v4l2_printk(KERN_DEBUG, &dev->v4l2_dev,
776 "video%d: signal recovered\n", vc->num);
777 vc->no_signal = false;
778 *reset_ch |= BIT(ch);
779 vc->pb = 0;
780 continue;
781 }
782 vc->no_signal = !!(fifo_status & BIT(ch));
783
784 /* Check FIFO errors only if there's signal */
785 if (!vc->no_signal) {
786 u32 fifo_ov, fifo_bad;
787
788 fifo_ov = (fifo_status >> 24) & BIT(ch);
789 fifo_bad = (fifo_status >> 16) & BIT(ch);
790 if (fifo_ov || fifo_bad) {
791 /* Mark this channel for reset */
792 v4l2_printk(KERN_DEBUG, &dev->v4l2_dev,
793 "video%d: FIFO error\n", vc->num);
794 *reset_ch |= BIT(ch);
795 vc->pb = 0;
796 continue;
797 }
798 }
799
800 pb = !!(pb_status & BIT(ch));
801 if (vc->pb != pb) {
802 /* Mark this channel for reset */
803 v4l2_printk(KERN_DEBUG, &dev->v4l2_dev,
804 "video%d: unexpected p-b buffer!\n",
805 vc->num);
806 *reset_ch |= BIT(ch);
807 vc->pb = 0;
808 continue;
809 }
810
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300811 spin_lock_irqsave(&vc->qlock, flags);
Ezequiel Garciaf8afaa82016-06-04 20:47:15 -0300812 tw686x_buf_done(vc, pb);
813 dev->dma_ops->buf_refill(vc, pb);
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300814 spin_unlock_irqrestore(&vc->qlock, flags);
815 }
816}
817
818void tw686x_video_free(struct tw686x_dev *dev)
819{
820 unsigned int ch, pb;
821
822 for (ch = 0; ch < max_channels(dev); ch++) {
823 struct tw686x_video_channel *vc = &dev->video_channels[ch];
824
825 if (vc->device)
826 video_unregister_device(vc->device);
827
Ezequiel Garciaf8afaa82016-06-04 20:47:15 -0300828 if (dev->dma_ops->free)
829 for (pb = 0; pb < 2; pb++)
830 dev->dma_ops->free(vc, pb);
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300831 }
Ezequiel Garciaf8afaa82016-06-04 20:47:15 -0300832
833 if (dev->dma_ops->cleanup)
834 dev->dma_ops->cleanup(dev);
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300835}
836
837int tw686x_video_init(struct tw686x_dev *dev)
838{
839 unsigned int ch, val, pb;
840 int err;
841
Ezequiel Garciaf8afaa82016-06-04 20:47:15 -0300842 if (dev->dma_mode == TW686X_DMA_MODE_MEMCPY)
843 dev->dma_ops = &memcpy_dma_ops;
844 else
845 return -EINVAL;
846
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300847 err = v4l2_device_register(&dev->pci_dev->dev, &dev->v4l2_dev);
848 if (err)
849 return err;
850
Ezequiel Garciaf8afaa82016-06-04 20:47:15 -0300851 if (dev->dma_ops->setup) {
852 err = dev->dma_ops->setup(dev);
853 if (err)
854 return err;
855 }
856
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300857 for (ch = 0; ch < max_channels(dev); ch++) {
858 struct tw686x_video_channel *vc = &dev->video_channels[ch];
859 struct video_device *vdev;
860
861 mutex_init(&vc->vb_mutex);
862 spin_lock_init(&vc->qlock);
863 INIT_LIST_HEAD(&vc->vidq_queued);
864
865 vc->dev = dev;
866 vc->ch = ch;
867
868 /* default settings */
869 vc->format = &formats[0];
870 vc->video_standard = V4L2_STD_NTSC;
871 vc->width = TW686X_VIDEO_WIDTH;
872 vc->height = TW686X_VIDEO_HEIGHT(vc->video_standard);
873 vc->input = 0;
874
875 reg_write(vc->dev, SDT[ch], 0);
876 tw686x_set_framerate(vc, 30);
877
878 reg_write(dev, VDELAY_LO[ch], 0x14);
879 reg_write(dev, HACTIVE_LO[ch], 0xd0);
880 reg_write(dev, VIDEO_SIZE[ch], 0);
881
Ezequiel Garciaf8afaa82016-06-04 20:47:15 -0300882 if (dev->dma_ops->alloc) {
883 for (pb = 0; pb < 2; pb++) {
884 err = dev->dma_ops->alloc(vc, pb);
885 if (err)
886 goto error;
887 }
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300888 }
889
890 vc->vidq.io_modes = VB2_READ | VB2_MMAP | VB2_DMABUF;
891 vc->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
892 vc->vidq.drv_priv = vc;
893 vc->vidq.buf_struct_size = sizeof(struct tw686x_v4l2_buf);
894 vc->vidq.ops = &tw686x_video_qops;
Ezequiel Garciaf8afaa82016-06-04 20:47:15 -0300895 vc->vidq.mem_ops = dev->dma_ops->mem_ops;
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300896 vc->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
897 vc->vidq.min_buffers_needed = 2;
898 vc->vidq.lock = &vc->vb_mutex;
Ezequiel Garcia1c9f47192016-04-01 19:38:21 -0300899 vc->vidq.gfp_flags = GFP_DMA32;
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300900
901 err = vb2_queue_init(&vc->vidq);
902 if (err) {
903 v4l2_err(&dev->v4l2_dev,
904 "dma%d: cannot init vb2 queue\n", ch);
905 goto error;
906 }
907
908 err = v4l2_ctrl_handler_init(&vc->ctrl_handler, 4);
909 if (err) {
910 v4l2_err(&dev->v4l2_dev,
911 "dma%d: cannot init ctrl handler\n", ch);
912 goto error;
913 }
914 v4l2_ctrl_new_std(&vc->ctrl_handler, &ctrl_ops,
915 V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
916 v4l2_ctrl_new_std(&vc->ctrl_handler, &ctrl_ops,
917 V4L2_CID_CONTRAST, 0, 255, 1, 100);
918 v4l2_ctrl_new_std(&vc->ctrl_handler, &ctrl_ops,
919 V4L2_CID_SATURATION, 0, 255, 1, 128);
920 v4l2_ctrl_new_std(&vc->ctrl_handler, &ctrl_ops,
921 V4L2_CID_HUE, -128, 127, 1, 0);
922 err = vc->ctrl_handler.error;
923 if (err)
924 goto error;
925
926 err = v4l2_ctrl_handler_setup(&vc->ctrl_handler);
927 if (err)
928 goto error;
929
930 vdev = video_device_alloc();
931 if (!vdev) {
932 v4l2_err(&dev->v4l2_dev,
933 "dma%d: unable to allocate device\n", ch);
934 err = -ENOMEM;
935 goto error;
936 }
937
938 snprintf(vdev->name, sizeof(vdev->name), "%s video", dev->name);
939 vdev->fops = &tw686x_video_fops;
940 vdev->ioctl_ops = &tw686x_video_ioctl_ops;
941 vdev->release = video_device_release;
942 vdev->v4l2_dev = &dev->v4l2_dev;
943 vdev->queue = &vc->vidq;
944 vdev->tvnorms = V4L2_STD_525_60 | V4L2_STD_625_50;
945 vdev->minor = -1;
946 vdev->lock = &vc->vb_mutex;
947 vdev->ctrl_handler = &vc->ctrl_handler;
948 vc->device = vdev;
949 video_set_drvdata(vdev, vc);
950
951 err = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
952 if (err < 0)
953 goto error;
954 vc->num = vdev->num;
955 }
956
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300957 val = TW686X_DEF_PHASE_REF;
958 for (ch = 0; ch < max_channels(dev); ch++)
Ezequiel Garciaf8afaa82016-06-04 20:47:15 -0300959 val |= dev->dma_ops->hw_dma_mode << (16 + ch * 2);
Ezequiel Garcia704a84c2016-03-02 11:30:16 -0300960 reg_write(dev, PHASE_REF, val);
961
962 reg_write(dev, MISC2[0], 0xe7);
963 reg_write(dev, VCTRL1[0], 0xcc);
964 reg_write(dev, LOOP[0], 0xa5);
965 if (max_channels(dev) > 4) {
966 reg_write(dev, VCTRL1[1], 0xcc);
967 reg_write(dev, LOOP[1], 0xa5);
968 reg_write(dev, MISC2[1], 0xe7);
969 }
970 return 0;
971
972error:
973 tw686x_video_free(dev);
974 return err;
975}