Lines Matching +full:capture +full:- +full:sd +full:- +full:lines
1 // SPDX-License-Identifier: GPL-2.0-only
5 * Derived from ivtv-ioctl.c and cx18-fileops.c
7 * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates.
11 #include <linux/dma-mapping.h>
15 #include <linux/v4l2-dv-timings.h>
17 #include <media/v4l2-ctrls.h>
18 #include <media/v4l2-event.h>
19 #include <media/v4l2-dv-timings.h>
23 #include "cobalt-alsa.h"
24 #include "cobalt-cpld.h"
25 #include "cobalt-driver.h"
26 #include "cobalt-v4l2.h"
27 #include "cobalt-irq.h"
28 #include "cobalt-omnitek.h"
38 struct cobalt_stream *s = q->drv_priv; in cobalt_queue_setup()
39 unsigned size = s->stride * s->height; in cobalt_queue_setup()
46 return sizes[0] < size ? -EINVAL : 0; in cobalt_queue_setup()
54 struct cobalt_stream *s = vb->vb2_queue->drv_priv; in cobalt_buf_init()
55 struct cobalt *cobalt = s->cobalt; in cobalt_buf_init()
61 struct sg_dma_desc_info *desc = &s->dma_desc_info[vb->index]; in cobalt_buf_init()
66 size = s->stride * s->height; in cobalt_buf_init()
70 return -EINVAL; in cobalt_buf_init()
73 if (desc->virt == NULL) { in cobalt_buf_init()
74 desc->dev = &cobalt->pci_dev->dev; in cobalt_buf_init()
76 s->is_audio ? audio_bytes : bytes); in cobalt_buf_init()
77 if (desc->virt == NULL) in cobalt_buf_init()
78 return -ENOMEM; in cobalt_buf_init()
80 ret = descriptor_list_create(cobalt, sg_desc->sgl, in cobalt_buf_init()
81 !s->is_output, sg_desc->nents, size, in cobalt_buf_init()
82 s->width * s->bpp, s->stride, desc); in cobalt_buf_init()
90 struct cobalt_stream *s = vb->vb2_queue->drv_priv; in cobalt_buf_cleanup()
91 struct sg_dma_desc_info *desc = &s->dma_desc_info[vb->index]; in cobalt_buf_cleanup()
99 struct cobalt_stream *s = vb->vb2_queue->drv_priv; in cobalt_buf_prepare()
101 vb2_set_plane_payload(vb, 0, s->stride * s->height); in cobalt_buf_prepare()
102 vbuf->field = V4L2_FIELD_NONE; in cobalt_buf_prepare()
112 list_for_each_entry(cb, &s->bufs, list) { in chain_all_buffers()
113 desc[i] = &s->dma_desc_info[cb->vb.vb2_buf.index]; in chain_all_buffers()
115 descriptor_list_chain(desc[i-1], desc[i]); in chain_all_buffers()
123 struct vb2_queue *q = vb->vb2_queue; in cobalt_buf_queue()
124 struct cobalt_stream *s = q->drv_priv; in cobalt_buf_queue()
126 struct sg_dma_desc_info *desc = &s->dma_desc_info[vb->index]; in cobalt_buf_queue()
133 spin_lock_irqsave(&s->irqlock, flags); in cobalt_buf_queue()
134 list_add_tail(&cb->list, &s->bufs); in cobalt_buf_queue()
136 spin_unlock_irqrestore(&s->irqlock, flags); in cobalt_buf_queue()
141 struct cobalt *cobalt = s->cobalt; in cobalt_enable_output()
142 struct v4l2_bt_timings *bt = &s->timings.bt; in cobalt_enable_output()
145 unsigned fmt = s->pixfmt != V4L2_PIX_FMT_BGR32 ? in cobalt_enable_output()
150 u64 clk = bt->pixelclock; in cobalt_enable_output()
152 if (bt->flags & V4L2_DV_FL_REDUCED_FPS) in cobalt_enable_output()
159 sd_fmt.format.colorspace = s->colorspace; in cobalt_enable_output()
160 sd_fmt.format.xfer_func = s->xfer_func; in cobalt_enable_output()
161 sd_fmt.format.ycbcr_enc = s->ycbcr_enc; in cobalt_enable_output()
162 sd_fmt.format.quantization = s->quantization; in cobalt_enable_output()
163 sd_fmt.format.width = bt->width; in cobalt_enable_output()
164 sd_fmt.format.height = bt->height; in cobalt_enable_output()
167 switch (s->pixfmt) { in cobalt_enable_output()
175 v4l2_subdev_call(s->sd, pad, set_fmt, NULL, &sd_fmt); in cobalt_enable_output()
177 iowrite32(0, &vo->control); in cobalt_enable_output()
179 iowrite32(bt->hsync, &vo->sync_generator_h_sync_length); in cobalt_enable_output()
180 iowrite32(bt->hbackporch, &vo->sync_generator_h_backporch_length); in cobalt_enable_output()
181 iowrite32(bt->width, &vo->sync_generator_h_active_length); in cobalt_enable_output()
182 iowrite32(bt->hfrontporch, &vo->sync_generator_h_frontporch_length); in cobalt_enable_output()
183 iowrite32(bt->vsync, &vo->sync_generator_v_sync_length); in cobalt_enable_output()
184 iowrite32(bt->vbackporch, &vo->sync_generator_v_backporch_length); in cobalt_enable_output()
185 iowrite32(bt->height, &vo->sync_generator_v_active_length); in cobalt_enable_output()
186 iowrite32(bt->vfrontporch, &vo->sync_generator_v_frontporch_length); in cobalt_enable_output()
187 iowrite32(0x9900c1, &vo->error_color); in cobalt_enable_output()
190 &vo->control); in cobalt_enable_output()
191 iowrite32(M00514_CONTROL_BITMAP_EVCNT_CLEAR_MSK | fmt, &vo->control); in cobalt_enable_output()
194 fmt, &vo->control); in cobalt_enable_output()
199 struct cobalt *cobalt = s->cobalt; in cobalt_enable_input()
200 int ch = (int)s->video_channel; in cobalt_enable_input()
203 .pad = s->pad_source, in cobalt_enable_input()
208 .pad = s->pad_source, in cobalt_enable_input()
214 s->video_channel, in cobalt_enable_input()
215 s->input == 0 ? "hdmi" : "generator", in cobalt_enable_input()
221 switch (s->pixfmt) { in cobalt_enable_input()
225 &packer->control); in cobalt_enable_input()
226 v4l2_subdev_call(s->sd, pad, set_fmt, NULL, in cobalt_enable_input()
232 &packer->control); in cobalt_enable_input()
233 v4l2_subdev_call(s->sd, pad, set_fmt, NULL, in cobalt_enable_input()
240 &packer->control); in cobalt_enable_input()
241 v4l2_subdev_call(s->sd, pad, set_fmt, NULL, in cobalt_enable_input()
249 struct cobalt *cobalt = s->cobalt; in cobalt_dma_start_streaming()
250 int rx = s->video_channel; in cobalt_dma_start_streaming()
256 spin_lock_irqsave(&s->irqlock, flags); in cobalt_dma_start_streaming()
257 if (!s->is_output) { in cobalt_dma_start_streaming()
258 iowrite32(M00460_CONTROL_BITMAP_CLEAR_MSK, &evcnt->control); in cobalt_dma_start_streaming()
259 iowrite32(M00460_CONTROL_BITMAP_ENABLE_MSK, &evcnt->control); in cobalt_dma_start_streaming()
263 u32 ctrl = ioread32(&vo->control); in cobalt_dma_start_streaming()
268 &vo->control); in cobalt_dma_start_streaming()
270 &vo->control); in cobalt_dma_start_streaming()
272 cb = list_first_entry(&s->bufs, struct cobalt_buffer, list); in cobalt_dma_start_streaming()
273 omni_sg_dma_start(s, &s->dma_desc_info[cb->vb.vb2_buf.index]); in cobalt_dma_start_streaming()
274 spin_unlock_irqrestore(&s->irqlock, flags); in cobalt_dma_start_streaming()
279 struct cobalt_stream *s = q->drv_priv; in cobalt_start_streaming()
280 struct cobalt *cobalt = s->cobalt; in cobalt_start_streaming()
284 int rx = s->video_channel; in cobalt_start_streaming()
287 struct v4l2_bt_timings *bt = &s->timings.bt; in cobalt_start_streaming()
291 if (s->is_audio) in cobalt_start_streaming()
293 if (s->is_output) { in cobalt_start_streaming()
294 s->unstable_frame = false; in cobalt_start_streaming()
305 iowrite32(M00460_CONTROL_BITMAP_CLEAR_MSK, &evcnt->control); in cobalt_start_streaming()
306 iowrite32(M00460_CONTROL_BITMAP_ENABLE_MSK, &evcnt->control); in cobalt_start_streaming()
307 iowrite32(bt->width, &cvi->frame_width); in cobalt_start_streaming()
308 iowrite32(bt->height, &cvi->frame_height); in cobalt_start_streaming()
311 bt->pixelclock), &vmr->hsync_timeout_val); in cobalt_start_streaming()
312 iowrite32(M00233_CONTROL_BITMAP_ENABLE_MEASURE_MSK, &vmr->control); in cobalt_start_streaming()
313 clk_freq = ioread32(&fw->clk_freq); in cobalt_start_streaming()
314 iowrite32(clk_freq / 1000000, &clkloss->ref_clk_cnt_val); in cobalt_start_streaming()
317 iowrite32(div_u64(bt->pixelclock * 995, 1000000000), in cobalt_start_streaming()
318 &clkloss->test_clk_cnt_val); in cobalt_start_streaming()
320 iowrite32(bt->width * bt->height, &fw->active_length); in cobalt_start_streaming()
321 iowrite32(div_u64((u64)clk_freq * tot_size, bt->pixelclock), in cobalt_start_streaming()
322 &fw->total_length); in cobalt_start_streaming()
325 &vmr->irq_triggers); in cobalt_start_streaming()
326 iowrite32(0, &cvi->control); in cobalt_start_streaming()
327 iowrite32(M00233_CONTROL_BITMAP_ENABLE_MEASURE_MSK, &vmr->control); in cobalt_start_streaming()
329 iowrite32(0xff, &fw->output_color); in cobalt_start_streaming()
330 iowrite32(M00479_CTRL_BITMAP_ENABLE_MSK, &clkloss->ctrl); in cobalt_start_streaming()
332 M00473_CTRL_BITMAP_FORCE_FREEWHEEL_MODE_MSK, &fw->ctrl); in cobalt_start_streaming()
333 s->unstable_frame = true; in cobalt_start_streaming()
334 s->enable_freewheel = false; in cobalt_start_streaming()
335 s->enable_cvi = false; in cobalt_start_streaming()
336 s->skip_first_frames = 0; in cobalt_start_streaming()
339 s->sequence = 0; in cobalt_start_streaming()
346 struct cobalt *cobalt = s->cobalt; in cobalt_dma_stop_streaming()
351 int rx = s->video_channel; in cobalt_dma_stop_streaming()
355 if (!s->is_output) { in cobalt_dma_stop_streaming()
356 iowrite32(0, &evcnt->control); in cobalt_dma_stop_streaming()
357 } else if (!s->is_audio) { in cobalt_dma_stop_streaming()
361 iowrite32(M00514_CONTROL_BITMAP_EVCNT_CLEAR_MSK, &vo->control); in cobalt_dma_stop_streaming()
362 iowrite32(0, &vo->control); in cobalt_dma_stop_streaming()
366 spin_lock_irqsave(&s->irqlock, flags); in cobalt_dma_stop_streaming()
367 list_for_each_entry(cb, &s->bufs, list) { in cobalt_dma_stop_streaming()
368 desc = &s->dma_desc_info[cb->vb.vb2_buf.index]; in cobalt_dma_stop_streaming()
372 spin_unlock_irqrestore(&s->irqlock, flags); in cobalt_dma_stop_streaming()
375 if (!wait_event_timeout(s->q.done_wq, is_dma_done(s), in cobalt_dma_stop_streaming()
381 1 << s->dma_channel); in cobalt_dma_stop_streaming()
386 struct cobalt_stream *s = q->drv_priv; in cobalt_stop_streaming()
387 struct cobalt *cobalt = s->cobalt; in cobalt_stop_streaming()
388 int rx = s->video_channel; in cobalt_stop_streaming()
399 spin_lock_irqsave(&s->irqlock, flags); in cobalt_stop_streaming()
400 list_for_each_safe(p, safe, &s->bufs) { in cobalt_stop_streaming()
402 list_del(&cb->list); in cobalt_stop_streaming()
403 vb2_buffer_done(&cb->vb.vb2_buf, VB2_BUF_STATE_ERROR); in cobalt_stop_streaming()
405 spin_unlock_irqrestore(&s->irqlock, flags); in cobalt_stop_streaming()
407 if (s->is_audio || s->is_output) in cobalt_stop_streaming()
413 iowrite32(0, &vmr->control); in cobalt_stop_streaming()
414 iowrite32(M00233_CONTROL_BITMAP_ENABLE_MEASURE_MSK, &vmr->control); in cobalt_stop_streaming()
415 iowrite32(0, &fw->ctrl); in cobalt_stop_streaming()
416 iowrite32(0, &clkloss->ctrl); in cobalt_stop_streaming()
435 void __iomem *adrs = cobalt->bar1 + regs->reg; in cobalt_cobaltc()
440 return -EPERM; in cobalt_cobaltc()
442 regs->size = 4; in cobalt_cobaltc()
444 iowrite32(regs->val, adrs); in cobalt_cobaltc()
446 regs->val = ioread32(adrs); in cobalt_cobaltc()
454 struct cobalt *cobalt = s->cobalt; in cobalt_g_register()
463 struct cobalt *cobalt = s->cobalt; in cobalt_s_register()
474 struct cobalt *cobalt = s->cobalt; in cobalt_querycap()
476 strscpy(vcap->driver, "cobalt", sizeof(vcap->driver)); in cobalt_querycap()
477 strscpy(vcap->card, "cobalt", sizeof(vcap->card)); in cobalt_querycap()
478 snprintf(vcap->bus_info, sizeof(vcap->bus_info), in cobalt_querycap()
479 "PCIe:%s", pci_name(cobalt->pci_dev)); in cobalt_querycap()
480 vcap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_READWRITE | in cobalt_querycap()
482 if (cobalt->have_hsma_tx) in cobalt_querycap()
483 vcap->capabilities |= V4L2_CAP_VIDEO_OUTPUT; in cobalt_querycap()
494 int rx = s->video_channel; in cobalt_video_input_status_show()
495 struct cobalt *cobalt = s->cobalt; in cobalt_video_input_status_show()
504 cvi_ctrl = ioread32(&cvi->control); in cobalt_video_input_status_show()
505 cvi_stat = ioread32(&cvi->status); in cobalt_video_input_status_show()
506 vmr_ctrl = ioread32(&vmr->control); in cobalt_video_input_status_show()
507 vmr_stat = ioread32(&vmr->status); in cobalt_video_input_status_show()
509 ioread32(&cvi->frame_width), ioread32(&cvi->frame_height)); in cobalt_video_input_status_show()
514 "HSync- " : "HSync+ ", in cobalt_video_input_status_show()
516 "VSync- " : "VSync+ "); in cobalt_video_input_status_show()
519 "lock " : "no-lock ", in cobalt_video_input_status_show()
521 "error " : "no-error "); in cobalt_video_input_status_show()
525 "HSync- " : "HSync+ ", in cobalt_video_input_status_show()
527 "VSync- " : "VSync+ ", in cobalt_video_input_status_show()
531 "irq-enabled " : "irq-disabled ", in cobalt_video_input_status_show()
533 "update-on-hsync " : "", in cobalt_video_input_status_show()
535 "hsync-timeout " : "", in cobalt_video_input_status_show()
537 "init-done" : ""); in cobalt_video_input_status_show()
539 ioread32(&vmr->irq_status) & 0xff, in cobalt_video_input_status_show()
540 ioread32(&vmr->irq_triggers) & 0xff); in cobalt_video_input_status_show()
541 cobalt_info("rx%d: vsync: %d\n", rx, ioread32(&vmr->vsync_time)); in cobalt_video_input_status_show()
542 cobalt_info("rx%d: vbp: %d\n", rx, ioread32(&vmr->vback_porch)); in cobalt_video_input_status_show()
543 cobalt_info("rx%d: vact: %d\n", rx, ioread32(&vmr->vactive_area)); in cobalt_video_input_status_show()
544 cobalt_info("rx%d: vfb: %d\n", rx, ioread32(&vmr->vfront_porch)); in cobalt_video_input_status_show()
545 cobalt_info("rx%d: hsync: %d\n", rx, ioread32(&vmr->hsync_time)); in cobalt_video_input_status_show()
546 cobalt_info("rx%d: hbp: %d\n", rx, ioread32(&vmr->hback_porch)); in cobalt_video_input_status_show()
547 cobalt_info("rx%d: hact: %d\n", rx, ioread32(&vmr->hactive_area)); in cobalt_video_input_status_show()
548 cobalt_info("rx%d: hfb: %d\n", rx, ioread32(&vmr->hfront_porch)); in cobalt_video_input_status_show()
550 (ioread32(&fw->ctrl) & M00473_CTRL_BITMAP_ENABLE_MSK) ? in cobalt_video_input_status_show()
552 (ioread32(&fw->ctrl) & M00473_CTRL_BITMAP_FORCE_FREEWHEEL_MODE_MSK) ? in cobalt_video_input_status_show()
554 (ioread32(&fw->status) & M00473_STATUS_BITMAP_FREEWHEEL_MODE_MSK) ? in cobalt_video_input_status_show()
555 "freewheeling " : "video-passthrough "); in cobalt_video_input_status_show()
556 iowrite32(0xff, &vmr->irq_status); in cobalt_video_input_status_show()
558 (ioread32(&clkloss->ctrl) & M00479_CTRL_BITMAP_ENABLE_MSK) ? in cobalt_video_input_status_show()
560 (ioread32(&clkloss->status) & M00479_STATUS_BITMAP_CLOCK_MISSING_MSK) ? in cobalt_video_input_status_show()
561 "clock-missing " : "found-clock "); in cobalt_video_input_status_show()
562 cobalt_info("rx%d: Packer: %x\n", rx, ioread32(&packer->control)); in cobalt_video_input_status_show()
568 struct cobalt *cobalt = s->cobalt; in cobalt_log_status()
573 cobalt_info("%s", cobalt->hdl_info); in cobalt_log_status()
578 s->dma_channel, s->video_channel); in cobalt_log_status()
582 v4l2_subdev_call(s->sd, core, log_status); in cobalt_log_status()
583 if (!s->is_output) { in cobalt_log_status()
588 stat = ioread32(&vo->rd_status); in cobalt_log_status()
595 cobalt_info("tx: evcnt: %d\n", ioread32(&vo->rd_evcnt_count)); in cobalt_log_status()
604 if (s->input == 1) { in cobalt_enum_dv_timings()
605 if (timings->index) in cobalt_enum_dv_timings()
606 return -EINVAL; in cobalt_enum_dv_timings()
607 memset(timings->reserved, 0, sizeof(timings->reserved)); in cobalt_enum_dv_timings()
608 timings->timings = cea1080p60; in cobalt_enum_dv_timings()
611 timings->pad = 0; in cobalt_enum_dv_timings()
612 return v4l2_subdev_call(s->sd, in cobalt_enum_dv_timings()
622 if (s->input == 1) { in cobalt_s_dv_timings()
627 if (v4l2_match_dv_timings(timings, &s->timings, 0, true)) in cobalt_s_dv_timings()
630 if (vb2_is_busy(&s->q)) in cobalt_s_dv_timings()
631 return -EBUSY; in cobalt_s_dv_timings()
633 err = v4l2_subdev_call(s->sd, in cobalt_s_dv_timings()
636 s->timings = *timings; in cobalt_s_dv_timings()
637 s->width = timings->bt.width; in cobalt_s_dv_timings()
638 s->height = timings->bt.height; in cobalt_s_dv_timings()
639 s->stride = timings->bt.width * s->bpp; in cobalt_s_dv_timings()
649 if (s->input == 1) { in cobalt_g_dv_timings()
653 return v4l2_subdev_call(s->sd, in cobalt_g_dv_timings()
662 if (s->input == 1) { in cobalt_query_dv_timings()
666 return v4l2_subdev_call(s->sd, in cobalt_query_dv_timings()
675 cap->pad = 0; in cobalt_dv_timings_cap()
676 return v4l2_subdev_call(s->sd, in cobalt_dv_timings_cap()
683 switch (f->index) { in cobalt_enum_fmt_vid_cap()
685 f->pixelformat = V4L2_PIX_FMT_YUYV; in cobalt_enum_fmt_vid_cap()
688 f->pixelformat = V4L2_PIX_FMT_RGB24; in cobalt_enum_fmt_vid_cap()
691 f->pixelformat = V4L2_PIX_FMT_BGR32; in cobalt_enum_fmt_vid_cap()
694 return -EINVAL; in cobalt_enum_fmt_vid_cap()
704 struct v4l2_pix_format *pix = &f->fmt.pix; in cobalt_g_fmt_vid_cap()
706 pix->width = s->width; in cobalt_g_fmt_vid_cap()
707 pix->height = s->height; in cobalt_g_fmt_vid_cap()
708 pix->bytesperline = s->stride; in cobalt_g_fmt_vid_cap()
709 pix->field = V4L2_FIELD_NONE; in cobalt_g_fmt_vid_cap()
711 if (s->input == 1) { in cobalt_g_fmt_vid_cap()
712 pix->colorspace = V4L2_COLORSPACE_SRGB; in cobalt_g_fmt_vid_cap()
715 .pad = s->pad_source, in cobalt_g_fmt_vid_cap()
719 v4l2_subdev_call(s->sd, pad, get_fmt, NULL, &sd_fmt); in cobalt_g_fmt_vid_cap()
723 pix->pixelformat = s->pixfmt; in cobalt_g_fmt_vid_cap()
724 pix->sizeimage = pix->bytesperline * pix->height; in cobalt_g_fmt_vid_cap()
733 struct v4l2_pix_format *pix = &f->fmt.pix; in cobalt_try_fmt_vid_cap()
736 if ((pix->width < 176) || (pix->height < 144)) { in cobalt_try_fmt_vid_cap()
737 pix->width = 176; in cobalt_try_fmt_vid_cap()
738 pix->height = 144; in cobalt_try_fmt_vid_cap()
741 if ((pix->width > 1920) || (pix->height > 1080)) { in cobalt_try_fmt_vid_cap()
742 pix->width = 1920; in cobalt_try_fmt_vid_cap()
743 pix->height = 1080; in cobalt_try_fmt_vid_cap()
747 pix->width &= ~0x3; in cobalt_try_fmt_vid_cap()
750 pix->height &= ~0x1; in cobalt_try_fmt_vid_cap()
752 if (s->input == 1) { in cobalt_try_fmt_vid_cap()
754 pix->width = 1920; in cobalt_try_fmt_vid_cap()
755 pix->height = 1080; in cobalt_try_fmt_vid_cap()
756 pix->colorspace = V4L2_COLORSPACE_SRGB; in cobalt_try_fmt_vid_cap()
759 .pad = s->pad_source, in cobalt_try_fmt_vid_cap()
763 v4l2_subdev_call(s->sd, pad, get_fmt, NULL, &sd_fmt); in cobalt_try_fmt_vid_cap()
767 switch (pix->pixelformat) { in cobalt_try_fmt_vid_cap()
770 pix->bytesperline = max(pix->bytesperline & ~0x3, in cobalt_try_fmt_vid_cap()
771 pix->width * COBALT_BYTES_PER_PIXEL_YUYV); in cobalt_try_fmt_vid_cap()
772 pix->pixelformat = V4L2_PIX_FMT_YUYV; in cobalt_try_fmt_vid_cap()
775 pix->bytesperline = max(pix->bytesperline & ~0x3, in cobalt_try_fmt_vid_cap()
776 pix->width * COBALT_BYTES_PER_PIXEL_RGB24); in cobalt_try_fmt_vid_cap()
779 pix->bytesperline = max(pix->bytesperline & ~0x3, in cobalt_try_fmt_vid_cap()
780 pix->width * COBALT_BYTES_PER_PIXEL_RGB32); in cobalt_try_fmt_vid_cap()
784 pix->sizeimage = pix->bytesperline * pix->height; in cobalt_try_fmt_vid_cap()
785 pix->field = V4L2_FIELD_NONE; in cobalt_try_fmt_vid_cap()
794 struct v4l2_pix_format *pix = &f->fmt.pix; in cobalt_s_fmt_vid_cap()
796 if (vb2_is_busy(&s->q)) in cobalt_s_fmt_vid_cap()
797 return -EBUSY; in cobalt_s_fmt_vid_cap()
800 return -EINVAL; in cobalt_s_fmt_vid_cap()
802 s->width = pix->width; in cobalt_s_fmt_vid_cap()
803 s->height = pix->height; in cobalt_s_fmt_vid_cap()
804 s->stride = pix->bytesperline; in cobalt_s_fmt_vid_cap()
805 switch (pix->pixelformat) { in cobalt_s_fmt_vid_cap()
807 s->bpp = COBALT_BYTES_PER_PIXEL_YUYV; in cobalt_s_fmt_vid_cap()
810 s->bpp = COBALT_BYTES_PER_PIXEL_RGB24; in cobalt_s_fmt_vid_cap()
813 s->bpp = COBALT_BYTES_PER_PIXEL_RGB32; in cobalt_s_fmt_vid_cap()
816 return -EINVAL; in cobalt_s_fmt_vid_cap()
818 s->pixfmt = pix->pixelformat; in cobalt_s_fmt_vid_cap()
827 struct v4l2_pix_format *pix = &f->fmt.pix; in cobalt_try_fmt_vid_out()
830 if ((pix->width < 176) || (pix->height < 144)) { in cobalt_try_fmt_vid_out()
831 pix->width = 176; in cobalt_try_fmt_vid_out()
832 pix->height = 144; in cobalt_try_fmt_vid_out()
835 if ((pix->width > 1920) || (pix->height > 1080)) { in cobalt_try_fmt_vid_out()
836 pix->width = 1920; in cobalt_try_fmt_vid_out()
837 pix->height = 1080; in cobalt_try_fmt_vid_out()
841 pix->width &= ~0x3; in cobalt_try_fmt_vid_out()
844 pix->height &= ~0x1; in cobalt_try_fmt_vid_out()
846 switch (pix->pixelformat) { in cobalt_try_fmt_vid_out()
849 pix->bytesperline = max(pix->bytesperline & ~0x3, in cobalt_try_fmt_vid_out()
850 pix->width * COBALT_BYTES_PER_PIXEL_YUYV); in cobalt_try_fmt_vid_out()
851 pix->pixelformat = V4L2_PIX_FMT_YUYV; in cobalt_try_fmt_vid_out()
854 pix->bytesperline = max(pix->bytesperline & ~0x3, in cobalt_try_fmt_vid_out()
855 pix->width * COBALT_BYTES_PER_PIXEL_RGB32); in cobalt_try_fmt_vid_out()
859 pix->sizeimage = pix->bytesperline * pix->height; in cobalt_try_fmt_vid_out()
860 pix->field = V4L2_FIELD_NONE; in cobalt_try_fmt_vid_out()
869 struct v4l2_pix_format *pix = &f->fmt.pix; in cobalt_g_fmt_vid_out()
871 pix->width = s->width; in cobalt_g_fmt_vid_out()
872 pix->height = s->height; in cobalt_g_fmt_vid_out()
873 pix->bytesperline = s->stride; in cobalt_g_fmt_vid_out()
874 pix->field = V4L2_FIELD_NONE; in cobalt_g_fmt_vid_out()
875 pix->pixelformat = s->pixfmt; in cobalt_g_fmt_vid_out()
876 pix->colorspace = s->colorspace; in cobalt_g_fmt_vid_out()
877 pix->xfer_func = s->xfer_func; in cobalt_g_fmt_vid_out()
878 pix->ycbcr_enc = s->ycbcr_enc; in cobalt_g_fmt_vid_out()
879 pix->quantization = s->quantization; in cobalt_g_fmt_vid_out()
880 pix->sizeimage = pix->bytesperline * pix->height; in cobalt_g_fmt_vid_out()
888 switch (f->index) { in cobalt_enum_fmt_vid_out()
890 f->pixelformat = V4L2_PIX_FMT_YUYV; in cobalt_enum_fmt_vid_out()
893 f->pixelformat = V4L2_PIX_FMT_BGR32; in cobalt_enum_fmt_vid_out()
896 return -EINVAL; in cobalt_enum_fmt_vid_out()
906 struct v4l2_pix_format *pix = &f->fmt.pix; in cobalt_s_fmt_vid_out()
913 return -EINVAL; in cobalt_s_fmt_vid_out()
915 if (vb2_is_busy(&s->q) && (pix->pixelformat != s->pixfmt || in cobalt_s_fmt_vid_out()
916 pix->width != s->width || pix->height != s->height || in cobalt_s_fmt_vid_out()
917 pix->bytesperline != s->stride)) in cobalt_s_fmt_vid_out()
918 return -EBUSY; in cobalt_s_fmt_vid_out()
920 switch (pix->pixelformat) { in cobalt_s_fmt_vid_out()
922 s->bpp = COBALT_BYTES_PER_PIXEL_YUYV; in cobalt_s_fmt_vid_out()
926 s->bpp = COBALT_BYTES_PER_PIXEL_RGB32; in cobalt_s_fmt_vid_out()
930 return -EINVAL; in cobalt_s_fmt_vid_out()
932 s->width = pix->width; in cobalt_s_fmt_vid_out()
933 s->height = pix->height; in cobalt_s_fmt_vid_out()
934 s->stride = pix->bytesperline; in cobalt_s_fmt_vid_out()
935 s->pixfmt = pix->pixelformat; in cobalt_s_fmt_vid_out()
936 s->colorspace = pix->colorspace; in cobalt_s_fmt_vid_out()
937 s->xfer_func = pix->xfer_func; in cobalt_s_fmt_vid_out()
938 s->ycbcr_enc = pix->ycbcr_enc; in cobalt_s_fmt_vid_out()
939 s->quantization = pix->quantization; in cobalt_s_fmt_vid_out()
941 v4l2_subdev_call(s->sd, pad, set_fmt, NULL, &sd_fmt); in cobalt_s_fmt_vid_out()
950 if (inp->index > 1) in cobalt_enum_input()
951 return -EINVAL; in cobalt_enum_input()
952 if (inp->index == 0) in cobalt_enum_input()
953 snprintf(inp->name, sizeof(inp->name), in cobalt_enum_input()
954 "HDMI-%d", s->video_channel); in cobalt_enum_input()
956 snprintf(inp->name, sizeof(inp->name), in cobalt_enum_input()
957 "Generator-%d", s->video_channel); in cobalt_enum_input()
958 inp->type = V4L2_INPUT_TYPE_CAMERA; in cobalt_enum_input()
959 inp->capabilities = V4L2_IN_CAP_DV_TIMINGS; in cobalt_enum_input()
960 if (inp->index == 1) in cobalt_enum_input()
962 return v4l2_subdev_call(s->sd, in cobalt_enum_input()
963 video, g_input_status, &inp->status); in cobalt_enum_input()
970 *i = s->input; in cobalt_g_input()
979 return -EINVAL; in cobalt_s_input()
980 if (vb2_is_busy(&s->q)) in cobalt_s_input()
981 return -EBUSY; in cobalt_s_input()
982 s->input = i; in cobalt_s_input()
986 if (s->input == 1) /* Test Pattern Generator */ in cobalt_s_input()
989 return v4l2_subdev_call(s->sd, video, s_routing, in cobalt_s_input()
996 if (out->index) in cobalt_enum_output()
997 return -EINVAL; in cobalt_enum_output()
998 snprintf(out->name, sizeof(out->name), "HDMI-%d", out->index); in cobalt_enum_output()
999 out->type = V4L2_OUTPUT_TYPE_ANALOG; in cobalt_enum_output()
1000 out->capabilities = V4L2_OUT_CAP_DV_TIMINGS; in cobalt_enum_output()
1012 return i ? -EINVAL : 0; in cobalt_s_output()
1018 u32 pad = edid->pad; in cobalt_g_edid()
1021 if (edid->pad >= (s->is_output ? 1 : 2)) in cobalt_g_edid()
1022 return -EINVAL; in cobalt_g_edid()
1023 edid->pad = 0; in cobalt_g_edid()
1024 ret = v4l2_subdev_call(s->sd, pad, get_edid, edid); in cobalt_g_edid()
1025 edid->pad = pad; in cobalt_g_edid()
1032 u32 pad = edid->pad; in cobalt_s_edid()
1035 if (edid->pad >= 2) in cobalt_s_edid()
1036 return -EINVAL; in cobalt_s_edid()
1037 edid->pad = 0; in cobalt_s_edid()
1038 ret = v4l2_subdev_call(s->sd, pad, set_edid, edid); in cobalt_s_edid()
1039 edid->pad = pad; in cobalt_s_edid()
1046 switch (sub->type) { in cobalt_subscribe_event()
1058 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) in cobalt_g_parm()
1059 return -EINVAL; in cobalt_g_parm()
1061 fps = v4l2_calc_timeperframe(&s->timings); in cobalt_g_parm()
1062 a->parm.capture.timeperframe.numerator = fps.numerator; in cobalt_g_parm()
1063 a->parm.capture.timeperframe.denominator = fps.denominator; in cobalt_g_parm()
1064 a->parm.capture.readbuffers = 3; in cobalt_g_parm()
1076 return -EINVAL; in cobalt_g_pixelaspect()
1078 if (s->input == 1) in cobalt_g_pixelaspect()
1081 err = v4l2_subdev_call(s->sd, pad, g_dv_timings, 0, &timings); in cobalt_g_pixelaspect()
1094 if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) in cobalt_g_selection()
1095 return -EINVAL; in cobalt_g_selection()
1097 if (s->input == 1) in cobalt_g_selection()
1100 err = v4l2_subdev_call(s->sd, pad, g_dv_timings, 0, &timings); in cobalt_g_selection()
1105 switch (sel->target) { in cobalt_g_selection()
1108 sel->r.top = 0; in cobalt_g_selection()
1109 sel->r.left = 0; in cobalt_g_selection()
1110 sel->r.width = timings.bt.width; in cobalt_g_selection()
1111 sel->r.height = timings.bt.height; in cobalt_g_selection()
1114 return -EINVAL; in cobalt_g_selection()
1202 struct cobalt_stream *s = cobalt->streams + node; in cobalt_node_register()
1203 struct video_device *vdev = &s->vdev; in cobalt_node_register()
1204 struct vb2_queue *q = &s->q; in cobalt_node_register()
1207 mutex_init(&s->lock); in cobalt_node_register()
1208 spin_lock_init(&s->irqlock); in cobalt_node_register()
1210 snprintf(vdev->name, sizeof(vdev->name), in cobalt_node_register()
1211 "%s-%d", cobalt->v4l2_dev.name, node); in cobalt_node_register()
1212 s->width = 1920; in cobalt_node_register()
1213 /* Audio frames are just 4 lines of 1920 bytes */ in cobalt_node_register()
1214 s->height = s->is_audio ? 4 : 1080; in cobalt_node_register()
1216 if (s->is_audio) { in cobalt_node_register()
1217 s->bpp = 1; in cobalt_node_register()
1218 s->pixfmt = V4L2_PIX_FMT_GREY; in cobalt_node_register()
1219 } else if (s->is_output) { in cobalt_node_register()
1220 s->bpp = COBALT_BYTES_PER_PIXEL_RGB32; in cobalt_node_register()
1221 s->pixfmt = V4L2_PIX_FMT_BGR32; in cobalt_node_register()
1223 s->bpp = COBALT_BYTES_PER_PIXEL_YUYV; in cobalt_node_register()
1224 s->pixfmt = V4L2_PIX_FMT_YUYV; in cobalt_node_register()
1226 s->colorspace = V4L2_COLORSPACE_SRGB; in cobalt_node_register()
1227 s->stride = s->width * s->bpp; in cobalt_node_register()
1229 if (!s->is_audio) { in cobalt_node_register()
1230 if (s->is_dummy) in cobalt_node_register()
1232 vdev->v4l2_dev = &cobalt->v4l2_dev; in cobalt_node_register()
1233 if (s->is_dummy) in cobalt_node_register()
1234 vdev->fops = &cobalt_empty_fops; in cobalt_node_register()
1236 vdev->fops = s->is_output ? &cobalt_out_fops : in cobalt_node_register()
1238 vdev->release = video_device_release_empty; in cobalt_node_register()
1239 vdev->vfl_dir = s->is_output ? VFL_DIR_TX : VFL_DIR_RX; in cobalt_node_register()
1240 vdev->lock = &s->lock; in cobalt_node_register()
1241 if (s->sd) in cobalt_node_register()
1242 vdev->ctrl_handler = s->sd->ctrl_handler; in cobalt_node_register()
1243 s->timings = dv1080p60; in cobalt_node_register()
1244 v4l2_subdev_call(s->sd, pad, s_dv_timings, 0, &s->timings); in cobalt_node_register()
1245 if (!s->is_output && s->sd) in cobalt_node_register()
1247 vdev->ioctl_ops = s->is_dummy ? &cobalt_ioctl_empty_ops : in cobalt_node_register()
1251 INIT_LIST_HEAD(&s->bufs); in cobalt_node_register()
1252 q->type = s->is_output ? V4L2_BUF_TYPE_VIDEO_OUTPUT : in cobalt_node_register()
1254 q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; in cobalt_node_register()
1255 q->io_modes |= s->is_output ? VB2_WRITE : VB2_READ; in cobalt_node_register()
1256 q->drv_priv = s; in cobalt_node_register()
1257 q->buf_struct_size = sizeof(struct cobalt_buffer); in cobalt_node_register()
1258 q->ops = &cobalt_qops; in cobalt_node_register()
1259 q->mem_ops = &vb2_dma_sg_memops; in cobalt_node_register()
1260 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; in cobalt_node_register()
1261 q->min_queued_buffers = 2; in cobalt_node_register()
1262 q->lock = &s->lock; in cobalt_node_register()
1263 q->dev = &cobalt->pci_dev->dev; in cobalt_node_register()
1264 vdev->queue = q; in cobalt_node_register()
1265 vdev->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_READWRITE; in cobalt_node_register()
1266 if (s->is_output) in cobalt_node_register()
1267 vdev->device_caps |= V4L2_CAP_VIDEO_OUTPUT; in cobalt_node_register()
1269 vdev->device_caps |= V4L2_CAP_VIDEO_CAPTURE; in cobalt_node_register()
1273 if (!s->is_audio && ret == 0) in cobalt_node_register()
1274 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); in cobalt_node_register()
1275 else if (!s->is_dummy) in cobalt_node_register()
1279 if (!s->is_audio) in cobalt_node_register()
1309 struct cobalt_stream *s = cobalt->streams + node; in cobalt_nodes_unregister()
1310 struct video_device *vdev = &s->vdev; in cobalt_nodes_unregister()
1312 if (!s->is_audio) in cobalt_nodes_unregister()
1314 else if (!s->is_dummy) in cobalt_nodes_unregister()