Lines Matching refs:solo_enc

93 static int solo_is_motion_on(struct solo_enc_dev *solo_enc)
95 struct solo_dev *solo_dev = solo_enc->solo_dev;
97 return (solo_dev->motion_mask >> solo_enc->ch) & 1;
100 static int solo_motion_detected(struct solo_enc_dev *solo_enc)
102 struct solo_dev *solo_dev = solo_enc->solo_dev;
104 u32 ch_mask = 1 << solo_enc->ch;
107 spin_lock_irqsave(&solo_enc->motion_lock, flags);
112 spin_unlock_irqrestore(&solo_enc->motion_lock, flags);
117 static void solo_motion_toggle(struct solo_enc_dev *solo_enc, int on)
119 struct solo_dev *solo_dev = solo_enc->solo_dev;
120 u32 mask = 1 << solo_enc->ch;
123 spin_lock_irqsave(&solo_enc->motion_lock, flags);
136 spin_unlock_irqrestore(&solo_enc->motion_lock, flags);
139 void solo_update_mode(struct solo_enc_dev *solo_enc)
141 struct solo_dev *solo_dev = solo_enc->solo_dev;
145 solo_enc->interlaced = (solo_enc->mode & 0x08) ? 1 : 0;
146 solo_enc->bw_weight = max(solo_dev->fps / solo_enc->interval, 1);
148 if (solo_enc->mode == SOLO_ENC_MODE_CIF) {
149 solo_enc->width = solo_dev->video_hsize >> 1;
150 solo_enc->height = solo_dev->video_vsize;
169 solo_enc->width = solo_dev->video_hsize;
170 solo_enc->height = solo_dev->video_vsize << 1;
171 solo_enc->bw_weight <<= 2;
191 memcpy(solo_enc->vop, vop, vop_len);
196 u16 interval = solo_enc->interval * 1000;
198 vop = solo_enc->vop;
208 solo_enc->vop_len = vop_len;
211 vop = solo_enc->jpeg_header;
212 vop[SOF0_START + 5] = 0xff & (solo_enc->height >> 8);
213 vop[SOF0_START + 6] = 0xff & solo_enc->height;
214 vop[SOF0_START + 7] = 0xff & (solo_enc->width >> 8);
215 vop[SOF0_START + 8] = 0xff & solo_enc->width;
218 jpeg_dqt[solo_g_jpeg_qp(solo_dev, solo_enc->ch)], DQT_LEN);
221 static int solo_enc_on(struct solo_enc_dev *solo_enc)
223 u8 ch = solo_enc->ch;
224 struct solo_dev *solo_dev = solo_enc->solo_dev;
227 solo_update_mode(solo_enc);
230 if (solo_enc->bw_weight > solo_dev->enc_bw_remain)
232 solo_enc->sequence = 0;
233 solo_dev->enc_bw_remain -= solo_enc->bw_weight;
235 if (solo_enc->type == SOLO_ENC_TYPE_EXT)
243 solo_enc->interlaced ? 1 : 0);
245 if (solo_enc->interlaced)
246 interval = solo_enc->interval - 1;
248 interval = solo_enc->interval;
251 solo_reg_write(solo_dev, SOLO_VE_CH_GOP(ch), solo_enc->gop);
252 solo_reg_write(solo_dev, SOLO_VE_CH_QP(ch), solo_enc->qp);
256 solo_reg_write(solo_dev, SOLO_VE_CH_GOP_E(ch), solo_enc->gop);
257 solo_reg_write(solo_dev, SOLO_VE_CH_QP_E(ch), solo_enc->qp);
261 solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(ch), solo_enc->mode);
266 static void solo_enc_off(struct solo_enc_dev *solo_enc)
268 struct solo_dev *solo_dev = solo_enc->solo_dev;
270 solo_dev->enc_bw_remain += solo_enc->bw_weight;
272 solo_reg_write(solo_dev, SOLO_CAP_CH_SCALE(solo_enc->ch), 0);
273 solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(solo_enc->ch), 0);
308 static int solo_send_desc(struct solo_enc_dev *solo_enc, int skip,
312 struct solo_dev *solo_dev = solo_enc->solo_dev;
320 solo_enc->desc_count = 1;
328 desc = &solo_enc->desc_items[solo_enc->desc_count++];
364 solo_enc->desc_count--;
376 if (solo_enc->desc_count >= (solo_enc->desc_nelts - 1)) {
377 ret = solo_p2m_dma_desc(solo_dev, solo_enc->desc_items,
378 solo_enc->desc_dma,
379 solo_enc->desc_count - 1);
382 solo_enc->desc_count = 1;
386 if (solo_enc->desc_count <= 1)
389 return solo_p2m_dma_desc(solo_dev, solo_enc->desc_items,
390 solo_enc->desc_dma, solo_enc->desc_count - 1);
449 static int solo_fill_jpeg(struct solo_enc_dev *solo_enc,
453 struct solo_dev *solo_dev = solo_enc->solo_dev;
459 if (vb2_plane_size(vb, 0) < vop_jpeg_size(vh) + solo_enc->jpeg_len)
462 frame_size = ALIGN(vop_jpeg_size(vh) + solo_enc->jpeg_len, DMA_ALIGN);
463 vb2_set_plane_payload(vb, 0, vop_jpeg_size(vh) + solo_enc->jpeg_len);
465 return solo_send_desc(solo_enc, solo_enc->jpeg_len, sgt,
471 static int solo_fill_mpeg(struct solo_enc_dev *solo_enc,
475 struct solo_dev *solo_dev = solo_enc->solo_dev;
487 skip = solo_enc->vop_len;
490 solo_enc->vop_len);
501 return solo_send_desc(solo_enc, skip, sgt, frame_off, frame_size,
506 static int solo_enc_fillbuf(struct solo_enc_dev *solo_enc,
513 switch (solo_enc->fmt) {
516 ret = solo_fill_mpeg(solo_enc, vb, vh);
519 ret = solo_fill_jpeg(solo_enc, vb, vh);
524 vbuf->sequence = solo_enc->sequence++;
528 if (solo_is_motion_on(solo_enc) && enc_buf->motion) {
539 v4l2_event_queue(solo_enc->vfd, &ev);
548 static void solo_enc_handle_one(struct solo_enc_dev *solo_enc,
554 mutex_lock(&solo_enc->lock);
555 if (solo_enc->type != enc_buf->type)
558 spin_lock_irqsave(&solo_enc->av_lock, flags);
559 if (list_empty(&solo_enc->vidq_active)) {
560 spin_unlock_irqrestore(&solo_enc->av_lock, flags);
563 vb = list_first_entry(&solo_enc->vidq_active, struct solo_vb2_buf,
566 spin_unlock_irqrestore(&solo_enc->av_lock, flags);
568 solo_enc_fillbuf(solo_enc, &vb->vb.vb2_buf, enc_buf);
570 mutex_unlock(&solo_enc->lock);
581 struct solo_enc_dev *solo_enc;
605 solo_enc = solo_dev->v4l2_enc[ch];
606 if (solo_enc == NULL) {
624 if (solo_motion_detected(solo_enc))
629 solo_enc_handle_one(solo_enc, &enc_buf);
673 struct solo_enc_dev *solo_enc = vb2_get_drv_priv(vq);
677 spin_lock(&solo_enc->av_lock);
678 list_add_tail(&solo_vb->list, &solo_enc->vidq_active);
679 spin_unlock(&solo_enc->av_lock);
710 struct solo_enc_dev *solo_enc = vb2_get_drv_priv(q);
712 return solo_enc_on(solo_enc);
717 struct solo_enc_dev *solo_enc = vb2_get_drv_priv(q);
720 spin_lock_irqsave(&solo_enc->av_lock, flags);
721 solo_enc_off(solo_enc);
722 while (!list_empty(&solo_enc->vidq_active)) {
724 solo_enc->vidq_active.next,
730 spin_unlock_irqrestore(&solo_enc->av_lock, flags);
736 struct solo_enc_dev *solo_enc = vb2_get_drv_priv(vb->vb2_queue);
739 switch (solo_enc->fmt) {
744 solo_enc->vop, solo_enc->vop_len);
748 solo_enc->jpeg_header, solo_enc->jpeg_len);
766 struct solo_enc_dev *solo_enc = video_drvdata(file);
767 struct solo_dev *solo_dev = solo_enc->solo_dev;
771 solo_enc->ch);
780 struct solo_enc_dev *solo_enc = video_drvdata(file);
781 struct solo_dev *solo_dev = solo_enc->solo_dev;
787 solo_enc->ch + 1);
789 input->std = solo_enc->vfd->tvnorms;
791 if (!tw28_get_video_status(solo_dev, solo_enc->ch))
817 struct solo_enc_dev *solo_enc = video_drvdata(file);
818 int dev_type = solo_enc->solo_dev->type;
850 struct solo_enc_dev *solo_enc = video_drvdata(file);
851 struct solo_dev *solo_dev = solo_enc->solo_dev;
889 struct solo_enc_dev *solo_enc = video_drvdata(file);
890 struct solo_dev *solo_dev = solo_enc->solo_dev;
894 if (vb2_is_busy(&solo_enc->vidq))
902 solo_enc->mode = SOLO_ENC_MODE_D1;
904 solo_enc->mode = SOLO_ENC_MODE_CIF;
907 solo_enc->fmt = pix->pixelformat;
917 solo_enc->type = SOLO_ENC_TYPE_EXT;
919 solo_update_mode(solo_enc);
926 struct solo_enc_dev *solo_enc = video_drvdata(file);
929 pix->width = solo_enc->width;
930 pix->height = solo_enc->height;
931 pix->pixelformat = solo_enc->fmt;
932 pix->field = solo_enc->interlaced ? V4L2_FIELD_INTERLACED :
942 struct solo_enc_dev *solo_enc = video_drvdata(file);
943 struct solo_dev *solo_dev = solo_enc->solo_dev;
954 struct solo_enc_dev *solo_enc = video_drvdata(file);
956 return solo_set_video_type(solo_enc->solo_dev, std & V4L2_STD_625_50);
962 struct solo_enc_dev *solo_enc = video_drvdata(file);
963 struct solo_dev *solo_dev = solo_enc->solo_dev;
989 struct solo_enc_dev *solo_enc = video_drvdata(file);
990 struct solo_dev *solo_dev = solo_enc->solo_dev;
1019 struct solo_enc_dev *solo_enc = video_drvdata(file);
1023 cp->timeperframe.numerator = solo_enc->interval;
1024 cp->timeperframe.denominator = solo_enc->solo_dev->fps;
1045 struct solo_enc_dev *solo_enc = video_drvdata(file);
1047 u8 fps = solo_enc->solo_dev->fps;
1049 if (vb2_is_streaming(&solo_enc->vidq))
1052 solo_enc->interval = calc_interval(fps, t->numerator, t->denominator);
1053 solo_update_mode(solo_enc);
1059 struct solo_enc_dev *solo_enc =
1061 struct solo_dev *solo_dev = solo_enc->solo_dev;
1070 return tw28_set_ctrl_val(solo_dev, ctrl->id, solo_enc->ch,
1073 solo_enc->gop = ctrl->val;
1074 solo_reg_write(solo_dev, SOLO_VE_CH_GOP(solo_enc->ch), solo_enc->gop);
1075 solo_reg_write(solo_dev, SOLO_VE_CH_GOP_E(solo_enc->ch), solo_enc->gop);
1078 solo_enc->qp = ctrl->val;
1079 solo_reg_write(solo_dev, SOLO_VE_CH_QP(solo_enc->ch), solo_enc->qp);
1080 solo_reg_write(solo_dev, SOLO_VE_CH_QP_E(solo_enc->ch), solo_enc->qp);
1083 solo_enc->motion_thresh = ctrl->val << 8;
1084 if (!solo_enc->motion_global || !solo_enc->motion_enabled)
1086 return solo_set_motion_threshold(solo_dev, solo_enc->ch,
1087 solo_enc->motion_thresh);
1089 solo_enc->motion_global = ctrl->val == V4L2_DETECT_MD_MODE_GLOBAL;
1090 solo_enc->motion_enabled = ctrl->val > V4L2_DETECT_MD_MODE_DISABLED;
1092 if (solo_enc->motion_global)
1093 err = solo_set_motion_threshold(solo_dev, solo_enc->ch,
1094 solo_enc->motion_thresh);
1096 err = solo_set_motion_block(solo_dev, solo_enc->ch,
1097 solo_enc->md_thresholds->p_cur.p_u16);
1101 solo_motion_toggle(solo_enc, ctrl->val);
1104 if (solo_enc->motion_enabled && !solo_enc->motion_global)
1105 return solo_set_motion_block(solo_dev, solo_enc->ch,
1106 solo_enc->md_thresholds->p_new.p_u16);
1109 strscpy(solo_enc->osd_text, ctrl->p_new.p_char,
1110 sizeof(solo_enc->osd_text));
1111 return solo_osd_print(solo_enc);
1212 struct solo_enc_dev *solo_enc;
1216 solo_enc = kzalloc(sizeof(*solo_enc), GFP_KERNEL);
1217 if (!solo_enc)
1220 hdl = &solo_enc->hdl;
1245 solo_enc->md_thresholds =
1252 solo_enc->solo_dev = solo_dev;
1253 solo_enc->ch = ch;
1254 mutex_init(&solo_enc->lock);
1255 spin_lock_init(&solo_enc->av_lock);
1256 INIT_LIST_HEAD(&solo_enc->vidq_active);
1257 solo_enc->fmt = (solo_dev->type == SOLO_DEV_6010) ?
1259 solo_enc->type = SOLO_ENC_TYPE_STD;
1261 solo_enc->qp = SOLO_DEFAULT_QP;
1262 solo_enc->gop = solo_dev->fps;
1263 solo_enc->interval = 1;
1264 solo_enc->mode = SOLO_ENC_MODE_CIF;
1265 solo_enc->motion_global = true;
1266 solo_enc->motion_thresh = SOLO_DEF_MOT_THRESH;
1267 solo_enc->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1268 solo_enc->vidq.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
1269 solo_enc->vidq.ops = &solo_enc_video_qops;
1270 solo_enc->vidq.mem_ops = &vb2_dma_sg_memops;
1271 solo_enc->vidq.drv_priv = solo_enc;
1272 solo_enc->vidq.gfp_flags = __GFP_DMA32 | __GFP_KSWAPD_RECLAIM;
1273 solo_enc->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
1274 solo_enc->vidq.buf_struct_size = sizeof(struct solo_vb2_buf);
1275 solo_enc->vidq.lock = &solo_enc->lock;
1276 solo_enc->vidq.dev = &solo_dev->pdev->dev;
1277 ret = vb2_queue_init(&solo_enc->vidq);
1280 solo_update_mode(solo_enc);
1282 spin_lock_init(&solo_enc->motion_lock);
1285 solo_enc->jpeg_len = sizeof(jpeg_header);
1286 memcpy(solo_enc->jpeg_header, jpeg_header, solo_enc->jpeg_len);
1288 solo_enc->desc_nelts = 32;
1289 solo_enc->desc_items = pci_alloc_consistent(solo_dev->pdev,
1291 solo_enc->desc_nelts,
1292 &solo_enc->desc_dma);
1294 if (solo_enc->desc_items == NULL)
1297 solo_enc->vfd = video_device_alloc();
1298 if (!solo_enc->vfd)
1301 *solo_enc->vfd = solo_enc_template;
1302 solo_enc->vfd->v4l2_dev = &solo_dev->v4l2_dev;
1303 solo_enc->vfd->ctrl_handler = hdl;
1304 solo_enc->vfd->queue = &solo_enc->vidq;
1305 solo_enc->vfd->lock = &solo_enc->lock;
1306 video_set_drvdata(solo_enc->vfd, solo_enc);
1307 ret = video_register_device(solo_enc->vfd, VFL_TYPE_VIDEO, nr);
1311 snprintf(solo_enc->vfd->name, sizeof(solo_enc->vfd->name),
1313 solo_enc->vfd->num);
1315 return solo_enc;
1318 video_device_release(solo_enc->vfd);
1320 pci_free_consistent(solo_enc->solo_dev->pdev,
1321 sizeof(struct solo_p2m_desc) * solo_enc->desc_nelts,
1322 solo_enc->desc_items, solo_enc->desc_dma);
1325 kfree(solo_enc);
1329 static void solo_enc_free(struct solo_enc_dev *solo_enc)
1331 if (solo_enc == NULL)
1334 pci_free_consistent(solo_enc->solo_dev->pdev,
1335 sizeof(struct solo_p2m_desc) * solo_enc->desc_nelts,
1336 solo_enc->desc_items, solo_enc->desc_dma);
1337 video_unregister_device(solo_enc->vfd);
1338 v4l2_ctrl_handler_free(&solo_enc->hdl);
1339 kfree(solo_enc);