Lines Matching +full:- +full:30 +full:mv

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * TW5864 driver - video encoding functions
10 #include <media/v4l2-common.h>
11 #include <media/v4l2-event.h>
12 #include <media/videobuf2-dma-contig.h>
15 #include "tw5864-reg.h"
188 return sizes[0] < H264_VLC_BUF_SIZE ? -EINVAL : 0; in tw5864_queue_setup()
199 struct vb2_queue *vq = vb->vb2_queue; in tw5864_buf_queue()
204 spin_lock_irqsave(&dev->slock, flags); in tw5864_buf_queue()
205 list_add_tail(&buf->list, &dev->active); in tw5864_buf_queue()
206 spin_unlock_irqrestore(&dev->slock, flags); in tw5864_buf_queue()
212 struct tw5864_dev *dev = input->root; in tw5864_input_std_get()
213 u8 std_reg = tw_indir_readb(TW5864_INDIR_VIN_E(input->nr)); in tw5864_input_std_get()
218 dev_dbg(&dev->pci->dev, in tw5864_input_std_get()
220 return -EAGAIN; in tw5864_input_std_get()
228 struct tw5864_dev *dev = input->root; in tw5864_enable_input()
229 int nr = input->nr; in tw5864_enable_input()
239 dev_dbg(&dev->pci->dev, "Enabling channel %d\n", nr); in tw5864_enable_input()
241 input->frame_seqno = 0; in tw5864_enable_input()
242 input->frame_gop_seqno = 0; in tw5864_enable_input()
243 input->h264_idr_pic_id = 0; in tw5864_enable_input()
245 input->reg_dsp_qp = input->qp; in tw5864_enable_input()
246 input->reg_dsp_ref_mvp_lambda = lambda_lookup_table[input->qp]; in tw5864_enable_input()
247 input->reg_dsp_i4x4_weight = intra4x4_lambda3[input->qp]; in tw5864_enable_input()
248 input->reg_emu = TW5864_EMU_EN_LPF | TW5864_EMU_EN_BHOST in tw5864_enable_input()
250 input->reg_dsp = nr /* channel id */ in tw5864_enable_input()
255 input->resolution = D1; in tw5864_enable_input()
257 d1_height = (input->std == STD_NTSC) ? 480 : 576; in tw5864_enable_input()
259 input->width = d1_width; in tw5864_enable_input()
260 input->height = d1_height; in tw5864_enable_input()
262 input->reg_interlacing = 0x4; in tw5864_enable_input()
264 switch (input->resolution) { in tw5864_enable_input()
267 frame_height_bus_value = input->height - 1; in tw5864_enable_input()
271 input->reg_dsp_codec |= TW5864_CIF_MAP_MD | TW5864_HD1_MAP_MD; in tw5864_enable_input()
272 input->reg_emu |= TW5864_DSP_FRAME_TYPE_D1; in tw5864_enable_input()
273 input->reg_interlacing = TW5864_DI_EN | TW5864_DSP_INTER_ST; in tw5864_enable_input()
278 input->height /= 2; in tw5864_enable_input()
279 input->width /= 2; in tw5864_enable_input()
281 frame_height_bus_value = input->height * 2 - 1; in tw5864_enable_input()
285 input->reg_dsp_codec |= TW5864_HD1_MAP_MD; in tw5864_enable_input()
286 input->reg_emu |= TW5864_DSP_FRAME_TYPE_D1; in tw5864_enable_input()
292 input->height /= 4; in tw5864_enable_input()
293 input->width /= 2; in tw5864_enable_input()
295 frame_height_bus_value = input->height * 2 - 1; in tw5864_enable_input()
299 input->reg_dsp_codec |= TW5864_CIF_MAP_MD; in tw5864_enable_input()
304 input->height /= 4; in tw5864_enable_input()
305 input->width /= 4; in tw5864_enable_input()
307 frame_height_bus_value = input->height * 2 - 1; in tw5864_enable_input()
311 input->reg_dsp_codec |= TW5864_CIF_MAP_MD; in tw5864_enable_input()
322 tw_indir_writeb(TW5864_INDIR_OUT_PIC_WIDTH(nr), input->width / 4); in tw5864_enable_input()
323 tw_indir_writeb(TW5864_INDIR_OUT_PIC_HEIGHT(nr), input->height / 4); in tw5864_enable_input()
329 input->width = 704; in tw5864_enable_input()
335 ((input->width / 16) << 8) | (input->height / 16)); in tw5864_enable_input()
344 (frame_height_bus_value + 1) / 2 - 1); in tw5864_enable_input()
358 input->std == STD_NTSC ? 29 : 24); in tw5864_enable_input()
364 spin_lock_irqsave(&dev->slock, flags); in tw5864_enable_input()
365 input->enabled = 1; in tw5864_enable_input()
366 spin_unlock_irqrestore(&dev->slock, flags); in tw5864_enable_input()
373 struct tw5864_dev *dev = input->root; in tw5864_request_encoded_frame()
377 tw_writel(TW5864_EMU, input->reg_emu); in tw5864_request_encoded_frame()
378 tw_writel(TW5864_INTERLACING, input->reg_interlacing); in tw5864_request_encoded_frame()
379 tw_writel(TW5864_DSP, input->reg_dsp); in tw5864_request_encoded_frame()
381 tw_writel(TW5864_DSP_QP, input->reg_dsp_qp); in tw5864_request_encoded_frame()
382 tw_writel(TW5864_DSP_REF_MVP_LAMBDA, input->reg_dsp_ref_mvp_lambda); in tw5864_request_encoded_frame()
383 tw_writel(TW5864_DSP_I4x4_WEIGHT, input->reg_dsp_i4x4_weight); in tw5864_request_encoded_frame()
388 if (input->frame_gop_seqno == 0) { in tw5864_request_encoded_frame()
389 /* Produce I-frame */ in tw5864_request_encoded_frame()
391 input->h264_idr_pic_id++; in tw5864_request_encoded_frame()
392 input->h264_idr_pic_id &= TW5864_DSP_REF_FRM; in tw5864_request_encoded_frame()
394 /* Produce P-frame */ in tw5864_request_encoded_frame()
401 ((input->tail_nb_bits + 24) << TW5864_VLC_BIT_ALIGN_SHIFT) | in tw5864_request_encoded_frame()
402 input->reg_dsp_qp); in tw5864_request_encoded_frame()
405 2 * input->nr); in tw5864_request_encoded_frame()
417 struct tw5864_dev *dev = input->root; in tw5864_disable_input()
420 dev_dbg(&dev->pci->dev, "Disabling channel %d\n", input->nr); in tw5864_disable_input()
422 spin_lock_irqsave(&dev->slock, flags); in tw5864_disable_input()
423 input->enabled = 0; in tw5864_disable_input()
424 spin_unlock_irqrestore(&dev->slock, flags); in tw5864_disable_input()
437 while (!list_empty(&input->active)) { in tw5864_start_streaming()
438 struct tw5864_buf *buf = list_entry(input->active.next, in tw5864_start_streaming()
441 list_del(&buf->list); in tw5864_start_streaming()
442 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_QUEUED); in tw5864_start_streaming()
454 spin_lock_irqsave(&input->slock, flags); in tw5864_stop_streaming()
455 if (input->vb) { in tw5864_stop_streaming()
456 vb2_buffer_done(&input->vb->vb.vb2_buf, VB2_BUF_STATE_ERROR); in tw5864_stop_streaming()
457 input->vb = NULL; in tw5864_stop_streaming()
459 while (!list_empty(&input->active)) { in tw5864_stop_streaming()
460 struct tw5864_buf *buf = list_entry(input->active.next, in tw5864_stop_streaming()
463 list_del(&buf->list); in tw5864_stop_streaming()
464 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); in tw5864_stop_streaming()
466 spin_unlock_irqrestore(&input->slock, flags); in tw5864_stop_streaming()
481 container_of(ctrl->handler, struct tw5864_input, hdl); in tw5864_s_ctrl()
482 struct tw5864_dev *dev = input->root; in tw5864_s_ctrl()
485 switch (ctrl->id) { in tw5864_s_ctrl()
487 tw_indir_writeb(TW5864_INDIR_VIN_A_BRIGHT(input->nr), in tw5864_s_ctrl()
488 (u8)ctrl->val); in tw5864_s_ctrl()
491 tw_indir_writeb(TW5864_INDIR_VIN_7_HUE(input->nr), in tw5864_s_ctrl()
492 (u8)ctrl->val); in tw5864_s_ctrl()
495 tw_indir_writeb(TW5864_INDIR_VIN_9_CNTRST(input->nr), in tw5864_s_ctrl()
496 (u8)ctrl->val); in tw5864_s_ctrl()
499 tw_indir_writeb(TW5864_INDIR_VIN_B_SAT_U(input->nr), in tw5864_s_ctrl()
500 (u8)ctrl->val); in tw5864_s_ctrl()
501 tw_indir_writeb(TW5864_INDIR_VIN_C_SAT_V(input->nr), in tw5864_s_ctrl()
502 (u8)ctrl->val); in tw5864_s_ctrl()
505 input->gop = ctrl->val; in tw5864_s_ctrl()
508 spin_lock_irqsave(&input->slock, flags); in tw5864_s_ctrl()
509 input->qp = ctrl->val; in tw5864_s_ctrl()
510 input->reg_dsp_qp = input->qp; in tw5864_s_ctrl()
511 input->reg_dsp_ref_mvp_lambda = lambda_lookup_table[input->qp]; in tw5864_s_ctrl()
512 input->reg_dsp_i4x4_weight = intra4x4_lambda3[input->qp]; in tw5864_s_ctrl()
513 spin_unlock_irqrestore(&input->slock, flags); in tw5864_s_ctrl()
516 memset(input->md_threshold_grid_values, ctrl->val, in tw5864_s_ctrl()
517 sizeof(input->md_threshold_grid_values)); in tw5864_s_ctrl()
522 /* input->md_threshold_grid_ctrl->p_new.p_u16 contains data */ in tw5864_s_ctrl()
523 memcpy(input->md_threshold_grid_values, in tw5864_s_ctrl()
524 input->md_threshold_grid_ctrl->p_new.p_u16, in tw5864_s_ctrl()
525 sizeof(input->md_threshold_grid_values)); in tw5864_s_ctrl()
536 f->fmt.pix.width = 704; in tw5864_fmt_vid_cap()
537 switch (input->std) { in tw5864_fmt_vid_cap()
540 return -EINVAL; in tw5864_fmt_vid_cap()
542 f->fmt.pix.height = 480; in tw5864_fmt_vid_cap()
546 f->fmt.pix.height = 576; in tw5864_fmt_vid_cap()
549 f->fmt.pix.field = V4L2_FIELD_INTERLACED; in tw5864_fmt_vid_cap()
550 f->fmt.pix.pixelformat = V4L2_PIX_FMT_H264; in tw5864_fmt_vid_cap()
551 f->fmt.pix.sizeimage = H264_VLC_BUF_SIZE; in tw5864_fmt_vid_cap()
552 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; in tw5864_fmt_vid_cap()
560 struct tw5864_dev *dev = input->root; in tw5864_enum_input()
562 u8 indir_0x000 = tw_indir_readb(TW5864_INDIR_VIN_0(input->nr)); in tw5864_enum_input()
563 u8 indir_0x00d = tw_indir_readb(TW5864_INDIR_VIN_D(input->nr)); in tw5864_enum_input()
567 if (i->index) in tw5864_enum_input()
568 return -EINVAL; in tw5864_enum_input()
570 i->type = V4L2_INPUT_TYPE_CAMERA; in tw5864_enum_input()
571 snprintf(i->name, sizeof(i->name), "Encoder %d", input->nr); in tw5864_enum_input()
572 i->std = TW5864_NORMS; in tw5864_enum_input()
574 i->status |= V4L2_IN_ST_NO_SYNC; in tw5864_enum_input()
576 i->status |= V4L2_IN_ST_NO_H_LOCK; in tw5864_enum_input()
578 i->status |= V4L2_IN_ST_NO_SIGNAL; in tw5864_enum_input()
580 i->status |= V4L2_IN_ST_NO_COLOR; in tw5864_enum_input()
582 i->status |= V4L2_IN_ST_MACROVISION; in tw5864_enum_input()
596 return -EINVAL; in tw5864_s_input()
605 strscpy(cap->driver, "tw5864", sizeof(cap->driver)); in tw5864_querycap()
606 snprintf(cap->card, sizeof(cap->card), "TW5864 Encoder %d", in tw5864_querycap()
607 input->nr); in tw5864_querycap()
629 *std = input->v4l2_std; in tw5864_g_std()
636 struct tw5864_dev *dev = input->root; in tw5864_s_std()
638 input->v4l2_std = std; in tw5864_s_std()
639 input->std = tw5864_from_v4l2_std(std); in tw5864_s_std()
640 tw_indir_writeb(TW5864_INDIR_VIN_E(input->nr), input->std); in tw5864_s_std()
647 if (f->index) in tw5864_enum_fmt_vid_cap()
648 return -EINVAL; in tw5864_enum_fmt_vid_cap()
650 f->pixelformat = V4L2_PIX_FMT_H264; in tw5864_enum_fmt_vid_cap()
658 switch (sub->type) { in tw5864_subscribe_event()
661 * Allow for up to 30 events (1 second for NTSC) to be stored. in tw5864_subscribe_event()
663 return v4l2_event_subscribe(fh, sub, 30, NULL); in tw5864_subscribe_event()
679 * For 1 FPS - 0x00000001 in tw5864_frame_interval_set()
682 * For max FPS - set all 25/30 lower bits: in tw5864_frame_interval_set()
686 * For half of max FPS - use such pattern: in tw5864_frame_interval_set()
692 * The value supplied to hardware is capped by mask of 25/30 lower bits. in tw5864_frame_interval_set()
694 struct tw5864_dev *dev = input->root; in tw5864_frame_interval_set()
697 int std_max_fps = input->std == STD_NTSC ? 30 : 25; in tw5864_frame_interval_set()
699 for (shift = 0; shift < std_max_fps; shift += input->frame_interval) in tw5864_frame_interval_set()
702 tw_writel(TW5864_H264EN_RATE_CNTL_LO_WORD(input->nr, 0), in tw5864_frame_interval_set()
704 tw_writel(TW5864_H264EN_RATE_CNTL_HI_WORD(input->nr, 0), in tw5864_frame_interval_set()
711 struct tw5864_dev *dev = input->root; in tw5864_frameinterval_get()
713 switch (input->std) { in tw5864_frameinterval_get()
715 frameinterval->numerator = 1001; in tw5864_frameinterval_get()
716 frameinterval->denominator = 30000; in tw5864_frameinterval_get()
720 frameinterval->numerator = 1; in tw5864_frameinterval_get()
721 frameinterval->denominator = 25; in tw5864_frameinterval_get()
724 dev_warn(&dev->pci->dev, "tw5864_frameinterval_get requested for unknown std %d\n", in tw5864_frameinterval_get()
725 input->std); in tw5864_frameinterval_get()
726 return -EINVAL; in tw5864_frameinterval_get()
737 if (fsize->index > 0) in tw5864_enum_framesizes()
738 return -EINVAL; in tw5864_enum_framesizes()
739 if (fsize->pixel_format != V4L2_PIX_FMT_H264) in tw5864_enum_framesizes()
740 return -EINVAL; in tw5864_enum_framesizes()
742 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; in tw5864_enum_framesizes()
743 fsize->discrete.width = 704; in tw5864_enum_framesizes()
744 fsize->discrete.height = input->std == STD_NTSC ? 480 : 576; in tw5864_enum_framesizes()
754 int std_max_fps = input->std == STD_NTSC ? 30 : 25; in tw5864_enum_frameintervals()
755 struct v4l2_frmsizeenum fsize = { .index = fintv->index, in tw5864_enum_frameintervals()
756 .pixel_format = fintv->pixel_format }; in tw5864_enum_frameintervals()
763 if (fintv->width != fsize.discrete.width || in tw5864_enum_frameintervals()
764 fintv->height != fsize.discrete.height) in tw5864_enum_frameintervals()
765 return -EINVAL; in tw5864_enum_frameintervals()
767 fintv->type = V4L2_FRMIVAL_TYPE_STEPWISE; in tw5864_enum_frameintervals()
773 fintv->stepwise.step = frameinterval; in tw5864_enum_frameintervals()
774 fintv->stepwise.min = frameinterval; in tw5864_enum_frameintervals()
775 fintv->stepwise.max = frameinterval; in tw5864_enum_frameintervals()
776 fintv->stepwise.max.numerator *= std_max_fps; in tw5864_enum_frameintervals()
785 struct v4l2_captureparm *cp = &sp->parm.capture; in tw5864_g_parm()
788 cp->capability = V4L2_CAP_TIMEPERFRAME; in tw5864_g_parm()
790 ret = tw5864_frameinterval_get(input, &cp->timeperframe); in tw5864_g_parm()
794 cp->timeperframe.numerator *= input->frame_interval; in tw5864_g_parm()
795 cp->capturemode = 0; in tw5864_g_parm()
796 cp->readbuffers = 2; in tw5864_g_parm()
805 struct v4l2_fract *t = &sp->parm.capture.timeperframe; in tw5864_s_parm()
813 if (!t->numerator || !t->denominator) { in tw5864_s_parm()
814 t->numerator = time_base.numerator * input->frame_interval; in tw5864_s_parm()
815 t->denominator = time_base.denominator; in tw5864_s_parm()
816 } else if (t->denominator != time_base.denominator) { in tw5864_s_parm()
817 t->numerator = t->numerator * time_base.denominator / in tw5864_s_parm()
818 t->denominator; in tw5864_s_parm()
819 t->denominator = time_base.denominator; in tw5864_s_parm()
822 input->frame_interval = t->numerator / time_base.numerator; in tw5864_s_parm()
823 if (input->frame_interval < 1) in tw5864_s_parm()
824 input->frame_interval = 1; in tw5864_s_parm()
851 struct tw5864_dev *dev = input->root; in tw5864_g_reg()
853 if (reg->reg < INDIR_SPACE_MAP_SHIFT) { in tw5864_g_reg()
854 if (reg->reg > 0x87fff) in tw5864_g_reg()
855 return -EINVAL; in tw5864_g_reg()
856 reg->size = 4; in tw5864_g_reg()
857 reg->val = tw_readl(reg->reg); in tw5864_g_reg()
859 __u64 indir_addr = reg->reg - INDIR_SPACE_MAP_SHIFT; in tw5864_g_reg()
862 return -EINVAL; in tw5864_g_reg()
863 reg->size = 1; in tw5864_g_reg()
864 reg->val = tw_indir_readb(reg->reg); in tw5864_g_reg()
873 struct tw5864_dev *dev = input->root; in tw5864_s_reg()
875 if (reg->reg < INDIR_SPACE_MAP_SHIFT) { in tw5864_s_reg()
876 if (reg->reg > 0x87fff) in tw5864_s_reg()
877 return -EINVAL; in tw5864_s_reg()
878 tw_writel(reg->reg, reg->val); in tw5864_s_reg()
880 __u64 indir_addr = reg->reg - INDIR_SPACE_MAP_SHIFT; in tw5864_s_reg()
883 return -EINVAL; in tw5864_s_reg()
884 tw_indir_writeb(reg->reg, reg->val); in tw5864_s_reg()
953 int last_dma_allocated = -1; in tw5864_video_init()
954 int last_input_nr_registered = -1; in tw5864_video_init()
957 struct tw5864_h264_frame *frame = &dev->h264_buf[i]; in tw5864_video_init()
959 frame->vlc.addr = dma_alloc_coherent(&dev->pci->dev, in tw5864_video_init()
961 &frame->vlc.dma_addr, in tw5864_video_init()
963 if (!frame->vlc.addr) { in tw5864_video_init()
964 dev_err(&dev->pci->dev, "dma alloc fail\n"); in tw5864_video_init()
965 ret = -ENOMEM; in tw5864_video_init()
968 frame->mv.addr = dma_alloc_coherent(&dev->pci->dev, in tw5864_video_init()
970 &frame->mv.dma_addr, in tw5864_video_init()
972 if (!frame->mv.addr) { in tw5864_video_init()
973 dev_err(&dev->pci->dev, "dma alloc fail\n"); in tw5864_video_init()
974 ret = -ENOMEM; in tw5864_video_init()
975 dma_free_coherent(&dev->pci->dev, H264_VLC_BUF_SIZE, in tw5864_video_init()
976 frame->vlc.addr, frame->vlc.dma_addr); in tw5864_video_init()
1017 spin_lock_irqsave(&dev->slock, flags); in tw5864_video_init()
1018 dev->encoder_busy = 0; in tw5864_video_init()
1019 dev->h264_buf_r_index = 0; in tw5864_video_init()
1020 dev->h264_buf_w_index = 0; in tw5864_video_init()
1022 dev->h264_buf[dev->h264_buf_w_index].vlc.dma_addr); in tw5864_video_init()
1024 dev->h264_buf[dev->h264_buf_w_index].mv.dma_addr); in tw5864_video_init()
1025 spin_unlock_irqrestore(&dev->slock, flags); in tw5864_video_init()
1046 * I-frames in switching channels. in tw5864_video_init()
1063 dev->irqmask |= TW5864_INTR_VLC_DONE | TW5864_INTR_TIMER; in tw5864_video_init()
1066 INIT_WORK(&dev->bh_work, tw5864_handle_frame_work); in tw5864_video_init()
1069 dev->inputs[i].root = dev; in tw5864_video_init()
1070 dev->inputs[i].nr = i; in tw5864_video_init()
1071 ret = tw5864_video_input_init(&dev->inputs[i], video_nr[i]); in tw5864_video_init()
1080 for (i = last_input_nr_registered; i >= 0; i--) in tw5864_video_init()
1081 tw5864_video_input_fini(&dev->inputs[i]); in tw5864_video_init()
1083 cancel_work_sync(&dev->bh_work); in tw5864_video_init()
1086 for (i = last_dma_allocated; i >= 0; i--) { in tw5864_video_init()
1087 dma_free_coherent(&dev->pci->dev, H264_VLC_BUF_SIZE, in tw5864_video_init()
1088 dev->h264_buf[i].vlc.addr, in tw5864_video_init()
1089 dev->h264_buf[i].vlc.dma_addr); in tw5864_video_init()
1090 dma_free_coherent(&dev->pci->dev, H264_MV_BUF_SIZE, in tw5864_video_init()
1091 dev->h264_buf[i].mv.addr, in tw5864_video_init()
1092 dev->h264_buf[i].mv.dma_addr); in tw5864_video_init()
1100 struct tw5864_dev *dev = input->root; in tw5864_video_input_init()
1102 struct v4l2_ctrl_handler *hdl = &input->hdl; in tw5864_video_input_init()
1104 mutex_init(&input->lock); in tw5864_video_input_init()
1105 spin_lock_init(&input->slock); in tw5864_video_input_init()
1108 INIT_LIST_HEAD(&input->active); in tw5864_video_input_init()
1109 input->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in tw5864_video_input_init()
1110 input->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; in tw5864_video_input_init()
1111 input->vidq.io_modes = VB2_MMAP | VB2_READ | VB2_DMABUF; in tw5864_video_input_init()
1112 input->vidq.ops = &tw5864_video_qops; in tw5864_video_input_init()
1113 input->vidq.mem_ops = &vb2_dma_contig_memops; in tw5864_video_input_init()
1114 input->vidq.drv_priv = input; in tw5864_video_input_init()
1115 input->vidq.gfp_flags = 0; in tw5864_video_input_init()
1116 input->vidq.buf_struct_size = sizeof(struct tw5864_buf); in tw5864_video_input_init()
1117 input->vidq.lock = &input->lock; in tw5864_video_input_init()
1118 input->vidq.min_queued_buffers = 2; in tw5864_video_input_init()
1119 input->vidq.dev = &input->root->pci->dev; in tw5864_video_input_init()
1120 ret = vb2_queue_init(&input->vidq); in tw5864_video_input_init()
1124 input->vdev = tw5864_video_template; in tw5864_video_input_init()
1125 input->vdev.v4l2_dev = &input->root->v4l2_dev; in tw5864_video_input_init()
1126 input->vdev.lock = &input->lock; in tw5864_video_input_init()
1127 input->vdev.queue = &input->vidq; in tw5864_video_input_init()
1128 video_set_drvdata(&input->vdev, input); in tw5864_video_input_init()
1133 V4L2_CID_BRIGHTNESS, -128, 127, 1, 0); in tw5864_video_input_init()
1138 v4l2_ctrl_new_std(hdl, &tw5864_ctrl_ops, V4L2_CID_HUE, -128, 127, 1, 0); in tw5864_video_input_init()
1151 input->md_threshold_grid_ctrl = in tw5864_video_input_init()
1153 if (hdl->error) { in tw5864_video_input_init()
1154 ret = hdl->error; in tw5864_video_input_init()
1157 input->vdev.ctrl_handler = hdl; in tw5864_video_input_init()
1160 input->qp = QP_VALUE; in tw5864_video_input_init()
1161 input->gop = GOP_SIZE; in tw5864_video_input_init()
1162 input->frame_interval = 1; in tw5864_video_input_init()
1164 ret = video_register_device(&input->vdev, VFL_TYPE_VIDEO, video_nr); in tw5864_video_input_init()
1168 dev_info(&input->root->pci->dev, "Registered video device %s\n", in tw5864_video_input_init()
1169 video_device_node_name(&input->vdev)); in tw5864_video_input_init()
1175 input->v4l2_std = V4L2_STD_NTSC_M; in tw5864_video_input_init()
1176 input->std = STD_NTSC; in tw5864_video_input_init()
1187 mutex_destroy(&input->lock); in tw5864_video_input_init()
1194 vb2_video_unregister_device(&dev->vdev); in tw5864_video_input_fini()
1195 v4l2_ctrl_handler_free(&dev->hdl); in tw5864_video_input_fini()
1202 cancel_work_sync(&dev->bh_work); in tw5864_video_fini()
1205 tw5864_video_input_fini(&dev->inputs[i]); in tw5864_video_fini()
1208 dma_free_coherent(&dev->pci->dev, H264_VLC_BUF_SIZE, in tw5864_video_fini()
1209 dev->h264_buf[i].vlc.addr, in tw5864_video_fini()
1210 dev->h264_buf[i].vlc.dma_addr); in tw5864_video_fini()
1211 dma_free_coherent(&dev->pci->dev, H264_MV_BUF_SIZE, in tw5864_video_fini()
1212 dev->h264_buf[i].mv.addr, in tw5864_video_fini()
1213 dev->h264_buf[i].mv.dma_addr); in tw5864_video_fini()
1219 struct tw5864_buf *vb = input->vb; in tw5864_prepare_frame_headers()
1225 spin_lock_irqsave(&input->slock, flags); in tw5864_prepare_frame_headers()
1226 if (list_empty(&input->active)) { in tw5864_prepare_frame_headers()
1227 spin_unlock_irqrestore(&input->slock, flags); in tw5864_prepare_frame_headers()
1228 input->vb = NULL; in tw5864_prepare_frame_headers()
1231 vb = list_first_entry(&input->active, struct tw5864_buf, list); in tw5864_prepare_frame_headers()
1232 list_del(&vb->list); in tw5864_prepare_frame_headers()
1233 spin_unlock_irqrestore(&input->slock, flags); in tw5864_prepare_frame_headers()
1236 dst = vb2_plane_vaddr(&vb->vb.vb2_buf, 0); in tw5864_prepare_frame_headers()
1237 dst_space = vb2_plane_size(&vb->vb.vb2_buf, 0); in tw5864_prepare_frame_headers()
1240 * Low-level bitstream writing functions don't have a fine way to say in tw5864_prepare_frame_headers()
1254 if (input->frame_gop_seqno == 0) in tw5864_prepare_frame_headers()
1255 tw5864_h264_put_stream_header(&dst, &dst_space, input->qp, in tw5864_prepare_frame_headers()
1256 input->width, input->height); in tw5864_prepare_frame_headers()
1259 tw5864_h264_put_slice_header(&dst, &dst_space, input->h264_idr_pic_id, in tw5864_prepare_frame_headers()
1260 input->frame_gop_seqno, in tw5864_prepare_frame_headers()
1261 &input->tail_nb_bits, &input->tail); in tw5864_prepare_frame_headers()
1262 input->vb = vb; in tw5864_prepare_frame_headers()
1263 input->buf_cur_ptr = dst; in tw5864_prepare_frame_headers()
1264 input->buf_cur_space_left = dst_space; in tw5864_prepare_frame_headers()
1269 * hardware-provided Motion Vector Data.
1282 * non_zero_members: number of non-zero residuals in each macro block in tw5864_md_metric_from_mvd()
1301 struct tw5864_input *input = frame->input; in tw5864_is_motion_triggered()
1302 u32 *mv = (u32 *)frame->mv.addr; in tw5864_is_motion_triggered() local
1307 const u16 thresh = input->md_threshold_grid_values[i]; in tw5864_is_motion_triggered()
1308 const unsigned int metric = tw5864_md_metric_from_mvd(mv[i]); in tw5864_is_motion_triggered()
1325 spin_lock_irqsave(&dev->slock, flags); in tw5864_handle_frame_work()
1326 while (dev->h264_buf_r_index != dev->h264_buf_w_index && batch_size--) { in tw5864_handle_frame_work()
1328 &dev->h264_buf[dev->h264_buf_r_index]; in tw5864_handle_frame_work()
1330 spin_unlock_irqrestore(&dev->slock, flags); in tw5864_handle_frame_work()
1331 dma_sync_single_for_cpu(&dev->pci->dev, frame->vlc.dma_addr, in tw5864_handle_frame_work()
1333 dma_sync_single_for_cpu(&dev->pci->dev, frame->mv.dma_addr, in tw5864_handle_frame_work()
1336 dma_sync_single_for_device(&dev->pci->dev, frame->vlc.dma_addr, in tw5864_handle_frame_work()
1338 dma_sync_single_for_device(&dev->pci->dev, frame->mv.dma_addr, in tw5864_handle_frame_work()
1340 spin_lock_irqsave(&dev->slock, flags); in tw5864_handle_frame_work()
1342 dev->h264_buf_r_index++; in tw5864_handle_frame_work()
1343 dev->h264_buf_r_index %= H264_BUF_CNT; in tw5864_handle_frame_work()
1345 spin_unlock_irqrestore(&dev->slock, flags); in tw5864_handle_frame_work()
1354 while (((count_len >> 2) - 1) > 0) { in tw5864_vlc_checksum()
1356 count_len -= 4; in tw5864_vlc_checksum()
1366 struct tw5864_input *input = frame->input; in tw5864_handle_frame()
1367 struct tw5864_dev *dev = input->root; in tw5864_handle_frame()
1370 int frame_len = frame->vlc_len - SKIP_VLCBUF_BYTES; in tw5864_handle_frame()
1371 u8 *dst = input->buf_cur_ptr; in tw5864_handle_frame()
1374 u8 vlc_first_byte = ((u8 *)(frame->vlc.addr + SKIP_VLCBUF_BYTES))[0]; in tw5864_handle_frame()
1381 if (frame->checksum != in tw5864_handle_frame()
1382 tw5864_vlc_checksum((u32 *)frame->vlc.addr, frame_len)) in tw5864_handle_frame()
1383 dev_err(&dev->pci->dev, in tw5864_handle_frame()
1387 spin_lock_irqsave(&input->slock, flags); in tw5864_handle_frame()
1388 vb = input->vb; in tw5864_handle_frame()
1389 input->vb = NULL; in tw5864_handle_frame()
1390 spin_unlock_irqrestore(&input->slock, flags); in tw5864_handle_frame()
1393 dev_dbg(&dev->pci->dev, "vb is empty, dropping frame\n"); in tw5864_handle_frame()
1397 v4l2_buf = to_vb2_v4l2_buffer(&vb->vb.vb2_buf); in tw5864_handle_frame()
1403 if (input->buf_cur_space_left < frame_len * 5 / 4) { in tw5864_handle_frame()
1404 dev_err_once(&dev->pci->dev, in tw5864_handle_frame()
1406 input->buf_cur_space_left, frame_len); in tw5864_handle_frame()
1410 for (i = 0; i < 8 - input->tail_nb_bits; i++) in tw5864_handle_frame()
1414 dst[0] = (input->tail & tail_mask) | (vlc_first_byte & vlc_mask); in tw5864_handle_frame()
1415 frame_len--; in tw5864_handle_frame()
1419 src = frame->vlc.addr + SKIP_VLCBUF_BYTES + 1; in tw5864_handle_frame()
1436 vb2_set_plane_payload(&vb->vb.vb2_buf, 0, in tw5864_handle_frame()
1437 dst - (u8 *)vb2_plane_vaddr(&vb->vb.vb2_buf, 0)); in tw5864_handle_frame()
1439 vb->vb.vb2_buf.timestamp = frame->timestamp; in tw5864_handle_frame()
1440 v4l2_buf->field = V4L2_FIELD_INTERLACED; in tw5864_handle_frame()
1441 v4l2_buf->sequence = frame->seqno; in tw5864_handle_frame()
1444 if (frame->gop_seqno /* P-frame */ && in tw5864_handle_frame()
1450 .frame_sequence = v4l2_buf->sequence, in tw5864_handle_frame()
1454 v4l2_event_queue(&input->vdev, &ev); in tw5864_handle_frame()
1457 vb2_buffer_done(&vb->vb.vb2_buf, VB2_BUF_STATE_DONE); in tw5864_handle_frame()