Lines Matching +full:min +full:- +full:pix +full:- +full:sizes

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2010-2013 Bluecherry, LLC <https://www.bluecherrydvr.com>
17 #include <media/v4l2-ioctl.h>
18 #include <media/v4l2-common.h>
19 #include <media/v4l2-event.h>
20 #include <media/videobuf2-dma-sg.h>
23 #include "solo6x10-tw28.h"
24 #include "solo6x10-jpeg.h"
95 struct solo_dev *solo_dev = solo_enc->solo_dev; in solo_is_motion_on()
97 return (solo_dev->motion_mask >> solo_enc->ch) & 1; in solo_is_motion_on()
102 struct solo_dev *solo_dev = solo_enc->solo_dev; in solo_motion_detected()
104 u32 ch_mask = 1 << solo_enc->ch; in solo_motion_detected()
107 spin_lock_irqsave(&solo_enc->motion_lock, flags); in solo_motion_detected()
112 spin_unlock_irqrestore(&solo_enc->motion_lock, flags); in solo_motion_detected()
119 struct solo_dev *solo_dev = solo_enc->solo_dev; in solo_motion_toggle()
120 u32 mask = 1 << solo_enc->ch; in solo_motion_toggle()
123 spin_lock_irqsave(&solo_enc->motion_lock, flags); in solo_motion_toggle()
126 solo_dev->motion_mask |= mask; in solo_motion_toggle()
128 solo_dev->motion_mask &= ~mask; in solo_motion_toggle()
133 SOLO_VI_MOTION_EN(solo_dev->motion_mask) | in solo_motion_toggle()
136 spin_unlock_irqrestore(&solo_enc->motion_lock, flags); in solo_motion_toggle()
141 struct solo_dev *solo_dev = solo_enc->solo_dev; in solo_update_mode()
145 solo_enc->interlaced = (solo_enc->mode & 0x08) ? 1 : 0; in solo_update_mode()
146 solo_enc->bw_weight = max(solo_dev->fps / solo_enc->interval, 1); in solo_update_mode()
148 if (solo_enc->mode == SOLO_ENC_MODE_CIF) { in solo_update_mode()
149 solo_enc->width = solo_dev->video_hsize >> 1; in solo_update_mode()
150 solo_enc->height = solo_dev->video_vsize; in solo_update_mode()
151 if (solo_dev->type == SOLO_DEV_6110) { in solo_update_mode()
152 if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) { in solo_update_mode()
160 if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) { in solo_update_mode()
169 solo_enc->width = solo_dev->video_hsize; in solo_update_mode()
170 solo_enc->height = solo_dev->video_vsize << 1; in solo_update_mode()
171 solo_enc->bw_weight <<= 2; in solo_update_mode()
172 if (solo_dev->type == SOLO_DEV_6110) { in solo_update_mode()
173 if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) { in solo_update_mode()
181 if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) { in solo_update_mode()
191 memcpy(solo_enc->vop, vop, vop_len); in solo_update_mode()
194 if (solo_dev->type == SOLO_DEV_6010) { in solo_update_mode()
195 u16 fps = solo_dev->fps * 1000; in solo_update_mode()
196 u16 interval = solo_enc->interval * 1000; in solo_update_mode()
198 vop = solo_enc->vop; in solo_update_mode()
208 solo_enc->vop_len = vop_len; in solo_update_mode()
211 vop = solo_enc->jpeg_header; in solo_update_mode()
212 vop[SOF0_START + 5] = 0xff & (solo_enc->height >> 8); in solo_update_mode()
213 vop[SOF0_START + 6] = 0xff & solo_enc->height; in solo_update_mode()
214 vop[SOF0_START + 7] = 0xff & (solo_enc->width >> 8); in solo_update_mode()
215 vop[SOF0_START + 8] = 0xff & solo_enc->width; in solo_update_mode()
218 jpeg_dqt[solo_g_jpeg_qp(solo_dev, solo_enc->ch)], DQT_LEN); in solo_update_mode()
223 u8 ch = solo_enc->ch; in solo_enc_on()
224 struct solo_dev *solo_dev = solo_enc->solo_dev; in solo_enc_on()
230 if (solo_enc->bw_weight > solo_dev->enc_bw_remain) in solo_enc_on()
231 return -EBUSY; in solo_enc_on()
232 solo_enc->sequence = 0; in solo_enc_on()
233 solo_dev->enc_bw_remain -= solo_enc->bw_weight; in solo_enc_on()
235 if (solo_enc->type == SOLO_ENC_TYPE_EXT) in solo_enc_on()
243 solo_enc->interlaced ? 1 : 0); in solo_enc_on()
245 if (solo_enc->interlaced) in solo_enc_on()
246 interval = solo_enc->interval - 1; in solo_enc_on()
248 interval = solo_enc->interval; in solo_enc_on()
251 solo_reg_write(solo_dev, SOLO_VE_CH_GOP(ch), solo_enc->gop); in solo_enc_on()
252 solo_reg_write(solo_dev, SOLO_VE_CH_QP(ch), solo_enc->qp); in solo_enc_on()
256 solo_reg_write(solo_dev, SOLO_VE_CH_GOP_E(ch), solo_enc->gop); in solo_enc_on()
257 solo_reg_write(solo_dev, SOLO_VE_CH_QP_E(ch), solo_enc->qp); in solo_enc_on()
261 solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(ch), solo_enc->mode); in solo_enc_on()
268 struct solo_dev *solo_dev = solo_enc->solo_dev; in solo_enc_off()
270 solo_dev->enc_bw_remain += solo_enc->bw_weight; in solo_enc_off()
272 solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(solo_enc->ch), 0); in solo_enc_off()
273 solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(solo_enc->ch), 0); in solo_enc_off()
282 return -EINVAL; in enc_get_mpeg_dma()
294 SOLO_MP4E_EXT_SIZE(solo_dev) - off, 0, 0); in enc_get_mpeg_dma()
298 dma + SOLO_MP4E_EXT_SIZE(solo_dev) - off, in enc_get_mpeg_dma()
300 size + off - SOLO_MP4E_EXT_SIZE(solo_dev), 0, 0); in enc_get_mpeg_dma()
312 struct solo_dev *solo_dev = solo_enc->solo_dev; in solo_send_desc()
318 return -EINVAL; in solo_send_desc()
320 solo_enc->desc_count = 1; in solo_send_desc()
322 for_each_sg(vbuf->sgl, sg, vbuf->nents, i) { in solo_send_desc()
326 int left = base_size - off; in solo_send_desc()
328 desc = &solo_enc->desc_items[solo_enc->desc_count++]; in solo_send_desc()
335 len -= skip; in solo_send_desc()
337 size -= skip; in solo_send_desc()
341 len = min(len, size); in solo_send_desc()
360 len - left, 0, 0); in solo_send_desc()
364 solo_enc->desc_count--; in solo_send_desc()
367 size -= len; in solo_send_desc()
373 off -= base_size; in solo_send_desc()
376 if (solo_enc->desc_count >= (solo_enc->desc_nelts - 1)) { in solo_send_desc()
377 ret = solo_p2m_dma_desc(solo_dev, solo_enc->desc_items, in solo_send_desc()
378 solo_enc->desc_dma, in solo_send_desc()
379 solo_enc->desc_count - 1); in solo_send_desc()
382 solo_enc->desc_count = 1; in solo_send_desc()
386 if (solo_enc->desc_count <= 1) in solo_send_desc()
389 return solo_p2m_dma_desc(solo_dev, solo_enc->desc_items, in solo_send_desc()
390 solo_enc->desc_dma, solo_enc->desc_count - 1); in solo_send_desc()
393 /* Extract values from VOP header - VE_STATUSxx */
453 struct solo_dev *solo_dev = solo_enc->solo_dev; in solo_fill_jpeg()
457 vbuf->flags |= V4L2_BUF_FLAG_KEYFRAME; in solo_fill_jpeg()
459 if (vb2_plane_size(vb, 0) < vop_jpeg_size(vh) + solo_enc->jpeg_len) in solo_fill_jpeg()
460 return -EIO; in solo_fill_jpeg()
462 frame_size = ALIGN(vop_jpeg_size(vh) + solo_enc->jpeg_len, DMA_ALIGN); in solo_fill_jpeg()
463 vb2_set_plane_payload(vb, 0, vop_jpeg_size(vh) + solo_enc->jpeg_len); in solo_fill_jpeg()
465 return solo_send_desc(solo_enc, solo_enc->jpeg_len, sgt, in solo_fill_jpeg()
466 vop_jpeg_offset(vh) - SOLO_JPEG_EXT_ADDR(solo_dev), in solo_fill_jpeg()
475 struct solo_dev *solo_dev = solo_enc->solo_dev; in solo_fill_mpeg()
481 return -EIO; in solo_fill_mpeg()
484 vbuf->flags &= ~(V4L2_BUF_FLAG_KEYFRAME | V4L2_BUF_FLAG_PFRAME | in solo_fill_mpeg()
487 skip = solo_enc->vop_len; in solo_fill_mpeg()
488 vbuf->flags |= V4L2_BUF_FLAG_KEYFRAME; in solo_fill_mpeg()
490 solo_enc->vop_len); in solo_fill_mpeg()
492 vbuf->flags |= V4L2_BUF_FLAG_PFRAME; in solo_fill_mpeg()
497 frame_off = (vop_mpeg_offset(vh) - SOLO_MP4E_EXT_ADDR(solo_dev) + in solo_fill_mpeg()
510 const vop_header *vh = enc_buf->vh; in solo_enc_fillbuf()
513 switch (solo_enc->fmt) { in solo_enc_fillbuf()
524 vbuf->sequence = solo_enc->sequence++; in solo_enc_fillbuf()
525 vb->timestamp = ktime_get_ns(); in solo_enc_fillbuf()
528 if (solo_is_motion_on(solo_enc) && enc_buf->motion) { in solo_enc_fillbuf()
534 .frame_sequence = vbuf->sequence, in solo_enc_fillbuf()
535 .region_mask = enc_buf->motion ? 1 : 0, in solo_enc_fillbuf()
539 v4l2_event_queue(solo_enc->vfd, &ev); in solo_enc_fillbuf()
554 mutex_lock(&solo_enc->lock); in solo_enc_handle_one()
555 if (solo_enc->type != enc_buf->type) in solo_enc_handle_one()
558 spin_lock_irqsave(&solo_enc->av_lock, flags); in solo_enc_handle_one()
559 if (list_empty(&solo_enc->vidq_active)) { in solo_enc_handle_one()
560 spin_unlock_irqrestore(&solo_enc->av_lock, flags); in solo_enc_handle_one()
563 vb = list_first_entry(&solo_enc->vidq_active, struct solo_vb2_buf, in solo_enc_handle_one()
565 list_del(&vb->list); in solo_enc_handle_one()
566 spin_unlock_irqrestore(&solo_enc->av_lock, flags); in solo_enc_handle_one()
568 solo_enc_fillbuf(solo_enc, &vb->vb.vb2_buf, enc_buf); in solo_enc_handle_one()
570 mutex_unlock(&solo_enc->lock); in solo_enc_handle_one()
575 wake_up_interruptible_all(&solo_dev->ring_thread_wait); in solo_enc_v4l2_isr()
589 if (cur_q == solo_dev->enc_idx) in solo_handle_ring()
593 SOLO_VE_MPEG4_QUE(solo_dev->enc_idx)); in solo_handle_ring()
594 solo_dev->enc_idx = (solo_dev->enc_idx + 1) % MP4_QS; in solo_handle_ring()
600 ch -= SOLO_MAX_CHANNELS; in solo_handle_ring()
605 solo_enc = solo_dev->v4l2_enc[ch]; in solo_handle_ring()
607 dev_err(&solo_dev->pdev->dev, in solo_handle_ring()
613 if (enc_get_mpeg_dma(solo_dev, solo_dev->vh_dma, off, in solo_handle_ring()
617 enc_buf.vh = solo_dev->vh_buf; in solo_handle_ring()
639 add_wait_queue(&solo_dev->ring_thread_wait, &wait); in solo_ring_thread()
644 if (timeout == -ERESTARTSYS || kthread_should_stop()) in solo_ring_thread()
650 remove_wait_queue(&solo_dev->ring_thread_wait, &wait); in solo_ring_thread()
657 unsigned int *num_planes, unsigned int sizes[], in solo_enc_queue_setup() argument
660 sizes[0] = FRAME_BUF_SIZE; in solo_enc_queue_setup()
672 struct vb2_queue *vq = vb->vb2_queue; in solo_enc_buf_queue()
677 spin_lock(&solo_enc->av_lock); in solo_enc_buf_queue()
678 list_add_tail(&solo_vb->list, &solo_enc->vidq_active); in solo_enc_buf_queue()
679 spin_unlock(&solo_enc->av_lock); in solo_enc_buf_queue()
684 solo_dev->ring_thread = kthread_run(solo_ring_thread, solo_dev, in solo_ring_start()
686 if (IS_ERR(solo_dev->ring_thread)) { in solo_ring_start()
687 int err = PTR_ERR(solo_dev->ring_thread); in solo_ring_start()
689 solo_dev->ring_thread = NULL; in solo_ring_start()
700 if (solo_dev->ring_thread) { in solo_ring_stop()
701 kthread_stop(solo_dev->ring_thread); in solo_ring_stop()
702 solo_dev->ring_thread = NULL; in solo_ring_stop()
720 spin_lock_irqsave(&solo_enc->av_lock, flags); in solo_enc_stop_streaming()
722 while (!list_empty(&solo_enc->vidq_active)) { in solo_enc_stop_streaming()
724 solo_enc->vidq_active.next, in solo_enc_stop_streaming()
727 list_del(&buf->list); in solo_enc_stop_streaming()
728 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR); in solo_enc_stop_streaming()
730 spin_unlock_irqrestore(&solo_enc->av_lock, flags); in solo_enc_stop_streaming()
736 struct solo_enc_dev *solo_enc = vb2_get_drv_priv(vb->vb2_queue); in solo_enc_buf_finish()
739 switch (solo_enc->fmt) { in solo_enc_buf_finish()
742 if (vbuf->flags & V4L2_BUF_FLAG_KEYFRAME) in solo_enc_buf_finish()
743 sg_copy_from_buffer(sgt->sgl, sgt->nents, in solo_enc_buf_finish()
744 solo_enc->vop, solo_enc->vop_len); in solo_enc_buf_finish()
747 sg_copy_from_buffer(sgt->sgl, sgt->nents, in solo_enc_buf_finish()
748 solo_enc->jpeg_header, solo_enc->jpeg_len); in solo_enc_buf_finish()
768 strscpy(cap->driver, SOLO6X10_NAME, sizeof(cap->driver)); in solo_enc_querycap()
769 snprintf(cap->card, sizeof(cap->card), "Softlogic 6x10 Enc %d", in solo_enc_querycap()
770 solo_enc->ch); in solo_enc_querycap()
778 struct solo_dev *solo_dev = solo_enc->solo_dev; in solo_enc_enum_input()
780 if (input->index) in solo_enc_enum_input()
781 return -EINVAL; in solo_enc_enum_input()
783 snprintf(input->name, sizeof(input->name), "Encoder %d", in solo_enc_enum_input()
784 solo_enc->ch + 1); in solo_enc_enum_input()
785 input->type = V4L2_INPUT_TYPE_CAMERA; in solo_enc_enum_input()
786 input->std = solo_enc->vfd->tvnorms; in solo_enc_enum_input()
788 if (!tw28_get_video_status(solo_dev, solo_enc->ch)) in solo_enc_enum_input()
789 input->status = V4L2_IN_ST_NO_SIGNAL; in solo_enc_enum_input()
798 return -EINVAL; in solo_enc_set_input()
815 int dev_type = solo_enc->solo_dev->type; in solo_enc_enum_fmt_cap()
817 switch (f->index) { in solo_enc_enum_fmt_cap()
821 f->pixelformat = V4L2_PIX_FMT_MPEG4; in solo_enc_enum_fmt_cap()
824 f->pixelformat = V4L2_PIX_FMT_H264; in solo_enc_enum_fmt_cap()
829 f->pixelformat = V4L2_PIX_FMT_MJPEG; in solo_enc_enum_fmt_cap()
832 return -EINVAL; in solo_enc_enum_fmt_cap()
841 || pixfmt == V4L2_PIX_FMT_MJPEG ? 0 : -EINVAL; in solo_valid_pixfmt()
848 struct solo_dev *solo_dev = solo_enc->solo_dev; in solo_enc_try_fmt_cap()
849 struct v4l2_pix_format *pix = &f->fmt.pix; in solo_enc_try_fmt_cap() local
851 if (solo_valid_pixfmt(pix->pixelformat, solo_dev->type)) in solo_enc_try_fmt_cap()
852 return -EINVAL; in solo_enc_try_fmt_cap()
854 if (pix->width < solo_dev->video_hsize || in solo_enc_try_fmt_cap()
855 pix->height < solo_dev->video_vsize << 1) { in solo_enc_try_fmt_cap()
857 pix->width = solo_dev->video_hsize >> 1; in solo_enc_try_fmt_cap()
858 pix->height = solo_dev->video_vsize; in solo_enc_try_fmt_cap()
861 pix->width = solo_dev->video_hsize; in solo_enc_try_fmt_cap()
862 pix->height = solo_dev->video_vsize << 1; in solo_enc_try_fmt_cap()
865 switch (pix->field) { in solo_enc_try_fmt_cap()
871 pix->field = V4L2_FIELD_INTERLACED; in solo_enc_try_fmt_cap()
876 pix->colorspace = V4L2_COLORSPACE_SMPTE170M; in solo_enc_try_fmt_cap()
877 pix->sizeimage = FRAME_BUF_SIZE; in solo_enc_try_fmt_cap()
878 pix->bytesperline = 0; in solo_enc_try_fmt_cap()
887 struct solo_dev *solo_dev = solo_enc->solo_dev; in solo_enc_set_fmt_cap()
888 struct v4l2_pix_format *pix = &f->fmt.pix; in solo_enc_set_fmt_cap() local
891 if (vb2_is_busy(&solo_enc->vidq)) in solo_enc_set_fmt_cap()
892 return -EBUSY; in solo_enc_set_fmt_cap()
898 if (pix->width == solo_dev->video_hsize) in solo_enc_set_fmt_cap()
899 solo_enc->mode = SOLO_ENC_MODE_D1; in solo_enc_set_fmt_cap()
901 solo_enc->mode = SOLO_ENC_MODE_CIF; in solo_enc_set_fmt_cap()
904 solo_enc->fmt = pix->pixelformat; in solo_enc_set_fmt_cap()
913 if (pix->priv) in solo_enc_set_fmt_cap()
914 solo_enc->type = SOLO_ENC_TYPE_EXT; in solo_enc_set_fmt_cap()
924 struct v4l2_pix_format *pix = &f->fmt.pix; in solo_enc_get_fmt_cap() local
926 pix->width = solo_enc->width; in solo_enc_get_fmt_cap()
927 pix->height = solo_enc->height; in solo_enc_get_fmt_cap()
928 pix->pixelformat = solo_enc->fmt; in solo_enc_get_fmt_cap()
929 pix->field = solo_enc->interlaced ? V4L2_FIELD_INTERLACED : in solo_enc_get_fmt_cap()
931 pix->sizeimage = FRAME_BUF_SIZE; in solo_enc_get_fmt_cap()
932 pix->colorspace = V4L2_COLORSPACE_SMPTE170M; in solo_enc_get_fmt_cap()
940 struct solo_dev *solo_dev = solo_enc->solo_dev; in solo_enc_g_std()
942 if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) in solo_enc_g_std()
953 return solo_set_video_type(solo_enc->solo_dev, std & V4L2_STD_625_50); in solo_enc_s_std()
960 struct solo_dev *solo_dev = solo_enc->solo_dev; in solo_enum_framesizes()
962 if (solo_valid_pixfmt(fsize->pixel_format, solo_dev->type)) in solo_enum_framesizes()
963 return -EINVAL; in solo_enum_framesizes()
965 switch (fsize->index) { in solo_enum_framesizes()
967 fsize->discrete.width = solo_dev->video_hsize >> 1; in solo_enum_framesizes()
968 fsize->discrete.height = solo_dev->video_vsize; in solo_enum_framesizes()
971 fsize->discrete.width = solo_dev->video_hsize; in solo_enum_framesizes()
972 fsize->discrete.height = solo_dev->video_vsize << 1; in solo_enum_framesizes()
975 return -EINVAL; in solo_enum_framesizes()
978 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; in solo_enum_framesizes()
987 struct solo_dev *solo_dev = solo_enc->solo_dev; in solo_enum_frameintervals()
989 if (solo_valid_pixfmt(fintv->pixel_format, solo_dev->type)) in solo_enum_frameintervals()
990 return -EINVAL; in solo_enum_frameintervals()
991 if (fintv->index) in solo_enum_frameintervals()
992 return -EINVAL; in solo_enum_frameintervals()
993 if ((fintv->width != solo_dev->video_hsize >> 1 || in solo_enum_frameintervals()
994 fintv->height != solo_dev->video_vsize) && in solo_enum_frameintervals()
995 (fintv->width != solo_dev->video_hsize || in solo_enum_frameintervals()
996 fintv->height != solo_dev->video_vsize << 1)) in solo_enum_frameintervals()
997 return -EINVAL; in solo_enum_frameintervals()
999 fintv->type = V4L2_FRMIVAL_TYPE_STEPWISE; in solo_enum_frameintervals()
1001 fintv->stepwise.min.numerator = 1; in solo_enum_frameintervals()
1002 fintv->stepwise.min.denominator = solo_dev->fps; in solo_enum_frameintervals()
1004 fintv->stepwise.max.numerator = 15; in solo_enum_frameintervals()
1005 fintv->stepwise.max.denominator = solo_dev->fps; in solo_enum_frameintervals()
1007 fintv->stepwise.step.numerator = 1; in solo_enum_frameintervals()
1008 fintv->stepwise.step.denominator = solo_dev->fps; in solo_enum_frameintervals()
1017 struct v4l2_captureparm *cp = &sp->parm.capture; in solo_g_parm()
1019 cp->capability = V4L2_CAP_TIMEPERFRAME; in solo_g_parm()
1020 cp->timeperframe.numerator = solo_enc->interval; in solo_g_parm()
1021 cp->timeperframe.denominator = solo_enc->solo_dev->fps; in solo_g_parm()
1022 cp->capturemode = 0; in solo_g_parm()
1024 cp->readbuffers = 2; in solo_g_parm()
1036 return min(15U, n / d + (n % d >= (fps >> 1))); in calc_interval()
1043 struct v4l2_fract *t = &sp->parm.capture.timeperframe; in solo_s_parm()
1044 u8 fps = solo_enc->solo_dev->fps; in solo_s_parm()
1046 if (vb2_is_streaming(&solo_enc->vidq)) in solo_s_parm()
1047 return -EBUSY; in solo_s_parm()
1049 solo_enc->interval = calc_interval(fps, t->numerator, t->denominator); in solo_s_parm()
1057 container_of(ctrl->handler, struct solo_enc_dev, hdl); in solo_s_ctrl()
1058 struct solo_dev *solo_dev = solo_enc->solo_dev; in solo_s_ctrl()
1061 switch (ctrl->id) { in solo_s_ctrl()
1067 return tw28_set_ctrl_val(solo_dev, ctrl->id, solo_enc->ch, in solo_s_ctrl()
1068 ctrl->val); in solo_s_ctrl()
1070 solo_enc->gop = ctrl->val; in solo_s_ctrl()
1071 solo_reg_write(solo_dev, SOLO_VE_CH_GOP(solo_enc->ch), solo_enc->gop); in solo_s_ctrl()
1072 solo_reg_write(solo_dev, SOLO_VE_CH_GOP_E(solo_enc->ch), solo_enc->gop); in solo_s_ctrl()
1075 solo_enc->qp = ctrl->val; in solo_s_ctrl()
1076 solo_reg_write(solo_dev, SOLO_VE_CH_QP(solo_enc->ch), solo_enc->qp); in solo_s_ctrl()
1077 solo_reg_write(solo_dev, SOLO_VE_CH_QP_E(solo_enc->ch), solo_enc->qp); in solo_s_ctrl()
1080 solo_enc->motion_thresh = ctrl->val << 8; in solo_s_ctrl()
1081 if (!solo_enc->motion_global || !solo_enc->motion_enabled) in solo_s_ctrl()
1083 return solo_set_motion_threshold(solo_dev, solo_enc->ch, in solo_s_ctrl()
1084 solo_enc->motion_thresh); in solo_s_ctrl()
1086 solo_enc->motion_global = ctrl->val == V4L2_DETECT_MD_MODE_GLOBAL; in solo_s_ctrl()
1087 solo_enc->motion_enabled = ctrl->val > V4L2_DETECT_MD_MODE_DISABLED; in solo_s_ctrl()
1088 if (ctrl->val) { in solo_s_ctrl()
1089 if (solo_enc->motion_global) in solo_s_ctrl()
1090 err = solo_set_motion_threshold(solo_dev, solo_enc->ch, in solo_s_ctrl()
1091 solo_enc->motion_thresh); in solo_s_ctrl()
1093 err = solo_set_motion_block(solo_dev, solo_enc->ch, in solo_s_ctrl()
1094 solo_enc->md_thresholds->p_cur.p_u16); in solo_s_ctrl()
1098 solo_motion_toggle(solo_enc, ctrl->val); in solo_s_ctrl()
1101 if (solo_enc->motion_enabled && !solo_enc->motion_global) in solo_s_ctrl()
1102 return solo_set_motion_block(solo_dev, solo_enc->ch, in solo_s_ctrl()
1103 solo_enc->md_thresholds->p_new.p_u16); in solo_s_ctrl()
1106 strscpy(solo_enc->osd_text, ctrl->p_new.p_char, in solo_s_ctrl()
1107 sizeof(solo_enc->osd_text)); in solo_s_ctrl()
1110 return -EINVAL; in solo_s_ctrl()
1120 switch (sub->type) { in solo_subscribe_event()
1176 .minor = -1,
1215 return ERR_PTR(-ENOMEM); in solo_enc_alloc()
1217 hdl = &solo_enc->hdl; in solo_enc_alloc()
1231 V4L2_CID_MPEG_VIDEO_GOP_SIZE, 1, 255, 1, solo_dev->fps); in solo_enc_alloc()
1242 solo_enc->md_thresholds = in solo_enc_alloc()
1244 if (hdl->error) { in solo_enc_alloc()
1245 ret = hdl->error; in solo_enc_alloc()
1249 solo_enc->solo_dev = solo_dev; in solo_enc_alloc()
1250 solo_enc->ch = ch; in solo_enc_alloc()
1251 mutex_init(&solo_enc->lock); in solo_enc_alloc()
1252 spin_lock_init(&solo_enc->av_lock); in solo_enc_alloc()
1253 INIT_LIST_HEAD(&solo_enc->vidq_active); in solo_enc_alloc()
1254 solo_enc->fmt = (solo_dev->type == SOLO_DEV_6010) ? in solo_enc_alloc()
1256 solo_enc->type = SOLO_ENC_TYPE_STD; in solo_enc_alloc()
1258 solo_enc->qp = SOLO_DEFAULT_QP; in solo_enc_alloc()
1259 solo_enc->gop = solo_dev->fps; in solo_enc_alloc()
1260 solo_enc->interval = 1; in solo_enc_alloc()
1261 solo_enc->mode = SOLO_ENC_MODE_CIF; in solo_enc_alloc()
1262 solo_enc->motion_global = true; in solo_enc_alloc()
1263 solo_enc->motion_thresh = SOLO_DEF_MOT_THRESH; in solo_enc_alloc()
1264 solo_enc->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in solo_enc_alloc()
1265 solo_enc->vidq.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; in solo_enc_alloc()
1266 solo_enc->vidq.ops = &solo_enc_video_qops; in solo_enc_alloc()
1267 solo_enc->vidq.mem_ops = &vb2_dma_sg_memops; in solo_enc_alloc()
1268 solo_enc->vidq.drv_priv = solo_enc; in solo_enc_alloc()
1269 solo_enc->vidq.gfp_flags = __GFP_DMA32 | __GFP_KSWAPD_RECLAIM; in solo_enc_alloc()
1270 solo_enc->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; in solo_enc_alloc()
1271 solo_enc->vidq.buf_struct_size = sizeof(struct solo_vb2_buf); in solo_enc_alloc()
1272 solo_enc->vidq.lock = &solo_enc->lock; in solo_enc_alloc()
1273 solo_enc->vidq.dev = &solo_dev->pdev->dev; in solo_enc_alloc()
1274 ret = vb2_queue_init(&solo_enc->vidq); in solo_enc_alloc()
1279 spin_lock_init(&solo_enc->motion_lock); in solo_enc_alloc()
1282 solo_enc->jpeg_len = sizeof(jpeg_header); in solo_enc_alloc()
1283 memcpy(solo_enc->jpeg_header, jpeg_header, solo_enc->jpeg_len); in solo_enc_alloc()
1285 solo_enc->desc_nelts = 32; in solo_enc_alloc()
1286 solo_enc->desc_items = dma_alloc_coherent(&solo_dev->pdev->dev, in solo_enc_alloc()
1288 solo_enc->desc_nelts, in solo_enc_alloc()
1289 &solo_enc->desc_dma, in solo_enc_alloc()
1291 ret = -ENOMEM; in solo_enc_alloc()
1292 if (solo_enc->desc_items == NULL) in solo_enc_alloc()
1295 solo_enc->vfd = video_device_alloc(); in solo_enc_alloc()
1296 if (!solo_enc->vfd) in solo_enc_alloc()
1299 *solo_enc->vfd = solo_enc_template; in solo_enc_alloc()
1300 solo_enc->vfd->v4l2_dev = &solo_dev->v4l2_dev; in solo_enc_alloc()
1301 solo_enc->vfd->ctrl_handler = hdl; in solo_enc_alloc()
1302 solo_enc->vfd->queue = &solo_enc->vidq; in solo_enc_alloc()
1303 solo_enc->vfd->lock = &solo_enc->lock; in solo_enc_alloc()
1304 video_set_drvdata(solo_enc->vfd, solo_enc); in solo_enc_alloc()
1305 ret = video_register_device(solo_enc->vfd, VFL_TYPE_VIDEO, nr); in solo_enc_alloc()
1309 snprintf(solo_enc->vfd->name, sizeof(solo_enc->vfd->name), in solo_enc_alloc()
1310 "%s-enc (%i/%i)", SOLO6X10_NAME, solo_dev->vfd->num, in solo_enc_alloc()
1311 solo_enc->vfd->num); in solo_enc_alloc()
1316 video_device_release(solo_enc->vfd); in solo_enc_alloc()
1318 dma_free_coherent(&solo_enc->solo_dev->pdev->dev, in solo_enc_alloc()
1319 sizeof(struct solo_p2m_desc) * solo_enc->desc_nelts, in solo_enc_alloc()
1320 solo_enc->desc_items, solo_enc->desc_dma); in solo_enc_alloc()
1332 dma_free_coherent(&solo_enc->solo_dev->pdev->dev, in solo_enc_free()
1333 sizeof(struct solo_p2m_desc) * solo_enc->desc_nelts, in solo_enc_free()
1334 solo_enc->desc_items, solo_enc->desc_dma); in solo_enc_free()
1335 video_unregister_device(solo_enc->vfd); in solo_enc_free()
1336 v4l2_ctrl_handler_free(&solo_enc->hdl); in solo_enc_free()
1344 init_waitqueue_head(&solo_dev->ring_thread_wait); in solo_enc_v4l2_init()
1346 solo_dev->vh_size = sizeof(vop_header); in solo_enc_v4l2_init()
1347 solo_dev->vh_buf = dma_alloc_coherent(&solo_dev->pdev->dev, in solo_enc_v4l2_init()
1348 solo_dev->vh_size, in solo_enc_v4l2_init()
1349 &solo_dev->vh_dma, GFP_KERNEL); in solo_enc_v4l2_init()
1350 if (solo_dev->vh_buf == NULL) in solo_enc_v4l2_init()
1351 return -ENOMEM; in solo_enc_v4l2_init()
1353 for (i = 0; i < solo_dev->nr_chans; i++) { in solo_enc_v4l2_init()
1354 solo_dev->v4l2_enc[i] = solo_enc_alloc(solo_dev, i, nr); in solo_enc_v4l2_init()
1355 if (IS_ERR(solo_dev->v4l2_enc[i])) in solo_enc_v4l2_init()
1359 if (i != solo_dev->nr_chans) { in solo_enc_v4l2_init()
1360 int ret = PTR_ERR(solo_dev->v4l2_enc[i]); in solo_enc_v4l2_init()
1362 while (i--) in solo_enc_v4l2_init()
1363 solo_enc_free(solo_dev->v4l2_enc[i]); in solo_enc_v4l2_init()
1364 dma_free_coherent(&solo_dev->pdev->dev, solo_dev->vh_size, in solo_enc_v4l2_init()
1365 solo_dev->vh_buf, solo_dev->vh_dma); in solo_enc_v4l2_init()
1366 solo_dev->vh_buf = NULL; in solo_enc_v4l2_init()
1370 if (solo_dev->type == SOLO_DEV_6010) in solo_enc_v4l2_init()
1371 solo_dev->enc_bw_remain = solo_dev->fps * 4 * 4; in solo_enc_v4l2_init()
1373 solo_dev->enc_bw_remain = solo_dev->fps * 4 * 5; in solo_enc_v4l2_init()
1375 dev_info(&solo_dev->pdev->dev, "Encoders as /dev/video%d-%d\n", in solo_enc_v4l2_init()
1376 solo_dev->v4l2_enc[0]->vfd->num, in solo_enc_v4l2_init()
1377 solo_dev->v4l2_enc[solo_dev->nr_chans - 1]->vfd->num); in solo_enc_v4l2_init()
1388 for (i = 0; i < solo_dev->nr_chans; i++) in solo_enc_v4l2_exit()
1389 solo_enc_free(solo_dev->v4l2_enc[i]); in solo_enc_v4l2_exit()
1391 if (solo_dev->vh_buf) in solo_enc_v4l2_exit()
1392 dma_free_coherent(&solo_dev->pdev->dev, solo_dev->vh_size, in solo_enc_v4l2_exit()
1393 solo_dev->vh_buf, solo_dev->vh_dma); in solo_enc_v4l2_exit()