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()
380 static int solo_enum_ext_input(struct solo_dev *solo_dev, in solo_enum_ext_input() argument
383 int ext = input->index - solo_dev->nr_chans; in solo_enum_ext_input()
386 if (ext >= solo_dev->nr_ext) in solo_enum_ext_input()
407 struct solo_dev *solo_dev = video_drvdata(file); in solo_enum_input() local
409 if (input->index >= solo_dev->nr_chans) { in solo_enum_input()
410 int ret = solo_enum_ext_input(solo_dev, input); in solo_enum_input()
419 if (!tw28_get_video_status(solo_dev, input->index)) in solo_enum_input()
424 input->std = solo_dev->vfd->tvnorms; in solo_enum_input()
430 struct solo_dev *solo_dev = video_drvdata(file); in solo_set_input() local
431 int ret = solo_v4l2_set_ch(solo_dev, index); in solo_set_input()
434 while (erase_off(solo_dev)) in solo_set_input()
443 struct solo_dev *solo_dev = video_drvdata(file); in solo_get_input() local
445 *index = solo_dev->cur_disp_ch; in solo_get_input()
463 struct solo_dev *solo_dev = video_drvdata(file); in solo_try_fmt_cap() local
465 int image_size = solo_image_size(solo_dev); in solo_try_fmt_cap()
470 pix->width = solo_dev->video_hsize; in solo_try_fmt_cap()
471 pix->height = solo_vlines(solo_dev); in solo_try_fmt_cap()
482 struct solo_dev *solo_dev = video_drvdata(file); in solo_set_fmt_cap() local
484 if (vb2_is_busy(&solo_dev->vidq)) in solo_set_fmt_cap()
495 struct solo_dev *solo_dev = video_drvdata(file); in solo_get_fmt_cap() local
498 pix->width = solo_dev->video_hsize; in solo_get_fmt_cap()
499 pix->height = solo_vlines(solo_dev); in solo_get_fmt_cap()
502 pix->sizeimage = solo_image_size(solo_dev); in solo_get_fmt_cap()
504 pix->bytesperline = solo_bytesperline(solo_dev); in solo_get_fmt_cap()
511 struct solo_dev *solo_dev = video_drvdata(file); in solo_g_std() local
513 if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) in solo_g_std()
520 int solo_set_video_type(struct solo_dev *solo_dev, bool is_50hz) in solo_set_video_type() argument
525 if (vb2_is_busy(&solo_dev->vidq)) in solo_set_video_type()
527 for (i = 0; i < solo_dev->nr_chans; i++) in solo_set_video_type()
528 if (vb2_is_busy(&solo_dev->v4l2_enc[i]->vidq)) in solo_set_video_type()
530 solo_dev->video_type = is_50hz ? SOLO_VO_FMT_TYPE_PAL : in solo_set_video_type()
533 solo_disp_init(solo_dev); in solo_set_video_type()
534 solo_enc_init(solo_dev); in solo_set_video_type()
535 solo_tw28_init(solo_dev); in solo_set_video_type()
536 for (i = 0; i < solo_dev->nr_chans; i++) in solo_set_video_type()
537 solo_update_mode(solo_dev->v4l2_enc[i]); in solo_set_video_type()
538 return solo_v4l2_set_ch(solo_dev, solo_dev->cur_disp_ch); in solo_set_video_type()
543 struct solo_dev *solo_dev = video_drvdata(file); in solo_s_std() local
545 return solo_set_video_type(solo_dev, std & V4L2_STD_625_50); in solo_s_std()
550 struct solo_dev *solo_dev = in solo_s_ctrl() local
551 container_of(ctrl->handler, struct solo_dev, disp_hdl); in solo_s_ctrl()
556 solo_reg_write(solo_dev, SOLO_VI_MOTION_BORDER, in solo_s_ctrl()
561 solo_reg_write(solo_dev, SOLO_VI_MOTION_BAR, in solo_s_ctrl()
567 solo_reg_write(solo_dev, SOLO_VI_MOTION_BORDER, 0); in solo_s_ctrl()
568 solo_reg_write(solo_dev, SOLO_VI_MOTION_BAR, 0); in solo_s_ctrl()
637 int solo_v4l2_init(struct solo_dev *solo_dev, unsigned nr) in solo_v4l2_init() argument
642 init_waitqueue_head(&solo_dev->disp_thread_wait); in solo_v4l2_init()
643 spin_lock_init(&solo_dev->slock); in solo_v4l2_init()
644 mutex_init(&solo_dev->lock); in solo_v4l2_init()
645 INIT_LIST_HEAD(&solo_dev->vidq_active); in solo_v4l2_init()
647 solo_dev->vfd = video_device_alloc(); in solo_v4l2_init()
648 if (!solo_dev->vfd) in solo_v4l2_init()
651 *solo_dev->vfd = solo_v4l2_template; in solo_v4l2_init()
652 solo_dev->vfd->v4l2_dev = &solo_dev->v4l2_dev; in solo_v4l2_init()
653 solo_dev->vfd->queue = &solo_dev->vidq; in solo_v4l2_init()
654 solo_dev->vfd->lock = &solo_dev->lock; in solo_v4l2_init()
655 v4l2_ctrl_handler_init(&solo_dev->disp_hdl, 1); in solo_v4l2_init()
656 v4l2_ctrl_new_custom(&solo_dev->disp_hdl, &solo_motion_trace_ctrl, NULL); in solo_v4l2_init()
657 if (solo_dev->disp_hdl.error) { in solo_v4l2_init()
658 ret = solo_dev->disp_hdl.error; in solo_v4l2_init()
661 solo_dev->vfd->ctrl_handler = &solo_dev->disp_hdl; in solo_v4l2_init()
663 video_set_drvdata(solo_dev->vfd, solo_dev); in solo_v4l2_init()
665 solo_dev->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in solo_v4l2_init()
666 solo_dev->vidq.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; in solo_v4l2_init()
667 solo_dev->vidq.ops = &solo_video_qops; in solo_v4l2_init()
668 solo_dev->vidq.mem_ops = &vb2_dma_contig_memops; in solo_v4l2_init()
669 solo_dev->vidq.drv_priv = solo_dev; in solo_v4l2_init()
670 solo_dev->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; in solo_v4l2_init()
671 solo_dev->vidq.gfp_flags = __GFP_DMA32 | __GFP_KSWAPD_RECLAIM; in solo_v4l2_init()
672 solo_dev->vidq.buf_struct_size = sizeof(struct solo_vb2_buf); in solo_v4l2_init()
673 solo_dev->vidq.lock = &solo_dev->lock; in solo_v4l2_init()
674 solo_dev->vidq.dev = &solo_dev->pdev->dev; in solo_v4l2_init()
675 ret = vb2_queue_init(&solo_dev->vidq); in solo_v4l2_init()
680 for (i = 0; i < solo_dev->nr_chans; i++) { in solo_v4l2_init()
681 solo_v4l2_set_ch(solo_dev, i); in solo_v4l2_init()
682 while (erase_off(solo_dev)) in solo_v4l2_init()
687 solo_v4l2_set_ch(solo_dev, 0); in solo_v4l2_init()
688 while (erase_off(solo_dev)) in solo_v4l2_init()
691 ret = video_register_device(solo_dev->vfd, VFL_TYPE_VIDEO, nr); in solo_v4l2_init()
695 snprintf(solo_dev->vfd->name, sizeof(solo_dev->vfd->name), "%s (%i)", in solo_v4l2_init()
696 SOLO6X10_NAME, solo_dev->vfd->num); in solo_v4l2_init()
698 dev_info(&solo_dev->pdev->dev, "Display as /dev/video%d with %d inputs (%d extended)\n", in solo_v4l2_init()
699 solo_dev->vfd->num, in solo_v4l2_init()
700 solo_dev->nr_chans, solo_dev->nr_ext); in solo_v4l2_init()
705 video_device_release(solo_dev->vfd); in solo_v4l2_init()
706 v4l2_ctrl_handler_free(&solo_dev->disp_hdl); in solo_v4l2_init()
707 solo_dev->vfd = NULL; in solo_v4l2_init()
711 void solo_v4l2_exit(struct solo_dev *solo_dev) in solo_v4l2_exit() argument
713 if (solo_dev->vfd == NULL) in solo_v4l2_exit()
716 video_unregister_device(solo_dev->vfd); in solo_v4l2_exit()
717 v4l2_ctrl_handler_free(&solo_dev->disp_hdl); in solo_v4l2_exit()
718 solo_dev->vfd = NULL; in solo_v4l2_exit()