Lines Matching refs:solo_dev

35 static inline void erase_on(struct solo_dev *solo_dev)  in erase_on()  argument
37 solo_reg_write(solo_dev, SOLO_VO_DISP_ERASE, SOLO_VO_DISP_ERASE_ON); in erase_on()
38 solo_dev->erasing = 1; in erase_on()
39 solo_dev->frame_blank = 0; in erase_on()
42 static inline int erase_off(struct solo_dev *solo_dev) in erase_off() argument
44 if (!solo_dev->erasing) in erase_off()
48 if (!solo_dev->frame_blank) in erase_off()
49 solo_reg_write(solo_dev, SOLO_VO_DISP_ERASE, 0); in erase_off()
51 if (solo_dev->frame_blank++ >= 8) in erase_off()
52 solo_dev->erasing = 0; in erase_off()
57 void solo_video_in_isr(struct solo_dev *solo_dev) in solo_video_in_isr() argument
59 wake_up_interruptible_all(&solo_dev->disp_thread_wait); in solo_video_in_isr()
62 static void solo_win_setup(struct solo_dev *solo_dev, u8 ch, in solo_win_setup() argument
65 if (ch >= solo_dev->nr_chans) in solo_win_setup()
69 solo_reg_write(solo_dev, SOLO_VI_WIN_CTRL0(ch), in solo_win_setup()
75 solo_reg_write(solo_dev, SOLO_VI_WIN_CTRL1(ch), in solo_win_setup()
80 static int solo_v4l2_ch_ext_4up(struct solo_dev *solo_dev, u8 idx, int on) in solo_v4l2_ch_ext_4up() argument
84 if (ch >= solo_dev->nr_chans) in solo_v4l2_ch_ext_4up()
91 solo_win_setup(solo_dev, i, solo_dev->video_hsize, in solo_v4l2_ch_ext_4up()
92 solo_vlines(solo_dev), in solo_v4l2_ch_ext_4up()
93 solo_dev->video_hsize, in solo_v4l2_ch_ext_4up()
94 solo_vlines(solo_dev), 0); in solo_v4l2_ch_ext_4up()
99 solo_win_setup(solo_dev, ch, 0, 0, solo_dev->video_hsize / 2, in solo_v4l2_ch_ext_4up()
100 solo_vlines(solo_dev) / 2, 3); in solo_v4l2_ch_ext_4up()
101 solo_win_setup(solo_dev, ch + 1, solo_dev->video_hsize / 2, 0, in solo_v4l2_ch_ext_4up()
102 solo_dev->video_hsize, solo_vlines(solo_dev) / 2, 3); in solo_v4l2_ch_ext_4up()
104 solo_win_setup(solo_dev, ch + 2, 0, solo_vlines(solo_dev) / 2, in solo_v4l2_ch_ext_4up()
105 solo_dev->video_hsize / 2, solo_vlines(solo_dev), 3); in solo_v4l2_ch_ext_4up()
106 solo_win_setup(solo_dev, ch + 3, solo_dev->video_hsize / 2, in solo_v4l2_ch_ext_4up()
107 solo_vlines(solo_dev) / 2, solo_dev->video_hsize, in solo_v4l2_ch_ext_4up()
108 solo_vlines(solo_dev), 3); in solo_v4l2_ch_ext_4up()
113 static int solo_v4l2_ch_ext_16up(struct solo_dev *solo_dev, int on) in solo_v4l2_ch_ext_16up() argument
119 solo_win_setup(solo_dev, i, solo_dev->video_hsize, in solo_v4l2_ch_ext_16up()
120 solo_vlines(solo_dev), in solo_v4l2_ch_ext_16up()
121 solo_dev->video_hsize, in solo_v4l2_ch_ext_16up()
122 solo_vlines(solo_dev), 0); in solo_v4l2_ch_ext_16up()
126 ysize = solo_vlines(solo_dev) / 4; in solo_v4l2_ch_ext_16up()
127 hsize = solo_dev->video_hsize / 4; in solo_v4l2_ch_ext_16up()
130 solo_win_setup(solo_dev, i * 4, 0, sy, hsize, in solo_v4l2_ch_ext_16up()
132 solo_win_setup(solo_dev, (i * 4) + 1, hsize, sy, in solo_v4l2_ch_ext_16up()
134 solo_win_setup(solo_dev, (i * 4) + 2, hsize * 2, sy, in solo_v4l2_ch_ext_16up()
136 solo_win_setup(solo_dev, (i * 4) + 3, hsize * 3, sy, in solo_v4l2_ch_ext_16up()
137 solo_dev->video_hsize, sy + ysize, 5); in solo_v4l2_ch_ext_16up()
143 static int solo_v4l2_ch(struct solo_dev *solo_dev, u8 ch, int on) in solo_v4l2_ch() argument
147 if (ch < solo_dev->nr_chans) { in solo_v4l2_ch()
148 solo_win_setup(solo_dev, ch, on ? 0 : solo_dev->video_hsize, in solo_v4l2_ch()
149 on ? 0 : solo_vlines(solo_dev), in solo_v4l2_ch()
150 solo_dev->video_hsize, solo_vlines(solo_dev), in solo_v4l2_ch()
155 if (ch >= solo_dev->nr_chans + solo_dev->nr_ext) in solo_v4l2_ch()
158 ext_ch = ch - solo_dev->nr_chans; in solo_v4l2_ch()
162 return solo_v4l2_ch_ext_4up(solo_dev, ext_ch, on); in solo_v4l2_ch()
165 return solo_v4l2_ch_ext_16up(solo_dev, on); in solo_v4l2_ch()
168 static int solo_v4l2_set_ch(struct solo_dev *solo_dev, u8 ch) in solo_v4l2_set_ch() argument
170 if (ch >= solo_dev->nr_chans + solo_dev->nr_ext) in solo_v4l2_set_ch()
173 erase_on(solo_dev); in solo_v4l2_set_ch()
175 solo_v4l2_ch(solo_dev, solo_dev->cur_disp_ch, 0); in solo_v4l2_set_ch()
176 solo_v4l2_ch(solo_dev, ch, 1); in solo_v4l2_set_ch()
178 solo_dev->cur_disp_ch = ch; in solo_v4l2_set_ch()
183 static void solo_fillbuf(struct solo_dev *solo_dev, in solo_fillbuf() argument
196 if (erase_off(solo_dev)) { in solo_fillbuf()
198 int image_size = solo_image_size(solo_dev); in solo_fillbuf()
206 fdma_addr = SOLO_DISP_EXT_ADDR + (solo_dev->old_write * in solo_fillbuf()
207 (SOLO_HW_BPL * solo_vlines(solo_dev))); in solo_fillbuf()
209 error = solo_p2m_dma_t(solo_dev, 0, addr, fdma_addr, in solo_fillbuf()
210 solo_bytesperline(solo_dev), in solo_fillbuf()
211 solo_vlines(solo_dev), SOLO_HW_BPL); in solo_fillbuf()
217 solo_vlines(solo_dev) * solo_bytesperline(solo_dev)); in solo_fillbuf()
218 vbuf->sequence = solo_dev->sequence++; in solo_fillbuf()
225 static void solo_thread_try(struct solo_dev *solo_dev) in solo_thread_try() argument
235 solo_reg_read(solo_dev, SOLO_VI_STATUS0)); in solo_thread_try()
236 if (cur_write == solo_dev->old_write) in solo_thread_try()
239 spin_lock(&solo_dev->slock); in solo_thread_try()
241 if (list_empty(&solo_dev->vidq_active)) in solo_thread_try()
244 vb = list_first_entry(&solo_dev->vidq_active, struct solo_vb2_buf, in solo_thread_try()
247 solo_dev->old_write = cur_write; in solo_thread_try()
250 spin_unlock(&solo_dev->slock); in solo_thread_try()
252 solo_fillbuf(solo_dev, &vb->vb.vb2_buf); in solo_thread_try()
255 assert_spin_locked(&solo_dev->slock); in solo_thread_try()
256 spin_unlock(&solo_dev->slock); in solo_thread_try()
261 struct solo_dev *solo_dev = data; in solo_thread() local
265 add_wait_queue(&solo_dev->disp_thread_wait, &wait); in solo_thread()
272 solo_thread_try(solo_dev); in solo_thread()
276 remove_wait_queue(&solo_dev->disp_thread_wait, &wait); in solo_thread()
281 static int solo_start_thread(struct solo_dev *solo_dev) in solo_start_thread() argument
285 solo_dev->kthread = kthread_run(solo_thread, solo_dev, SOLO6X10_NAME "_disp"); in solo_start_thread()
287 if (IS_ERR(solo_dev->kthread)) { in solo_start_thread()
288 ret = PTR_ERR(solo_dev->kthread); in solo_start_thread()
289 solo_dev->kthread = NULL; in solo_start_thread()
292 solo_irq_on(solo_dev, SOLO_IRQ_VIDEO_IN); in solo_start_thread()
297 static void solo_stop_thread(struct solo_dev *solo_dev) in solo_stop_thread() argument
299 if (!solo_dev->kthread) in solo_stop_thread()
302 solo_irq_off(solo_dev, SOLO_IRQ_VIDEO_IN); in solo_stop_thread()
303 kthread_stop(solo_dev->kthread); in solo_stop_thread()
304 solo_dev->kthread = NULL; in solo_stop_thread()
311 struct solo_dev *solo_dev = vb2_get_drv_priv(q); in solo_queue_setup() local
313 sizes[0] = solo_image_size(solo_dev); in solo_queue_setup()
324 struct solo_dev *solo_dev = vb2_get_drv_priv(q); in solo_start_streaming() local
326 solo_dev->sequence = 0; in solo_start_streaming()
327 return solo_start_thread(solo_dev); in solo_start_streaming()
332 struct solo_dev *solo_dev = vb2_get_drv_priv(q); in solo_stop_streaming() local
334 solo_stop_thread(solo_dev); in solo_stop_streaming()
336 spin_lock(&solo_dev->slock); in solo_stop_streaming()
337 while (!list_empty(&solo_dev->vidq_active)) { in solo_stop_streaming()
339 solo_dev->vidq_active.next, in solo_stop_streaming()
345 spin_unlock(&solo_dev->slock); in solo_stop_streaming()
346 INIT_LIST_HEAD(&solo_dev->vidq_active); in solo_stop_streaming()
353 struct solo_dev *solo_dev = vb2_get_drv_priv(vq); in solo_buf_queue() local
357 spin_lock(&solo_dev->slock); in solo_buf_queue()
358 list_add_tail(&solo_vb->list, &solo_dev->vidq_active); in solo_buf_queue()
359 spin_unlock(&solo_dev->slock); in solo_buf_queue()
360 wake_up_interruptible(&solo_dev->disp_thread_wait); in solo_buf_queue()
375 struct solo_dev *solo_dev = video_drvdata(file); in solo_querycap() local
380 pci_name(solo_dev->pdev)); in solo_querycap()
384 static int solo_enum_ext_input(struct solo_dev *solo_dev, in solo_enum_ext_input() argument
387 int ext = input->index - solo_dev->nr_chans; in solo_enum_ext_input()
390 if (ext >= solo_dev->nr_ext) in solo_enum_ext_input()
411 struct solo_dev *solo_dev = video_drvdata(file); in solo_enum_input() local
413 if (input->index >= solo_dev->nr_chans) { in solo_enum_input()
414 int ret = solo_enum_ext_input(solo_dev, input); in solo_enum_input()
423 if (!tw28_get_video_status(solo_dev, input->index)) in solo_enum_input()
428 input->std = solo_dev->vfd->tvnorms; in solo_enum_input()
434 struct solo_dev *solo_dev = video_drvdata(file); in solo_set_input() local
435 int ret = solo_v4l2_set_ch(solo_dev, index); in solo_set_input()
438 while (erase_off(solo_dev)) in solo_set_input()
447 struct solo_dev *solo_dev = video_drvdata(file); in solo_get_input() local
449 *index = solo_dev->cur_disp_ch; in solo_get_input()
467 struct solo_dev *solo_dev = video_drvdata(file); in solo_try_fmt_cap() local
469 int image_size = solo_image_size(solo_dev); in solo_try_fmt_cap()
474 pix->width = solo_dev->video_hsize; in solo_try_fmt_cap()
475 pix->height = solo_vlines(solo_dev); in solo_try_fmt_cap()
486 struct solo_dev *solo_dev = video_drvdata(file); in solo_set_fmt_cap() local
488 if (vb2_is_busy(&solo_dev->vidq)) in solo_set_fmt_cap()
499 struct solo_dev *solo_dev = video_drvdata(file); in solo_get_fmt_cap() local
502 pix->width = solo_dev->video_hsize; in solo_get_fmt_cap()
503 pix->height = solo_vlines(solo_dev); in solo_get_fmt_cap()
506 pix->sizeimage = solo_image_size(solo_dev); in solo_get_fmt_cap()
508 pix->bytesperline = solo_bytesperline(solo_dev); in solo_get_fmt_cap()
515 struct solo_dev *solo_dev = video_drvdata(file); in solo_g_std() local
517 if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) in solo_g_std()
524 int solo_set_video_type(struct solo_dev *solo_dev, bool is_50hz) in solo_set_video_type() argument
529 if (vb2_is_busy(&solo_dev->vidq)) in solo_set_video_type()
531 for (i = 0; i < solo_dev->nr_chans; i++) in solo_set_video_type()
532 if (vb2_is_busy(&solo_dev->v4l2_enc[i]->vidq)) in solo_set_video_type()
534 solo_dev->video_type = is_50hz ? SOLO_VO_FMT_TYPE_PAL : in solo_set_video_type()
537 solo_disp_init(solo_dev); in solo_set_video_type()
538 solo_enc_init(solo_dev); in solo_set_video_type()
539 solo_tw28_init(solo_dev); in solo_set_video_type()
540 for (i = 0; i < solo_dev->nr_chans; i++) in solo_set_video_type()
541 solo_update_mode(solo_dev->v4l2_enc[i]); in solo_set_video_type()
542 return solo_v4l2_set_ch(solo_dev, solo_dev->cur_disp_ch); in solo_set_video_type()
547 struct solo_dev *solo_dev = video_drvdata(file); in solo_s_std() local
549 return solo_set_video_type(solo_dev, std & V4L2_STD_625_50); in solo_s_std()
554 struct solo_dev *solo_dev = in solo_s_ctrl() local
555 container_of(ctrl->handler, struct solo_dev, disp_hdl); in solo_s_ctrl()
560 solo_reg_write(solo_dev, SOLO_VI_MOTION_BORDER, in solo_s_ctrl()
565 solo_reg_write(solo_dev, SOLO_VI_MOTION_BAR, in solo_s_ctrl()
571 solo_reg_write(solo_dev, SOLO_VI_MOTION_BORDER, 0); in solo_s_ctrl()
572 solo_reg_write(solo_dev, SOLO_VI_MOTION_BAR, 0); in solo_s_ctrl()
641 int solo_v4l2_init(struct solo_dev *solo_dev, unsigned nr) in solo_v4l2_init() argument
646 init_waitqueue_head(&solo_dev->disp_thread_wait); in solo_v4l2_init()
647 spin_lock_init(&solo_dev->slock); in solo_v4l2_init()
648 mutex_init(&solo_dev->lock); in solo_v4l2_init()
649 INIT_LIST_HEAD(&solo_dev->vidq_active); in solo_v4l2_init()
651 solo_dev->vfd = video_device_alloc(); in solo_v4l2_init()
652 if (!solo_dev->vfd) in solo_v4l2_init()
655 *solo_dev->vfd = solo_v4l2_template; in solo_v4l2_init()
656 solo_dev->vfd->v4l2_dev = &solo_dev->v4l2_dev; in solo_v4l2_init()
657 solo_dev->vfd->queue = &solo_dev->vidq; in solo_v4l2_init()
658 solo_dev->vfd->lock = &solo_dev->lock; in solo_v4l2_init()
659 v4l2_ctrl_handler_init(&solo_dev->disp_hdl, 1); in solo_v4l2_init()
660 v4l2_ctrl_new_custom(&solo_dev->disp_hdl, &solo_motion_trace_ctrl, NULL); in solo_v4l2_init()
661 if (solo_dev->disp_hdl.error) { in solo_v4l2_init()
662 ret = solo_dev->disp_hdl.error; in solo_v4l2_init()
665 solo_dev->vfd->ctrl_handler = &solo_dev->disp_hdl; in solo_v4l2_init()
667 video_set_drvdata(solo_dev->vfd, solo_dev); in solo_v4l2_init()
669 solo_dev->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in solo_v4l2_init()
670 solo_dev->vidq.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; in solo_v4l2_init()
671 solo_dev->vidq.ops = &solo_video_qops; in solo_v4l2_init()
672 solo_dev->vidq.mem_ops = &vb2_dma_contig_memops; in solo_v4l2_init()
673 solo_dev->vidq.drv_priv = solo_dev; in solo_v4l2_init()
674 solo_dev->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; in solo_v4l2_init()
675 solo_dev->vidq.gfp_flags = __GFP_DMA32 | __GFP_KSWAPD_RECLAIM; in solo_v4l2_init()
676 solo_dev->vidq.buf_struct_size = sizeof(struct solo_vb2_buf); in solo_v4l2_init()
677 solo_dev->vidq.lock = &solo_dev->lock; in solo_v4l2_init()
678 solo_dev->vidq.dev = &solo_dev->pdev->dev; in solo_v4l2_init()
679 ret = vb2_queue_init(&solo_dev->vidq); in solo_v4l2_init()
684 for (i = 0; i < solo_dev->nr_chans; i++) { in solo_v4l2_init()
685 solo_v4l2_set_ch(solo_dev, i); in solo_v4l2_init()
686 while (erase_off(solo_dev)) in solo_v4l2_init()
691 solo_v4l2_set_ch(solo_dev, 0); in solo_v4l2_init()
692 while (erase_off(solo_dev)) in solo_v4l2_init()
695 ret = video_register_device(solo_dev->vfd, VFL_TYPE_VIDEO, nr); in solo_v4l2_init()
699 snprintf(solo_dev->vfd->name, sizeof(solo_dev->vfd->name), "%s (%i)", in solo_v4l2_init()
700 SOLO6X10_NAME, solo_dev->vfd->num); in solo_v4l2_init()
702 dev_info(&solo_dev->pdev->dev, "Display as /dev/video%d with %d inputs (%d extended)\n", in solo_v4l2_init()
703 solo_dev->vfd->num, in solo_v4l2_init()
704 solo_dev->nr_chans, solo_dev->nr_ext); in solo_v4l2_init()
709 video_device_release(solo_dev->vfd); in solo_v4l2_init()
710 v4l2_ctrl_handler_free(&solo_dev->disp_hdl); in solo_v4l2_init()
711 solo_dev->vfd = NULL; in solo_v4l2_init()
715 void solo_v4l2_exit(struct solo_dev *solo_dev) in solo_v4l2_exit() argument
717 if (solo_dev->vfd == NULL) in solo_v4l2_exit()
720 video_unregister_device(solo_dev->vfd); in solo_v4l2_exit()
721 v4l2_ctrl_handler_free(&solo_dev->disp_hdl); in solo_v4l2_exit()
722 solo_dev->vfd = NULL; in solo_v4l2_exit()