Lines Matching +full:- +full:30 +full:mv
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * TW5864 driver - video encoding functions
9 #include <media/v4l2-common.h>
10 #include <media/v4l2-event.h>
11 #include <media/videobuf2-dma-contig.h>
14 #include "tw5864-reg.h"
187 return sizes[0] < H264_VLC_BUF_SIZE ? -EINVAL : 0; in tw5864_queue_setup()
198 struct vb2_queue *vq = vb->vb2_queue; in tw5864_buf_queue()
203 spin_lock_irqsave(&dev->slock, flags); in tw5864_buf_queue()
204 list_add_tail(&buf->list, &dev->active); in tw5864_buf_queue()
205 spin_unlock_irqrestore(&dev->slock, flags); in tw5864_buf_queue()
211 struct tw5864_dev *dev = input->root; in tw5864_input_std_get()
212 u8 std_reg = tw_indir_readb(TW5864_INDIR_VIN_E(input->nr)); in tw5864_input_std_get()
217 dev_dbg(&dev->pci->dev, in tw5864_input_std_get()
219 return -EAGAIN; in tw5864_input_std_get()
227 struct tw5864_dev *dev = input->root; in tw5864_enable_input()
228 int nr = input->nr; in tw5864_enable_input()
238 dev_dbg(&dev->pci->dev, "Enabling channel %d\n", nr); in tw5864_enable_input()
240 input->frame_seqno = 0; in tw5864_enable_input()
241 input->frame_gop_seqno = 0; in tw5864_enable_input()
242 input->h264_idr_pic_id = 0; in tw5864_enable_input()
244 input->reg_dsp_qp = input->qp; in tw5864_enable_input()
245 input->reg_dsp_ref_mvp_lambda = lambda_lookup_table[input->qp]; in tw5864_enable_input()
246 input->reg_dsp_i4x4_weight = intra4x4_lambda3[input->qp]; in tw5864_enable_input()
247 input->reg_emu = TW5864_EMU_EN_LPF | TW5864_EMU_EN_BHOST in tw5864_enable_input()
249 input->reg_dsp = nr /* channel id */ in tw5864_enable_input()
254 input->resolution = D1; in tw5864_enable_input()
256 d1_height = (input->std == STD_NTSC) ? 480 : 576; in tw5864_enable_input()
258 input->width = d1_width; in tw5864_enable_input()
259 input->height = d1_height; in tw5864_enable_input()
261 input->reg_interlacing = 0x4; in tw5864_enable_input()
263 switch (input->resolution) { in tw5864_enable_input()
266 frame_height_bus_value = input->height - 1; in tw5864_enable_input()
270 input->reg_dsp_codec |= TW5864_CIF_MAP_MD | TW5864_HD1_MAP_MD; in tw5864_enable_input()
271 input->reg_emu |= TW5864_DSP_FRAME_TYPE_D1; in tw5864_enable_input()
272 input->reg_interlacing = TW5864_DI_EN | TW5864_DSP_INTER_ST; in tw5864_enable_input()
277 input->height /= 2; in tw5864_enable_input()
278 input->width /= 2; in tw5864_enable_input()
280 frame_height_bus_value = input->height * 2 - 1; in tw5864_enable_input()
284 input->reg_dsp_codec |= TW5864_HD1_MAP_MD; in tw5864_enable_input()
285 input->reg_emu |= TW5864_DSP_FRAME_TYPE_D1; in tw5864_enable_input()
291 input->height /= 4; in tw5864_enable_input()
292 input->width /= 2; in tw5864_enable_input()
294 frame_height_bus_value = input->height * 2 - 1; in tw5864_enable_input()
298 input->reg_dsp_codec |= TW5864_CIF_MAP_MD; in tw5864_enable_input()
303 input->height /= 4; in tw5864_enable_input()
304 input->width /= 4; in tw5864_enable_input()
306 frame_height_bus_value = input->height * 2 - 1; in tw5864_enable_input()
310 input->reg_dsp_codec |= TW5864_CIF_MAP_MD; in tw5864_enable_input()
321 tw_indir_writeb(TW5864_INDIR_OUT_PIC_WIDTH(nr), input->width / 4); in tw5864_enable_input()
322 tw_indir_writeb(TW5864_INDIR_OUT_PIC_HEIGHT(nr), input->height / 4); in tw5864_enable_input()
328 input->width = 704; in tw5864_enable_input()
334 ((input->width / 16) << 8) | (input->height / 16)); in tw5864_enable_input()
343 (frame_height_bus_value + 1) / 2 - 1); in tw5864_enable_input()
357 input->std == STD_NTSC ? 29 : 24); in tw5864_enable_input()
363 spin_lock_irqsave(&dev->slock, flags); in tw5864_enable_input()
364 input->enabled = 1; in tw5864_enable_input()
365 spin_unlock_irqrestore(&dev->slock, flags); in tw5864_enable_input()
372 struct tw5864_dev *dev = input->root; in tw5864_request_encoded_frame()
376 tw_writel(TW5864_EMU, input->reg_emu); in tw5864_request_encoded_frame()
377 tw_writel(TW5864_INTERLACING, input->reg_interlacing); in tw5864_request_encoded_frame()
378 tw_writel(TW5864_DSP, input->reg_dsp); in tw5864_request_encoded_frame()
380 tw_writel(TW5864_DSP_QP, input->reg_dsp_qp); in tw5864_request_encoded_frame()
381 tw_writel(TW5864_DSP_REF_MVP_LAMBDA, input->reg_dsp_ref_mvp_lambda); in tw5864_request_encoded_frame()
382 tw_writel(TW5864_DSP_I4x4_WEIGHT, input->reg_dsp_i4x4_weight); in tw5864_request_encoded_frame()
387 if (input->frame_gop_seqno == 0) { in tw5864_request_encoded_frame()
388 /* Produce I-frame */ in tw5864_request_encoded_frame()
390 input->h264_idr_pic_id++; in tw5864_request_encoded_frame()
391 input->h264_idr_pic_id &= TW5864_DSP_REF_FRM; in tw5864_request_encoded_frame()
393 /* Produce P-frame */ in tw5864_request_encoded_frame()
400 ((input->tail_nb_bits + 24) << TW5864_VLC_BIT_ALIGN_SHIFT) | in tw5864_request_encoded_frame()
401 input->reg_dsp_qp); in tw5864_request_encoded_frame()
404 2 * input->nr); in tw5864_request_encoded_frame()
416 struct tw5864_dev *dev = input->root; in tw5864_disable_input()
419 dev_dbg(&dev->pci->dev, "Disabling channel %d\n", input->nr); in tw5864_disable_input()
421 spin_lock_irqsave(&dev->slock, flags); in tw5864_disable_input()
422 input->enabled = 0; in tw5864_disable_input()
423 spin_unlock_irqrestore(&dev->slock, flags); in tw5864_disable_input()
436 while (!list_empty(&input->active)) { in tw5864_start_streaming()
437 struct tw5864_buf *buf = list_entry(input->active.next, in tw5864_start_streaming()
440 list_del(&buf->list); in tw5864_start_streaming()
441 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED); in tw5864_start_streaming()
453 spin_lock_irqsave(&input->slock, flags); in tw5864_stop_streaming()
454 if (input->vb) { in tw5864_stop_streaming()
455 vb2_buffer_done(&input->vb->vb.vb2_buf, VB2_BUF_STATE_ERROR); in tw5864_stop_streaming()
456 input->vb = NULL; in tw5864_stop_streaming()
458 while (!list_empty(&input->active)) { in tw5864_stop_streaming()
459 struct tw5864_buf *buf = list_entry(input->active.next, in tw5864_stop_streaming()
462 list_del(&buf->list); in tw5864_stop_streaming()
463 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); in tw5864_stop_streaming()
465 spin_unlock_irqrestore(&input->slock, flags); in tw5864_stop_streaming()
480 container_of(ctrl->handler, struct tw5864_input, hdl); in tw5864_s_ctrl()
481 struct tw5864_dev *dev = input->root; in tw5864_s_ctrl()
484 switch (ctrl->id) { in tw5864_s_ctrl()
486 tw_indir_writeb(TW5864_INDIR_VIN_A_BRIGHT(input->nr), in tw5864_s_ctrl()
487 (u8)ctrl->val); in tw5864_s_ctrl()
490 tw_indir_writeb(TW5864_INDIR_VIN_7_HUE(input->nr), in tw5864_s_ctrl()
491 (u8)ctrl->val); in tw5864_s_ctrl()
494 tw_indir_writeb(TW5864_INDIR_VIN_9_CNTRST(input->nr), in tw5864_s_ctrl()
495 (u8)ctrl->val); in tw5864_s_ctrl()
498 tw_indir_writeb(TW5864_INDIR_VIN_B_SAT_U(input->nr), in tw5864_s_ctrl()
499 (u8)ctrl->val); in tw5864_s_ctrl()
500 tw_indir_writeb(TW5864_INDIR_VIN_C_SAT_V(input->nr), in tw5864_s_ctrl()
501 (u8)ctrl->val); in tw5864_s_ctrl()
504 input->gop = ctrl->val; in tw5864_s_ctrl()
507 spin_lock_irqsave(&input->slock, flags); in tw5864_s_ctrl()
508 input->qp = ctrl->val; in tw5864_s_ctrl()
509 input->reg_dsp_qp = input->qp; in tw5864_s_ctrl()
510 input->reg_dsp_ref_mvp_lambda = lambda_lookup_table[input->qp]; in tw5864_s_ctrl()
511 input->reg_dsp_i4x4_weight = intra4x4_lambda3[input->qp]; in tw5864_s_ctrl()
512 spin_unlock_irqrestore(&input->slock, flags); in tw5864_s_ctrl()
515 memset(input->md_threshold_grid_values, ctrl->val, in tw5864_s_ctrl()
516 sizeof(input->md_threshold_grid_values)); in tw5864_s_ctrl()
521 /* input->md_threshold_grid_ctrl->p_new.p_u16 contains data */ in tw5864_s_ctrl()
522 memcpy(input->md_threshold_grid_values, in tw5864_s_ctrl()
523 input->md_threshold_grid_ctrl->p_new.p_u16, in tw5864_s_ctrl()
524 sizeof(input->md_threshold_grid_values)); in tw5864_s_ctrl()
535 f->fmt.pix.width = 704; in tw5864_fmt_vid_cap()
536 switch (input->std) { in tw5864_fmt_vid_cap()
539 return -EINVAL; in tw5864_fmt_vid_cap()
541 f->fmt.pix.height = 480; in tw5864_fmt_vid_cap()
545 f->fmt.pix.height = 576; in tw5864_fmt_vid_cap()
548 f->fmt.pix.field = V4L2_FIELD_INTERLACED; in tw5864_fmt_vid_cap()
549 f->fmt.pix.pixelformat = V4L2_PIX_FMT_H264; in tw5864_fmt_vid_cap()
550 f->fmt.pix.sizeimage = H264_VLC_BUF_SIZE; in tw5864_fmt_vid_cap()
551 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; in tw5864_fmt_vid_cap()
559 struct tw5864_dev *dev = input->root; in tw5864_enum_input()
561 u8 indir_0x000 = tw_indir_readb(TW5864_INDIR_VIN_0(input->nr)); in tw5864_enum_input()
562 u8 indir_0x00d = tw_indir_readb(TW5864_INDIR_VIN_D(input->nr)); in tw5864_enum_input()
566 if (i->index) in tw5864_enum_input()
567 return -EINVAL; in tw5864_enum_input()
569 i->type = V4L2_INPUT_TYPE_CAMERA; in tw5864_enum_input()
570 snprintf(i->name, sizeof(i->name), "Encoder %d", input->nr); in tw5864_enum_input()
571 i->std = TW5864_NORMS; in tw5864_enum_input()
573 i->status |= V4L2_IN_ST_NO_SYNC; in tw5864_enum_input()
575 i->status |= V4L2_IN_ST_NO_H_LOCK; in tw5864_enum_input()
577 i->status |= V4L2_IN_ST_NO_SIGNAL; in tw5864_enum_input()
579 i->status |= V4L2_IN_ST_NO_COLOR; in tw5864_enum_input()
581 i->status |= V4L2_IN_ST_MACROVISION; in tw5864_enum_input()
595 return -EINVAL; in tw5864_s_input()
604 strscpy(cap->driver, "tw5864", sizeof(cap->driver)); in tw5864_querycap()
605 snprintf(cap->card, sizeof(cap->card), "TW5864 Encoder %d", in tw5864_querycap()
606 input->nr); in tw5864_querycap()
628 *std = input->v4l2_std; in tw5864_g_std()
635 struct tw5864_dev *dev = input->root; in tw5864_s_std()
637 input->v4l2_std = std; in tw5864_s_std()
638 input->std = tw5864_from_v4l2_std(std); in tw5864_s_std()
639 tw_indir_writeb(TW5864_INDIR_VIN_E(input->nr), input->std); in tw5864_s_std()
646 if (f->index) in tw5864_enum_fmt_vid_cap()
647 return -EINVAL; in tw5864_enum_fmt_vid_cap()
649 f->pixelformat = V4L2_PIX_FMT_H264; in tw5864_enum_fmt_vid_cap()
657 switch (sub->type) { in tw5864_subscribe_event()
660 * Allow for up to 30 events (1 second for NTSC) to be stored. in tw5864_subscribe_event()
662 return v4l2_event_subscribe(fh, sub, 30, NULL); in tw5864_subscribe_event()
678 * For 1 FPS - 0x00000001 in tw5864_frame_interval_set()
681 * For max FPS - set all 25/30 lower bits: in tw5864_frame_interval_set()
685 * For half of max FPS - use such pattern: in tw5864_frame_interval_set()
691 * The value supplied to hardware is capped by mask of 25/30 lower bits. in tw5864_frame_interval_set()
693 struct tw5864_dev *dev = input->root; in tw5864_frame_interval_set()
696 int std_max_fps = input->std == STD_NTSC ? 30 : 25; in tw5864_frame_interval_set()
698 for (shift = 0; shift < std_max_fps; shift += input->frame_interval) in tw5864_frame_interval_set()
701 tw_writel(TW5864_H264EN_RATE_CNTL_LO_WORD(input->nr, 0), in tw5864_frame_interval_set()
703 tw_writel(TW5864_H264EN_RATE_CNTL_HI_WORD(input->nr, 0), in tw5864_frame_interval_set()
710 struct tw5864_dev *dev = input->root; in tw5864_frameinterval_get()
712 switch (input->std) { in tw5864_frameinterval_get()
714 frameinterval->numerator = 1001; in tw5864_frameinterval_get()
715 frameinterval->denominator = 30000; in tw5864_frameinterval_get()
719 frameinterval->numerator = 1; in tw5864_frameinterval_get()
720 frameinterval->denominator = 25; in tw5864_frameinterval_get()
723 dev_warn(&dev->pci->dev, "tw5864_frameinterval_get requested for unknown std %d\n", in tw5864_frameinterval_get()
724 input->std); in tw5864_frameinterval_get()
725 return -EINVAL; in tw5864_frameinterval_get()
736 if (fsize->index > 0) in tw5864_enum_framesizes()
737 return -EINVAL; in tw5864_enum_framesizes()
738 if (fsize->pixel_format != V4L2_PIX_FMT_H264) in tw5864_enum_framesizes()
739 return -EINVAL; in tw5864_enum_framesizes()
741 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; in tw5864_enum_framesizes()
742 fsize->discrete.width = 704; in tw5864_enum_framesizes()
743 fsize->discrete.height = input->std == STD_NTSC ? 480 : 576; in tw5864_enum_framesizes()
753 int std_max_fps = input->std == STD_NTSC ? 30 : 25; in tw5864_enum_frameintervals()
754 struct v4l2_frmsizeenum fsize = { .index = fintv->index, in tw5864_enum_frameintervals()
755 .pixel_format = fintv->pixel_format }; in tw5864_enum_frameintervals()
762 if (fintv->width != fsize.discrete.width || in tw5864_enum_frameintervals()
763 fintv->height != fsize.discrete.height) in tw5864_enum_frameintervals()
764 return -EINVAL; in tw5864_enum_frameintervals()
766 fintv->type = V4L2_FRMIVAL_TYPE_STEPWISE; in tw5864_enum_frameintervals()
772 fintv->stepwise.step = frameinterval; in tw5864_enum_frameintervals()
773 fintv->stepwise.min = frameinterval; in tw5864_enum_frameintervals()
774 fintv->stepwise.max = frameinterval; in tw5864_enum_frameintervals()
775 fintv->stepwise.max.numerator *= std_max_fps; in tw5864_enum_frameintervals()
784 struct v4l2_captureparm *cp = &sp->parm.capture; in tw5864_g_parm()
787 cp->capability = V4L2_CAP_TIMEPERFRAME; in tw5864_g_parm()
789 ret = tw5864_frameinterval_get(input, &cp->timeperframe); in tw5864_g_parm()
793 cp->timeperframe.numerator *= input->frame_interval; in tw5864_g_parm()
794 cp->capturemode = 0; in tw5864_g_parm()
795 cp->readbuffers = 2; in tw5864_g_parm()
804 struct v4l2_fract *t = &sp->parm.capture.timeperframe; in tw5864_s_parm()
812 if (!t->numerator || !t->denominator) { in tw5864_s_parm()
813 t->numerator = time_base.numerator * input->frame_interval; in tw5864_s_parm()
814 t->denominator = time_base.denominator; in tw5864_s_parm()
815 } else if (t->denominator != time_base.denominator) { in tw5864_s_parm()
816 t->numerator = t->numerator * time_base.denominator / in tw5864_s_parm()
817 t->denominator; in tw5864_s_parm()
818 t->denominator = time_base.denominator; in tw5864_s_parm()
821 input->frame_interval = t->numerator / time_base.numerator; in tw5864_s_parm()
822 if (input->frame_interval < 1) in tw5864_s_parm()
823 input->frame_interval = 1; in tw5864_s_parm()
850 struct tw5864_dev *dev = input->root; in tw5864_g_reg()
852 if (reg->reg < INDIR_SPACE_MAP_SHIFT) { in tw5864_g_reg()
853 if (reg->reg > 0x87fff) in tw5864_g_reg()
854 return -EINVAL; in tw5864_g_reg()
855 reg->size = 4; in tw5864_g_reg()
856 reg->val = tw_readl(reg->reg); in tw5864_g_reg()
858 __u64 indir_addr = reg->reg - INDIR_SPACE_MAP_SHIFT; in tw5864_g_reg()
861 return -EINVAL; in tw5864_g_reg()
862 reg->size = 1; in tw5864_g_reg()
863 reg->val = tw_indir_readb(reg->reg); in tw5864_g_reg()
872 struct tw5864_dev *dev = input->root; in tw5864_s_reg()
874 if (reg->reg < INDIR_SPACE_MAP_SHIFT) { in tw5864_s_reg()
875 if (reg->reg > 0x87fff) in tw5864_s_reg()
876 return -EINVAL; in tw5864_s_reg()
877 tw_writel(reg->reg, reg->val); in tw5864_s_reg()
879 __u64 indir_addr = reg->reg - INDIR_SPACE_MAP_SHIFT; in tw5864_s_reg()
882 return -EINVAL; in tw5864_s_reg()
883 tw_indir_writeb(reg->reg, reg->val); in tw5864_s_reg()
952 int last_dma_allocated = -1; in tw5864_video_init()
953 int last_input_nr_registered = -1; in tw5864_video_init()
956 struct tw5864_h264_frame *frame = &dev->h264_buf[i]; in tw5864_video_init()
958 frame->vlc.addr = dma_alloc_coherent(&dev->pci->dev, in tw5864_video_init()
960 &frame->vlc.dma_addr, in tw5864_video_init()
962 if (!frame->vlc.addr) { in tw5864_video_init()
963 dev_err(&dev->pci->dev, "dma alloc fail\n"); in tw5864_video_init()
964 ret = -ENOMEM; in tw5864_video_init()
967 frame->mv.addr = dma_alloc_coherent(&dev->pci->dev, in tw5864_video_init()
969 &frame->mv.dma_addr, in tw5864_video_init()
971 if (!frame->mv.addr) { in tw5864_video_init()
972 dev_err(&dev->pci->dev, "dma alloc fail\n"); in tw5864_video_init()
973 ret = -ENOMEM; in tw5864_video_init()
974 dma_free_coherent(&dev->pci->dev, H264_VLC_BUF_SIZE, in tw5864_video_init()
975 frame->vlc.addr, frame->vlc.dma_addr); in tw5864_video_init()
1016 spin_lock_irqsave(&dev->slock, flags); in tw5864_video_init()
1017 dev->encoder_busy = 0; in tw5864_video_init()
1018 dev->h264_buf_r_index = 0; in tw5864_video_init()
1019 dev->h264_buf_w_index = 0; in tw5864_video_init()
1021 dev->h264_buf[dev->h264_buf_w_index].vlc.dma_addr); in tw5864_video_init()
1023 dev->h264_buf[dev->h264_buf_w_index].mv.dma_addr); in tw5864_video_init()
1024 spin_unlock_irqrestore(&dev->slock, flags); in tw5864_video_init()
1045 * I-frames in switching channels. in tw5864_video_init()
1062 dev->irqmask |= TW5864_INTR_VLC_DONE | TW5864_INTR_TIMER; in tw5864_video_init()
1065 tasklet_setup(&dev->tasklet, tw5864_handle_frame_task); in tw5864_video_init()
1068 dev->inputs[i].root = dev; in tw5864_video_init()
1069 dev->inputs[i].nr = i; in tw5864_video_init()
1070 ret = tw5864_video_input_init(&dev->inputs[i], video_nr[i]); in tw5864_video_init()
1079 for (i = last_input_nr_registered; i >= 0; i--) in tw5864_video_init()
1080 tw5864_video_input_fini(&dev->inputs[i]); in tw5864_video_init()
1082 tasklet_kill(&dev->tasklet); in tw5864_video_init()
1085 for (i = last_dma_allocated; i >= 0; i--) { in tw5864_video_init()
1086 dma_free_coherent(&dev->pci->dev, H264_VLC_BUF_SIZE, in tw5864_video_init()
1087 dev->h264_buf[i].vlc.addr, in tw5864_video_init()
1088 dev->h264_buf[i].vlc.dma_addr); in tw5864_video_init()
1089 dma_free_coherent(&dev->pci->dev, H264_MV_BUF_SIZE, in tw5864_video_init()
1090 dev->h264_buf[i].mv.addr, in tw5864_video_init()
1091 dev->h264_buf[i].mv.dma_addr); in tw5864_video_init()
1099 struct tw5864_dev *dev = input->root; in tw5864_video_input_init()
1101 struct v4l2_ctrl_handler *hdl = &input->hdl; in tw5864_video_input_init()
1103 mutex_init(&input->lock); in tw5864_video_input_init()
1104 spin_lock_init(&input->slock); in tw5864_video_input_init()
1107 INIT_LIST_HEAD(&input->active); in tw5864_video_input_init()
1108 input->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in tw5864_video_input_init()
1109 input->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; in tw5864_video_input_init()
1110 input->vidq.io_modes = VB2_MMAP | VB2_READ | VB2_DMABUF; in tw5864_video_input_init()
1111 input->vidq.ops = &tw5864_video_qops; in tw5864_video_input_init()
1112 input->vidq.mem_ops = &vb2_dma_contig_memops; in tw5864_video_input_init()
1113 input->vidq.drv_priv = input; in tw5864_video_input_init()
1114 input->vidq.gfp_flags = 0; in tw5864_video_input_init()
1115 input->vidq.buf_struct_size = sizeof(struct tw5864_buf); in tw5864_video_input_init()
1116 input->vidq.lock = &input->lock; in tw5864_video_input_init()
1117 input->vidq.min_buffers_needed = 2; in tw5864_video_input_init()
1118 input->vidq.dev = &input->root->pci->dev; in tw5864_video_input_init()
1119 ret = vb2_queue_init(&input->vidq); in tw5864_video_input_init()
1123 input->vdev = tw5864_video_template; in tw5864_video_input_init()
1124 input->vdev.v4l2_dev = &input->root->v4l2_dev; in tw5864_video_input_init()
1125 input->vdev.lock = &input->lock; in tw5864_video_input_init()
1126 input->vdev.queue = &input->vidq; in tw5864_video_input_init()
1127 video_set_drvdata(&input->vdev, input); in tw5864_video_input_init()
1132 V4L2_CID_BRIGHTNESS, -128, 127, 1, 0); in tw5864_video_input_init()
1137 v4l2_ctrl_new_std(hdl, &tw5864_ctrl_ops, V4L2_CID_HUE, -128, 127, 1, 0); in tw5864_video_input_init()
1150 input->md_threshold_grid_ctrl = in tw5864_video_input_init()
1152 if (hdl->error) { in tw5864_video_input_init()
1153 ret = hdl->error; in tw5864_video_input_init()
1156 input->vdev.ctrl_handler = hdl; in tw5864_video_input_init()
1159 input->qp = QP_VALUE; in tw5864_video_input_init()
1160 input->gop = GOP_SIZE; in tw5864_video_input_init()
1161 input->frame_interval = 1; in tw5864_video_input_init()
1163 ret = video_register_device(&input->vdev, VFL_TYPE_VIDEO, video_nr); in tw5864_video_input_init()
1167 dev_info(&input->root->pci->dev, "Registered video device %s\n", in tw5864_video_input_init()
1168 video_device_node_name(&input->vdev)); in tw5864_video_input_init()
1174 input->v4l2_std = V4L2_STD_NTSC_M; in tw5864_video_input_init()
1175 input->std = STD_NTSC; in tw5864_video_input_init()
1186 mutex_destroy(&input->lock); in tw5864_video_input_init()
1193 vb2_video_unregister_device(&dev->vdev); in tw5864_video_input_fini()
1194 v4l2_ctrl_handler_free(&dev->hdl); in tw5864_video_input_fini()
1201 tasklet_kill(&dev->tasklet); in tw5864_video_fini()
1204 tw5864_video_input_fini(&dev->inputs[i]); in tw5864_video_fini()
1207 dma_free_coherent(&dev->pci->dev, H264_VLC_BUF_SIZE, in tw5864_video_fini()
1208 dev->h264_buf[i].vlc.addr, in tw5864_video_fini()
1209 dev->h264_buf[i].vlc.dma_addr); in tw5864_video_fini()
1210 dma_free_coherent(&dev->pci->dev, H264_MV_BUF_SIZE, in tw5864_video_fini()
1211 dev->h264_buf[i].mv.addr, in tw5864_video_fini()
1212 dev->h264_buf[i].mv.dma_addr); in tw5864_video_fini()
1218 struct tw5864_buf *vb = input->vb; in tw5864_prepare_frame_headers()
1224 spin_lock_irqsave(&input->slock, flags); in tw5864_prepare_frame_headers()
1225 if (list_empty(&input->active)) { in tw5864_prepare_frame_headers()
1226 spin_unlock_irqrestore(&input->slock, flags); in tw5864_prepare_frame_headers()
1227 input->vb = NULL; in tw5864_prepare_frame_headers()
1230 vb = list_first_entry(&input->active, struct tw5864_buf, list); in tw5864_prepare_frame_headers()
1231 list_del(&vb->list); in tw5864_prepare_frame_headers()
1232 spin_unlock_irqrestore(&input->slock, flags); in tw5864_prepare_frame_headers()
1235 dst = vb2_plane_vaddr(&vb->vb.vb2_buf, 0); in tw5864_prepare_frame_headers()
1236 dst_space = vb2_plane_size(&vb->vb.vb2_buf, 0); in tw5864_prepare_frame_headers()
1239 * Low-level bitstream writing functions don't have a fine way to say in tw5864_prepare_frame_headers()
1253 if (input->frame_gop_seqno == 0) in tw5864_prepare_frame_headers()
1254 tw5864_h264_put_stream_header(&dst, &dst_space, input->qp, in tw5864_prepare_frame_headers()
1255 input->width, input->height); in tw5864_prepare_frame_headers()
1258 tw5864_h264_put_slice_header(&dst, &dst_space, input->h264_idr_pic_id, in tw5864_prepare_frame_headers()
1259 input->frame_gop_seqno, in tw5864_prepare_frame_headers()
1260 &input->tail_nb_bits, &input->tail); in tw5864_prepare_frame_headers()
1261 input->vb = vb; in tw5864_prepare_frame_headers()
1262 input->buf_cur_ptr = dst; in tw5864_prepare_frame_headers()
1263 input->buf_cur_space_left = dst_space; in tw5864_prepare_frame_headers()
1268 * hardware-provided Motion Vector Data.
1281 * non_zero_members: number of non-zero residuals in each macro block in tw5864_md_metric_from_mvd()
1300 struct tw5864_input *input = frame->input; in tw5864_is_motion_triggered()
1301 u32 *mv = (u32 *)frame->mv.addr; in tw5864_is_motion_triggered() local
1306 const u16 thresh = input->md_threshold_grid_values[i]; in tw5864_is_motion_triggered()
1307 const unsigned int metric = tw5864_md_metric_from_mvd(mv[i]); in tw5864_is_motion_triggered()
1324 spin_lock_irqsave(&dev->slock, flags); in tw5864_handle_frame_task()
1325 while (dev->h264_buf_r_index != dev->h264_buf_w_index && batch_size--) { in tw5864_handle_frame_task()
1327 &dev->h264_buf[dev->h264_buf_r_index]; in tw5864_handle_frame_task()
1329 spin_unlock_irqrestore(&dev->slock, flags); in tw5864_handle_frame_task()
1330 dma_sync_single_for_cpu(&dev->pci->dev, frame->vlc.dma_addr, in tw5864_handle_frame_task()
1332 dma_sync_single_for_cpu(&dev->pci->dev, frame->mv.dma_addr, in tw5864_handle_frame_task()
1335 dma_sync_single_for_device(&dev->pci->dev, frame->vlc.dma_addr, in tw5864_handle_frame_task()
1337 dma_sync_single_for_device(&dev->pci->dev, frame->mv.dma_addr, in tw5864_handle_frame_task()
1339 spin_lock_irqsave(&dev->slock, flags); in tw5864_handle_frame_task()
1341 dev->h264_buf_r_index++; in tw5864_handle_frame_task()
1342 dev->h264_buf_r_index %= H264_BUF_CNT; in tw5864_handle_frame_task()
1344 spin_unlock_irqrestore(&dev->slock, flags); in tw5864_handle_frame_task()
1353 while (((count_len >> 2) - 1) > 0) { in tw5864_vlc_checksum()
1355 count_len -= 4; in tw5864_vlc_checksum()
1365 struct tw5864_input *input = frame->input; in tw5864_handle_frame()
1366 struct tw5864_dev *dev = input->root; in tw5864_handle_frame()
1369 int frame_len = frame->vlc_len - SKIP_VLCBUF_BYTES; in tw5864_handle_frame()
1370 u8 *dst = input->buf_cur_ptr; in tw5864_handle_frame()
1373 u8 vlc_first_byte = ((u8 *)(frame->vlc.addr + SKIP_VLCBUF_BYTES))[0]; in tw5864_handle_frame()
1380 if (frame->checksum != in tw5864_handle_frame()
1381 tw5864_vlc_checksum((u32 *)frame->vlc.addr, frame_len)) in tw5864_handle_frame()
1382 dev_err(&dev->pci->dev, in tw5864_handle_frame()
1386 spin_lock_irqsave(&input->slock, flags); in tw5864_handle_frame()
1387 vb = input->vb; in tw5864_handle_frame()
1388 input->vb = NULL; in tw5864_handle_frame()
1389 spin_unlock_irqrestore(&input->slock, flags); in tw5864_handle_frame()
1392 dev_dbg(&dev->pci->dev, "vb is empty, dropping frame\n"); in tw5864_handle_frame()
1396 v4l2_buf = to_vb2_v4l2_buffer(&vb->vb.vb2_buf); in tw5864_handle_frame()
1402 if (input->buf_cur_space_left < frame_len * 5 / 4) { in tw5864_handle_frame()
1403 dev_err_once(&dev->pci->dev, in tw5864_handle_frame()
1405 input->buf_cur_space_left, frame_len); in tw5864_handle_frame()
1409 for (i = 0; i < 8 - input->tail_nb_bits; i++) in tw5864_handle_frame()
1413 dst[0] = (input->tail & tail_mask) | (vlc_first_byte & vlc_mask); in tw5864_handle_frame()
1414 frame_len--; in tw5864_handle_frame()
1418 src = frame->vlc.addr + SKIP_VLCBUF_BYTES + 1; in tw5864_handle_frame()
1435 vb2_set_plane_payload(&vb->vb.vb2_buf, 0, in tw5864_handle_frame()
1436 dst - (u8 *)vb2_plane_vaddr(&vb->vb.vb2_buf, 0)); in tw5864_handle_frame()
1438 vb->vb.vb2_buf.timestamp = frame->timestamp; in tw5864_handle_frame()
1439 v4l2_buf->field = V4L2_FIELD_INTERLACED; in tw5864_handle_frame()
1440 v4l2_buf->sequence = frame->seqno; in tw5864_handle_frame()
1443 if (frame->gop_seqno /* P-frame */ && in tw5864_handle_frame()
1449 .frame_sequence = v4l2_buf->sequence, in tw5864_handle_frame()
1453 v4l2_event_queue(&input->vdev, &ev); in tw5864_handle_frame()
1456 vb2_buffer_done(&vb->vb.vb2_buf, VB2_BUF_STATE_DONE); in tw5864_handle_frame()