Lines Matching refs:solo_dev

43 static inline void erase_on(struct solo_dev *solo_dev)  in erase_on()  argument
45 solo_reg_write(solo_dev, SOLO_VO_DISP_ERASE, SOLO_VO_DISP_ERASE_ON); in erase_on()
46 solo_dev->erasing = 1; in erase_on()
47 solo_dev->frame_blank = 0; in erase_on()
50 static inline int erase_off(struct solo_dev *solo_dev) in erase_off() argument
52 if (!solo_dev->erasing) in erase_off()
56 if (!solo_dev->frame_blank) in erase_off()
57 solo_reg_write(solo_dev, SOLO_VO_DISP_ERASE, 0); in erase_off()
59 if (solo_dev->frame_blank++ >= 8) in erase_off()
60 solo_dev->erasing = 0; in erase_off()
65 void solo_video_in_isr(struct solo_dev *solo_dev) in solo_video_in_isr() argument
67 wake_up_interruptible_all(&solo_dev->disp_thread_wait); in solo_video_in_isr()
70 static void solo_win_setup(struct solo_dev *solo_dev, u8 ch, in solo_win_setup() argument
73 if (ch >= solo_dev->nr_chans) in solo_win_setup()
77 solo_reg_write(solo_dev, SOLO_VI_WIN_CTRL0(ch), in solo_win_setup()
83 solo_reg_write(solo_dev, SOLO_VI_WIN_CTRL1(ch), in solo_win_setup()
88 static int solo_v4l2_ch_ext_4up(struct solo_dev *solo_dev, u8 idx, int on) in solo_v4l2_ch_ext_4up() argument
92 if (ch >= solo_dev->nr_chans) in solo_v4l2_ch_ext_4up()
99 solo_win_setup(solo_dev, i, solo_dev->video_hsize, in solo_v4l2_ch_ext_4up()
100 solo_vlines(solo_dev), in solo_v4l2_ch_ext_4up()
101 solo_dev->video_hsize, in solo_v4l2_ch_ext_4up()
102 solo_vlines(solo_dev), 0); in solo_v4l2_ch_ext_4up()
107 solo_win_setup(solo_dev, ch, 0, 0, solo_dev->video_hsize / 2, in solo_v4l2_ch_ext_4up()
108 solo_vlines(solo_dev) / 2, 3); in solo_v4l2_ch_ext_4up()
109 solo_win_setup(solo_dev, ch + 1, solo_dev->video_hsize / 2, 0, in solo_v4l2_ch_ext_4up()
110 solo_dev->video_hsize, solo_vlines(solo_dev) / 2, 3); in solo_v4l2_ch_ext_4up()
112 solo_win_setup(solo_dev, ch + 2, 0, solo_vlines(solo_dev) / 2, in solo_v4l2_ch_ext_4up()
113 solo_dev->video_hsize / 2, solo_vlines(solo_dev), 3); in solo_v4l2_ch_ext_4up()
114 solo_win_setup(solo_dev, ch + 3, solo_dev->video_hsize / 2, in solo_v4l2_ch_ext_4up()
115 solo_vlines(solo_dev) / 2, solo_dev->video_hsize, in solo_v4l2_ch_ext_4up()
116 solo_vlines(solo_dev), 3); in solo_v4l2_ch_ext_4up()
121 static int solo_v4l2_ch_ext_16up(struct solo_dev *solo_dev, int on) in solo_v4l2_ch_ext_16up() argument
127 solo_win_setup(solo_dev, i, solo_dev->video_hsize, in solo_v4l2_ch_ext_16up()
128 solo_vlines(solo_dev), in solo_v4l2_ch_ext_16up()
129 solo_dev->video_hsize, in solo_v4l2_ch_ext_16up()
130 solo_vlines(solo_dev), 0); in solo_v4l2_ch_ext_16up()
134 ysize = solo_vlines(solo_dev) / 4; in solo_v4l2_ch_ext_16up()
135 hsize = solo_dev->video_hsize / 4; in solo_v4l2_ch_ext_16up()
138 solo_win_setup(solo_dev, i * 4, 0, sy, hsize, in solo_v4l2_ch_ext_16up()
140 solo_win_setup(solo_dev, (i * 4) + 1, hsize, sy, in solo_v4l2_ch_ext_16up()
142 solo_win_setup(solo_dev, (i * 4) + 2, hsize * 2, sy, in solo_v4l2_ch_ext_16up()
144 solo_win_setup(solo_dev, (i * 4) + 3, hsize * 3, sy, in solo_v4l2_ch_ext_16up()
145 solo_dev->video_hsize, sy + ysize, 5); in solo_v4l2_ch_ext_16up()
151 static int solo_v4l2_ch(struct solo_dev *solo_dev, u8 ch, int on) in solo_v4l2_ch() argument
155 if (ch < solo_dev->nr_chans) { in solo_v4l2_ch()
156 solo_win_setup(solo_dev, ch, on ? 0 : solo_dev->video_hsize, in solo_v4l2_ch()
157 on ? 0 : solo_vlines(solo_dev), in solo_v4l2_ch()
158 solo_dev->video_hsize, solo_vlines(solo_dev), in solo_v4l2_ch()
163 if (ch >= solo_dev->nr_chans + solo_dev->nr_ext) in solo_v4l2_ch()
166 ext_ch = ch - solo_dev->nr_chans; in solo_v4l2_ch()
170 return solo_v4l2_ch_ext_4up(solo_dev, ext_ch, on); in solo_v4l2_ch()
173 return solo_v4l2_ch_ext_16up(solo_dev, on); in solo_v4l2_ch()
176 static int solo_v4l2_set_ch(struct solo_dev *solo_dev, u8 ch) in solo_v4l2_set_ch() argument
178 if (ch >= solo_dev->nr_chans + solo_dev->nr_ext) in solo_v4l2_set_ch()
181 erase_on(solo_dev); in solo_v4l2_set_ch()
183 solo_v4l2_ch(solo_dev, solo_dev->cur_disp_ch, 0); in solo_v4l2_set_ch()
184 solo_v4l2_ch(solo_dev, ch, 1); in solo_v4l2_set_ch()
186 solo_dev->cur_disp_ch = ch; in solo_v4l2_set_ch()
191 static void solo_fillbuf(struct solo_dev *solo_dev, in solo_fillbuf() argument
203 if (erase_off(solo_dev)) { in solo_fillbuf()
205 int image_size = solo_image_size(solo_dev); in solo_fillbuf()
213 fdma_addr = SOLO_DISP_EXT_ADDR + (solo_dev->old_write * in solo_fillbuf()
214 (SOLO_HW_BPL * solo_vlines(solo_dev))); in solo_fillbuf()
216 error = solo_p2m_dma_t(solo_dev, 0, vbuf, fdma_addr, in solo_fillbuf()
217 solo_bytesperline(solo_dev), in solo_fillbuf()
218 solo_vlines(solo_dev), SOLO_HW_BPL); in solo_fillbuf()
224 solo_vlines(solo_dev) * solo_bytesperline(solo_dev)); in solo_fillbuf()
225 vb->v4l2_buf.sequence = solo_dev->sequence++; in solo_fillbuf()
232 static void solo_thread_try(struct solo_dev *solo_dev) in solo_thread_try() argument
242 solo_reg_read(solo_dev, SOLO_VI_STATUS0)); in solo_thread_try()
243 if (cur_write == solo_dev->old_write) in solo_thread_try()
246 spin_lock(&solo_dev->slock); in solo_thread_try()
248 if (list_empty(&solo_dev->vidq_active)) in solo_thread_try()
251 vb = list_first_entry(&solo_dev->vidq_active, struct solo_vb2_buf, in solo_thread_try()
254 solo_dev->old_write = cur_write; in solo_thread_try()
257 spin_unlock(&solo_dev->slock); in solo_thread_try()
259 solo_fillbuf(solo_dev, &vb->vb); in solo_thread_try()
262 assert_spin_locked(&solo_dev->slock); in solo_thread_try()
263 spin_unlock(&solo_dev->slock); in solo_thread_try()
268 struct solo_dev *solo_dev = data; in solo_thread() local
272 add_wait_queue(&solo_dev->disp_thread_wait, &wait); in solo_thread()
279 solo_thread_try(solo_dev); in solo_thread()
283 remove_wait_queue(&solo_dev->disp_thread_wait, &wait); in solo_thread()
288 static int solo_start_thread(struct solo_dev *solo_dev) in solo_start_thread() argument
292 solo_dev->kthread = kthread_run(solo_thread, solo_dev, SOLO6X10_NAME "_disp"); in solo_start_thread()
294 if (IS_ERR(solo_dev->kthread)) { in solo_start_thread()
295 ret = PTR_ERR(solo_dev->kthread); in solo_start_thread()
296 solo_dev->kthread = NULL; in solo_start_thread()
299 solo_irq_on(solo_dev, SOLO_IRQ_VIDEO_IN); in solo_start_thread()
304 static void solo_stop_thread(struct solo_dev *solo_dev) in solo_stop_thread() argument
306 if (!solo_dev->kthread) in solo_stop_thread()
309 solo_irq_off(solo_dev, SOLO_IRQ_VIDEO_IN); in solo_stop_thread()
310 kthread_stop(solo_dev->kthread); in solo_stop_thread()
311 solo_dev->kthread = NULL; in solo_stop_thread()
318 struct solo_dev *solo_dev = vb2_get_drv_priv(q); in solo_queue_setup() local
320 sizes[0] = solo_image_size(solo_dev); in solo_queue_setup()
321 alloc_ctxs[0] = solo_dev->alloc_ctx; in solo_queue_setup()
332 struct solo_dev *solo_dev = vb2_get_drv_priv(q); in solo_start_streaming() local
334 solo_dev->sequence = 0; in solo_start_streaming()
335 return solo_start_thread(solo_dev); in solo_start_streaming()
340 struct solo_dev *solo_dev = vb2_get_drv_priv(q); in solo_stop_streaming() local
342 solo_stop_thread(solo_dev); in solo_stop_streaming()
343 INIT_LIST_HEAD(&solo_dev->vidq_active); in solo_stop_streaming()
349 struct solo_dev *solo_dev = vb2_get_drv_priv(vq); in solo_buf_queue() local
353 spin_lock(&solo_dev->slock); in solo_buf_queue()
354 list_add_tail(&solo_vb->list, &solo_dev->vidq_active); in solo_buf_queue()
355 spin_unlock(&solo_dev->slock); in solo_buf_queue()
356 wake_up_interruptible(&solo_dev->disp_thread_wait); in solo_buf_queue()
371 struct solo_dev *solo_dev = video_drvdata(file); in solo_querycap() local
376 pci_name(solo_dev->pdev)); in solo_querycap()
383 static int solo_enum_ext_input(struct solo_dev *solo_dev, in solo_enum_ext_input() argument
393 if (input->index >= (solo_dev->nr_chans + solo_dev->nr_ext)) in solo_enum_ext_input()
396 if (solo_dev->nr_ext == 5) in solo_enum_ext_input()
398 else if (solo_dev->nr_ext == 2) in solo_enum_ext_input()
404 dispnames[input->index - solo_dev->nr_chans]); in solo_enum_ext_input()
412 struct solo_dev *solo_dev = video_drvdata(file); in solo_enum_input() local
414 if (input->index >= solo_dev->nr_chans) { in solo_enum_input()
415 int ret = solo_enum_ext_input(solo_dev, input); in solo_enum_input()
424 if (!tw28_get_video_status(solo_dev, input->index)) in solo_enum_input()
429 input->std = solo_dev->vfd->tvnorms; in solo_enum_input()
435 struct solo_dev *solo_dev = video_drvdata(file); in solo_set_input() local
436 int ret = solo_v4l2_set_ch(solo_dev, index); in solo_set_input()
439 while (erase_off(solo_dev)) in solo_set_input()
448 struct solo_dev *solo_dev = video_drvdata(file); in solo_get_input() local
450 *index = solo_dev->cur_disp_ch; in solo_get_input()
470 struct solo_dev *solo_dev = video_drvdata(file); in solo_try_fmt_cap() local
472 int image_size = solo_image_size(solo_dev); in solo_try_fmt_cap()
477 pix->width = solo_dev->video_hsize; in solo_try_fmt_cap()
478 pix->height = solo_vlines(solo_dev); in solo_try_fmt_cap()
490 struct solo_dev *solo_dev = video_drvdata(file); in solo_set_fmt_cap() local
492 if (vb2_is_busy(&solo_dev->vidq)) in solo_set_fmt_cap()
503 struct solo_dev *solo_dev = video_drvdata(file); in solo_get_fmt_cap() local
506 pix->width = solo_dev->video_hsize; in solo_get_fmt_cap()
507 pix->height = solo_vlines(solo_dev); in solo_get_fmt_cap()
510 pix->sizeimage = solo_image_size(solo_dev); in solo_get_fmt_cap()
512 pix->bytesperline = solo_bytesperline(solo_dev); in solo_get_fmt_cap()
520 struct solo_dev *solo_dev = video_drvdata(file); in solo_g_std() local
522 if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) in solo_g_std()
529 int solo_set_video_type(struct solo_dev *solo_dev, bool is_50hz) in solo_set_video_type() argument
534 if (vb2_is_busy(&solo_dev->vidq)) in solo_set_video_type()
536 for (i = 0; i < solo_dev->nr_chans; i++) in solo_set_video_type()
537 if (vb2_is_busy(&solo_dev->v4l2_enc[i]->vidq)) in solo_set_video_type()
539 solo_dev->video_type = is_50hz ? SOLO_VO_FMT_TYPE_PAL : in solo_set_video_type()
542 solo_disp_init(solo_dev); in solo_set_video_type()
543 solo_enc_init(solo_dev); in solo_set_video_type()
544 solo_tw28_init(solo_dev); in solo_set_video_type()
545 for (i = 0; i < solo_dev->nr_chans; i++) in solo_set_video_type()
546 solo_update_mode(solo_dev->v4l2_enc[i]); in solo_set_video_type()
547 return solo_v4l2_set_ch(solo_dev, solo_dev->cur_disp_ch); in solo_set_video_type()
552 struct solo_dev *solo_dev = video_drvdata(file); in solo_s_std() local
554 return solo_set_video_type(solo_dev, std & V4L2_STD_625_50); in solo_s_std()
559 struct solo_dev *solo_dev = in solo_s_ctrl() local
560 container_of(ctrl->handler, struct solo_dev, disp_hdl); in solo_s_ctrl()
565 solo_reg_write(solo_dev, SOLO_VI_MOTION_BORDER, in solo_s_ctrl()
570 solo_reg_write(solo_dev, SOLO_VI_MOTION_BAR, in solo_s_ctrl()
576 solo_reg_write(solo_dev, SOLO_VI_MOTION_BORDER, 0); in solo_s_ctrl()
577 solo_reg_write(solo_dev, SOLO_VI_MOTION_BAR, 0); in solo_s_ctrl()
644 int solo_v4l2_init(struct solo_dev *solo_dev, unsigned nr) in solo_v4l2_init() argument
649 init_waitqueue_head(&solo_dev->disp_thread_wait); in solo_v4l2_init()
650 spin_lock_init(&solo_dev->slock); in solo_v4l2_init()
651 mutex_init(&solo_dev->lock); in solo_v4l2_init()
652 INIT_LIST_HEAD(&solo_dev->vidq_active); in solo_v4l2_init()
654 solo_dev->vfd = video_device_alloc(); in solo_v4l2_init()
655 if (!solo_dev->vfd) in solo_v4l2_init()
658 *solo_dev->vfd = solo_v4l2_template; in solo_v4l2_init()
659 solo_dev->vfd->v4l2_dev = &solo_dev->v4l2_dev; in solo_v4l2_init()
660 solo_dev->vfd->queue = &solo_dev->vidq; in solo_v4l2_init()
661 solo_dev->vfd->lock = &solo_dev->lock; in solo_v4l2_init()
662 v4l2_ctrl_handler_init(&solo_dev->disp_hdl, 1); in solo_v4l2_init()
663 v4l2_ctrl_new_custom(&solo_dev->disp_hdl, &solo_motion_trace_ctrl, NULL); in solo_v4l2_init()
664 if (solo_dev->disp_hdl.error) { in solo_v4l2_init()
665 ret = solo_dev->disp_hdl.error; in solo_v4l2_init()
668 solo_dev->vfd->ctrl_handler = &solo_dev->disp_hdl; in solo_v4l2_init()
670 video_set_drvdata(solo_dev->vfd, solo_dev); in solo_v4l2_init()
672 solo_dev->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in solo_v4l2_init()
673 solo_dev->vidq.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; in solo_v4l2_init()
674 solo_dev->vidq.ops = &solo_video_qops; in solo_v4l2_init()
675 solo_dev->vidq.mem_ops = &vb2_dma_contig_memops; in solo_v4l2_init()
676 solo_dev->vidq.drv_priv = solo_dev; in solo_v4l2_init()
677 solo_dev->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; in solo_v4l2_init()
678 solo_dev->vidq.gfp_flags = __GFP_DMA32; in solo_v4l2_init()
679 solo_dev->vidq.buf_struct_size = sizeof(struct solo_vb2_buf); in solo_v4l2_init()
680 solo_dev->vidq.lock = &solo_dev->lock; in solo_v4l2_init()
681 ret = vb2_queue_init(&solo_dev->vidq); in solo_v4l2_init()
685 solo_dev->alloc_ctx = vb2_dma_contig_init_ctx(&solo_dev->pdev->dev); in solo_v4l2_init()
686 if (IS_ERR(solo_dev->alloc_ctx)) { in solo_v4l2_init()
687 dev_err(&solo_dev->pdev->dev, "Can't allocate buffer context"); in solo_v4l2_init()
688 return PTR_ERR(solo_dev->alloc_ctx); in solo_v4l2_init()
692 for (i = 0; i < solo_dev->nr_chans; i++) { in solo_v4l2_init()
693 solo_v4l2_set_ch(solo_dev, i); in solo_v4l2_init()
694 while (erase_off(solo_dev)) in solo_v4l2_init()
699 solo_v4l2_set_ch(solo_dev, 0); in solo_v4l2_init()
700 while (erase_off(solo_dev)) in solo_v4l2_init()
703 ret = video_register_device(solo_dev->vfd, VFL_TYPE_GRABBER, nr); in solo_v4l2_init()
707 snprintf(solo_dev->vfd->name, sizeof(solo_dev->vfd->name), "%s (%i)", in solo_v4l2_init()
708 SOLO6X10_NAME, solo_dev->vfd->num); in solo_v4l2_init()
710 dev_info(&solo_dev->pdev->dev, "Display as /dev/video%d with " in solo_v4l2_init()
711 "%d inputs (%d extended)\n", solo_dev->vfd->num, in solo_v4l2_init()
712 solo_dev->nr_chans, solo_dev->nr_ext); in solo_v4l2_init()
717 video_device_release(solo_dev->vfd); in solo_v4l2_init()
718 vb2_dma_contig_cleanup_ctx(solo_dev->alloc_ctx); in solo_v4l2_init()
719 v4l2_ctrl_handler_free(&solo_dev->disp_hdl); in solo_v4l2_init()
720 solo_dev->vfd = NULL; in solo_v4l2_init()
724 void solo_v4l2_exit(struct solo_dev *solo_dev) in solo_v4l2_exit() argument
726 if (solo_dev->vfd == NULL) in solo_v4l2_exit()
729 video_unregister_device(solo_dev->vfd); in solo_v4l2_exit()
730 vb2_dma_contig_cleanup_ctx(solo_dev->alloc_ctx); in solo_v4l2_exit()
731 v4l2_ctrl_handler_free(&solo_dev->disp_hdl); in solo_v4l2_exit()
732 solo_dev->vfd = NULL; in solo_v4l2_exit()