Lines Matching refs:solo_dev
44 static inline void erase_on(struct solo_dev *solo_dev) in erase_on() argument
46 solo_reg_write(solo_dev, SOLO_VO_DISP_ERASE, SOLO_VO_DISP_ERASE_ON); in erase_on()
47 solo_dev->erasing = 1; in erase_on()
48 solo_dev->frame_blank = 0; in erase_on()
51 static inline int erase_off(struct solo_dev *solo_dev) in erase_off() argument
53 if (!solo_dev->erasing) in erase_off()
57 if (!solo_dev->frame_blank) in erase_off()
58 solo_reg_write(solo_dev, SOLO_VO_DISP_ERASE, 0); in erase_off()
60 if (solo_dev->frame_blank++ >= 8) in erase_off()
61 solo_dev->erasing = 0; in erase_off()
66 void solo_video_in_isr(struct solo_dev *solo_dev) in solo_video_in_isr() argument
68 wake_up_interruptible_all(&solo_dev->disp_thread_wait); in solo_video_in_isr()
71 static void solo_win_setup(struct solo_dev *solo_dev, u8 ch, in solo_win_setup() argument
74 if (ch >= solo_dev->nr_chans) in solo_win_setup()
78 solo_reg_write(solo_dev, SOLO_VI_WIN_CTRL0(ch), in solo_win_setup()
84 solo_reg_write(solo_dev, SOLO_VI_WIN_CTRL1(ch), in solo_win_setup()
89 static int solo_v4l2_ch_ext_4up(struct solo_dev *solo_dev, u8 idx, int on) in solo_v4l2_ch_ext_4up() argument
93 if (ch >= solo_dev->nr_chans) in solo_v4l2_ch_ext_4up()
100 solo_win_setup(solo_dev, i, solo_dev->video_hsize, in solo_v4l2_ch_ext_4up()
101 solo_vlines(solo_dev), in solo_v4l2_ch_ext_4up()
102 solo_dev->video_hsize, in solo_v4l2_ch_ext_4up()
103 solo_vlines(solo_dev), 0); in solo_v4l2_ch_ext_4up()
108 solo_win_setup(solo_dev, ch, 0, 0, solo_dev->video_hsize / 2, in solo_v4l2_ch_ext_4up()
109 solo_vlines(solo_dev) / 2, 3); in solo_v4l2_ch_ext_4up()
110 solo_win_setup(solo_dev, ch + 1, solo_dev->video_hsize / 2, 0, in solo_v4l2_ch_ext_4up()
111 solo_dev->video_hsize, solo_vlines(solo_dev) / 2, 3); in solo_v4l2_ch_ext_4up()
113 solo_win_setup(solo_dev, ch + 2, 0, solo_vlines(solo_dev) / 2, in solo_v4l2_ch_ext_4up()
114 solo_dev->video_hsize / 2, solo_vlines(solo_dev), 3); in solo_v4l2_ch_ext_4up()
115 solo_win_setup(solo_dev, ch + 3, solo_dev->video_hsize / 2, in solo_v4l2_ch_ext_4up()
116 solo_vlines(solo_dev) / 2, solo_dev->video_hsize, in solo_v4l2_ch_ext_4up()
117 solo_vlines(solo_dev), 3); in solo_v4l2_ch_ext_4up()
122 static int solo_v4l2_ch_ext_16up(struct solo_dev *solo_dev, int on) in solo_v4l2_ch_ext_16up() argument
128 solo_win_setup(solo_dev, i, solo_dev->video_hsize, in solo_v4l2_ch_ext_16up()
129 solo_vlines(solo_dev), in solo_v4l2_ch_ext_16up()
130 solo_dev->video_hsize, in solo_v4l2_ch_ext_16up()
131 solo_vlines(solo_dev), 0); in solo_v4l2_ch_ext_16up()
135 ysize = solo_vlines(solo_dev) / 4; in solo_v4l2_ch_ext_16up()
136 hsize = solo_dev->video_hsize / 4; in solo_v4l2_ch_ext_16up()
139 solo_win_setup(solo_dev, i * 4, 0, sy, hsize, in solo_v4l2_ch_ext_16up()
141 solo_win_setup(solo_dev, (i * 4) + 1, hsize, sy, in solo_v4l2_ch_ext_16up()
143 solo_win_setup(solo_dev, (i * 4) + 2, hsize * 2, sy, in solo_v4l2_ch_ext_16up()
145 solo_win_setup(solo_dev, (i * 4) + 3, hsize * 3, sy, in solo_v4l2_ch_ext_16up()
146 solo_dev->video_hsize, sy + ysize, 5); in solo_v4l2_ch_ext_16up()
152 static int solo_v4l2_ch(struct solo_dev *solo_dev, u8 ch, int on) in solo_v4l2_ch() argument
156 if (ch < solo_dev->nr_chans) { in solo_v4l2_ch()
157 solo_win_setup(solo_dev, ch, on ? 0 : solo_dev->video_hsize, in solo_v4l2_ch()
158 on ? 0 : solo_vlines(solo_dev), in solo_v4l2_ch()
159 solo_dev->video_hsize, solo_vlines(solo_dev), in solo_v4l2_ch()
164 if (ch >= solo_dev->nr_chans + solo_dev->nr_ext) in solo_v4l2_ch()
167 ext_ch = ch - solo_dev->nr_chans; in solo_v4l2_ch()
171 return solo_v4l2_ch_ext_4up(solo_dev, ext_ch, on); in solo_v4l2_ch()
174 return solo_v4l2_ch_ext_16up(solo_dev, on); in solo_v4l2_ch()
177 static int solo_v4l2_set_ch(struct solo_dev *solo_dev, u8 ch) in solo_v4l2_set_ch() argument
179 if (ch >= solo_dev->nr_chans + solo_dev->nr_ext) in solo_v4l2_set_ch()
182 erase_on(solo_dev); in solo_v4l2_set_ch()
184 solo_v4l2_ch(solo_dev, solo_dev->cur_disp_ch, 0); in solo_v4l2_set_ch()
185 solo_v4l2_ch(solo_dev, ch, 1); in solo_v4l2_set_ch()
187 solo_dev->cur_disp_ch = ch; in solo_v4l2_set_ch()
192 static void solo_fillbuf(struct solo_dev *solo_dev, in solo_fillbuf() argument
205 if (erase_off(solo_dev)) { in solo_fillbuf()
207 int image_size = solo_image_size(solo_dev); in solo_fillbuf()
215 fdma_addr = SOLO_DISP_EXT_ADDR + (solo_dev->old_write * in solo_fillbuf()
216 (SOLO_HW_BPL * solo_vlines(solo_dev))); in solo_fillbuf()
218 error = solo_p2m_dma_t(solo_dev, 0, addr, fdma_addr, in solo_fillbuf()
219 solo_bytesperline(solo_dev), in solo_fillbuf()
220 solo_vlines(solo_dev), SOLO_HW_BPL); in solo_fillbuf()
226 solo_vlines(solo_dev) * solo_bytesperline(solo_dev)); in solo_fillbuf()
227 vbuf->sequence = solo_dev->sequence++; in solo_fillbuf()
234 static void solo_thread_try(struct solo_dev *solo_dev) in solo_thread_try() argument
244 solo_reg_read(solo_dev, SOLO_VI_STATUS0)); in solo_thread_try()
245 if (cur_write == solo_dev->old_write) in solo_thread_try()
248 spin_lock(&solo_dev->slock); in solo_thread_try()
250 if (list_empty(&solo_dev->vidq_active)) in solo_thread_try()
253 vb = list_first_entry(&solo_dev->vidq_active, struct solo_vb2_buf, in solo_thread_try()
256 solo_dev->old_write = cur_write; in solo_thread_try()
259 spin_unlock(&solo_dev->slock); in solo_thread_try()
261 solo_fillbuf(solo_dev, &vb->vb.vb2_buf); in solo_thread_try()
264 assert_spin_locked(&solo_dev->slock); in solo_thread_try()
265 spin_unlock(&solo_dev->slock); in solo_thread_try()
270 struct solo_dev *solo_dev = data; in solo_thread() local
274 add_wait_queue(&solo_dev->disp_thread_wait, &wait); in solo_thread()
281 solo_thread_try(solo_dev); in solo_thread()
285 remove_wait_queue(&solo_dev->disp_thread_wait, &wait); in solo_thread()
290 static int solo_start_thread(struct solo_dev *solo_dev) in solo_start_thread() argument
294 solo_dev->kthread = kthread_run(solo_thread, solo_dev, SOLO6X10_NAME "_disp"); in solo_start_thread()
296 if (IS_ERR(solo_dev->kthread)) { in solo_start_thread()
297 ret = PTR_ERR(solo_dev->kthread); in solo_start_thread()
298 solo_dev->kthread = NULL; in solo_start_thread()
301 solo_irq_on(solo_dev, SOLO_IRQ_VIDEO_IN); in solo_start_thread()
306 static void solo_stop_thread(struct solo_dev *solo_dev) in solo_stop_thread() argument
308 if (!solo_dev->kthread) in solo_stop_thread()
311 solo_irq_off(solo_dev, SOLO_IRQ_VIDEO_IN); in solo_stop_thread()
312 kthread_stop(solo_dev->kthread); in solo_stop_thread()
313 solo_dev->kthread = NULL; in solo_stop_thread()
320 struct solo_dev *solo_dev = vb2_get_drv_priv(q); in solo_queue_setup() local
322 sizes[0] = solo_image_size(solo_dev); in solo_queue_setup()
323 alloc_ctxs[0] = solo_dev->alloc_ctx; in solo_queue_setup()
334 struct solo_dev *solo_dev = vb2_get_drv_priv(q); in solo_start_streaming() local
336 solo_dev->sequence = 0; in solo_start_streaming()
337 return solo_start_thread(solo_dev); in solo_start_streaming()
342 struct solo_dev *solo_dev = vb2_get_drv_priv(q); in solo_stop_streaming() local
344 solo_stop_thread(solo_dev); in solo_stop_streaming()
345 INIT_LIST_HEAD(&solo_dev->vidq_active); in solo_stop_streaming()
352 struct solo_dev *solo_dev = vb2_get_drv_priv(vq); in solo_buf_queue() local
356 spin_lock(&solo_dev->slock); in solo_buf_queue()
357 list_add_tail(&solo_vb->list, &solo_dev->vidq_active); in solo_buf_queue()
358 spin_unlock(&solo_dev->slock); in solo_buf_queue()
359 wake_up_interruptible(&solo_dev->disp_thread_wait); in solo_buf_queue()
374 struct solo_dev *solo_dev = video_drvdata(file); in solo_querycap() local
379 pci_name(solo_dev->pdev)); in solo_querycap()
386 static int solo_enum_ext_input(struct solo_dev *solo_dev, in solo_enum_ext_input() argument
396 if (input->index >= (solo_dev->nr_chans + solo_dev->nr_ext)) in solo_enum_ext_input()
399 if (solo_dev->nr_ext == 5) in solo_enum_ext_input()
401 else if (solo_dev->nr_ext == 2) in solo_enum_ext_input()
407 dispnames[input->index - solo_dev->nr_chans]); in solo_enum_ext_input()
415 struct solo_dev *solo_dev = video_drvdata(file); in solo_enum_input() local
417 if (input->index >= solo_dev->nr_chans) { in solo_enum_input()
418 int ret = solo_enum_ext_input(solo_dev, input); in solo_enum_input()
427 if (!tw28_get_video_status(solo_dev, input->index)) in solo_enum_input()
432 input->std = solo_dev->vfd->tvnorms; in solo_enum_input()
438 struct solo_dev *solo_dev = video_drvdata(file); in solo_set_input() local
439 int ret = solo_v4l2_set_ch(solo_dev, index); in solo_set_input()
442 while (erase_off(solo_dev)) in solo_set_input()
451 struct solo_dev *solo_dev = video_drvdata(file); in solo_get_input() local
453 *index = solo_dev->cur_disp_ch; in solo_get_input()
473 struct solo_dev *solo_dev = video_drvdata(file); in solo_try_fmt_cap() local
475 int image_size = solo_image_size(solo_dev); in solo_try_fmt_cap()
480 pix->width = solo_dev->video_hsize; in solo_try_fmt_cap()
481 pix->height = solo_vlines(solo_dev); in solo_try_fmt_cap()
493 struct solo_dev *solo_dev = video_drvdata(file); in solo_set_fmt_cap() local
495 if (vb2_is_busy(&solo_dev->vidq)) in solo_set_fmt_cap()
506 struct solo_dev *solo_dev = video_drvdata(file); in solo_get_fmt_cap() local
509 pix->width = solo_dev->video_hsize; in solo_get_fmt_cap()
510 pix->height = solo_vlines(solo_dev); in solo_get_fmt_cap()
513 pix->sizeimage = solo_image_size(solo_dev); in solo_get_fmt_cap()
515 pix->bytesperline = solo_bytesperline(solo_dev); in solo_get_fmt_cap()
523 struct solo_dev *solo_dev = video_drvdata(file); in solo_g_std() local
525 if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) in solo_g_std()
532 int solo_set_video_type(struct solo_dev *solo_dev, bool is_50hz) in solo_set_video_type() argument
537 if (vb2_is_busy(&solo_dev->vidq)) in solo_set_video_type()
539 for (i = 0; i < solo_dev->nr_chans; i++) in solo_set_video_type()
540 if (vb2_is_busy(&solo_dev->v4l2_enc[i]->vidq)) in solo_set_video_type()
542 solo_dev->video_type = is_50hz ? SOLO_VO_FMT_TYPE_PAL : in solo_set_video_type()
545 solo_disp_init(solo_dev); in solo_set_video_type()
546 solo_enc_init(solo_dev); in solo_set_video_type()
547 solo_tw28_init(solo_dev); in solo_set_video_type()
548 for (i = 0; i < solo_dev->nr_chans; i++) in solo_set_video_type()
549 solo_update_mode(solo_dev->v4l2_enc[i]); in solo_set_video_type()
550 return solo_v4l2_set_ch(solo_dev, solo_dev->cur_disp_ch); in solo_set_video_type()
555 struct solo_dev *solo_dev = video_drvdata(file); in solo_s_std() local
557 return solo_set_video_type(solo_dev, std & V4L2_STD_625_50); in solo_s_std()
562 struct solo_dev *solo_dev = in solo_s_ctrl() local
563 container_of(ctrl->handler, struct solo_dev, disp_hdl); in solo_s_ctrl()
568 solo_reg_write(solo_dev, SOLO_VI_MOTION_BORDER, in solo_s_ctrl()
573 solo_reg_write(solo_dev, SOLO_VI_MOTION_BAR, in solo_s_ctrl()
579 solo_reg_write(solo_dev, SOLO_VI_MOTION_BORDER, 0); in solo_s_ctrl()
580 solo_reg_write(solo_dev, SOLO_VI_MOTION_BAR, 0); in solo_s_ctrl()
647 int solo_v4l2_init(struct solo_dev *solo_dev, unsigned nr) in solo_v4l2_init() argument
652 init_waitqueue_head(&solo_dev->disp_thread_wait); in solo_v4l2_init()
653 spin_lock_init(&solo_dev->slock); in solo_v4l2_init()
654 mutex_init(&solo_dev->lock); in solo_v4l2_init()
655 INIT_LIST_HEAD(&solo_dev->vidq_active); in solo_v4l2_init()
657 solo_dev->vfd = video_device_alloc(); in solo_v4l2_init()
658 if (!solo_dev->vfd) in solo_v4l2_init()
661 *solo_dev->vfd = solo_v4l2_template; in solo_v4l2_init()
662 solo_dev->vfd->v4l2_dev = &solo_dev->v4l2_dev; in solo_v4l2_init()
663 solo_dev->vfd->queue = &solo_dev->vidq; in solo_v4l2_init()
664 solo_dev->vfd->lock = &solo_dev->lock; in solo_v4l2_init()
665 v4l2_ctrl_handler_init(&solo_dev->disp_hdl, 1); in solo_v4l2_init()
666 v4l2_ctrl_new_custom(&solo_dev->disp_hdl, &solo_motion_trace_ctrl, NULL); in solo_v4l2_init()
667 if (solo_dev->disp_hdl.error) { in solo_v4l2_init()
668 ret = solo_dev->disp_hdl.error; in solo_v4l2_init()
671 solo_dev->vfd->ctrl_handler = &solo_dev->disp_hdl; in solo_v4l2_init()
673 video_set_drvdata(solo_dev->vfd, solo_dev); in solo_v4l2_init()
675 solo_dev->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in solo_v4l2_init()
676 solo_dev->vidq.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; in solo_v4l2_init()
677 solo_dev->vidq.ops = &solo_video_qops; in solo_v4l2_init()
678 solo_dev->vidq.mem_ops = &vb2_dma_contig_memops; in solo_v4l2_init()
679 solo_dev->vidq.drv_priv = solo_dev; in solo_v4l2_init()
680 solo_dev->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; in solo_v4l2_init()
681 solo_dev->vidq.gfp_flags = __GFP_DMA32 | __GFP_KSWAPD_RECLAIM; in solo_v4l2_init()
682 solo_dev->vidq.buf_struct_size = sizeof(struct solo_vb2_buf); in solo_v4l2_init()
683 solo_dev->vidq.lock = &solo_dev->lock; in solo_v4l2_init()
684 ret = vb2_queue_init(&solo_dev->vidq); in solo_v4l2_init()
688 solo_dev->alloc_ctx = vb2_dma_contig_init_ctx(&solo_dev->pdev->dev); in solo_v4l2_init()
689 if (IS_ERR(solo_dev->alloc_ctx)) { in solo_v4l2_init()
690 dev_err(&solo_dev->pdev->dev, "Can't allocate buffer context"); in solo_v4l2_init()
691 return PTR_ERR(solo_dev->alloc_ctx); in solo_v4l2_init()
695 for (i = 0; i < solo_dev->nr_chans; i++) { in solo_v4l2_init()
696 solo_v4l2_set_ch(solo_dev, i); in solo_v4l2_init()
697 while (erase_off(solo_dev)) in solo_v4l2_init()
702 solo_v4l2_set_ch(solo_dev, 0); in solo_v4l2_init()
703 while (erase_off(solo_dev)) in solo_v4l2_init()
706 ret = video_register_device(solo_dev->vfd, VFL_TYPE_GRABBER, nr); in solo_v4l2_init()
710 snprintf(solo_dev->vfd->name, sizeof(solo_dev->vfd->name), "%s (%i)", in solo_v4l2_init()
711 SOLO6X10_NAME, solo_dev->vfd->num); in solo_v4l2_init()
713 dev_info(&solo_dev->pdev->dev, "Display as /dev/video%d with " in solo_v4l2_init()
714 "%d inputs (%d extended)\n", solo_dev->vfd->num, in solo_v4l2_init()
715 solo_dev->nr_chans, solo_dev->nr_ext); in solo_v4l2_init()
720 video_device_release(solo_dev->vfd); in solo_v4l2_init()
721 vb2_dma_contig_cleanup_ctx(solo_dev->alloc_ctx); in solo_v4l2_init()
722 v4l2_ctrl_handler_free(&solo_dev->disp_hdl); in solo_v4l2_init()
723 solo_dev->vfd = NULL; in solo_v4l2_init()
727 void solo_v4l2_exit(struct solo_dev *solo_dev) in solo_v4l2_exit() argument
729 if (solo_dev->vfd == NULL) in solo_v4l2_exit()
732 video_unregister_device(solo_dev->vfd); in solo_v4l2_exit()
733 vb2_dma_contig_cleanup_ctx(solo_dev->alloc_ctx); in solo_v4l2_exit()
734 v4l2_ctrl_handler_free(&solo_dev->disp_hdl); in solo_v4l2_exit()
735 solo_dev->vfd = NULL; in solo_v4l2_exit()