int solo_v4l2_init(struct solo6010_dev *solo_dev) { int ret; int i; init_waitqueue_head(&solo_dev->disp_thread_wait); solo_dev->vfd = video_device_alloc(); if (!solo_dev->vfd) return -ENOMEM; *solo_dev->vfd = solo_v4l2_template; solo_dev->vfd->parent = &solo_dev->pdev->dev; ret = video_register_device(solo_dev->vfd, VFL_TYPE_GRABBER, video_nr); if (ret < 0) { video_device_release(solo_dev->vfd); solo_dev->vfd = NULL; return ret; } video_set_drvdata(solo_dev->vfd, solo_dev); snprintf(solo_dev->vfd->name, sizeof(solo_dev->vfd->name), "%s (%i)", SOLO6010_NAME, solo_dev->vfd->num); if (video_nr != -1) video_nr++; dev_info(&solo_dev->pdev->dev, "Display as /dev/video%d with " "%d inputs (%d extended)\n", solo_dev->vfd->num, solo_dev->nr_chans, solo_dev->nr_ext); /* Cycle all the channels and clear */ for (i = 0; i < solo_dev->nr_chans; i++) { solo_v4l2_set_ch(solo_dev, i); while (erase_off(solo_dev)) ;// Do nothing } /* Set the default display channel */ solo_v4l2_set_ch(solo_dev, 0); while (erase_off(solo_dev)) ;// Do nothing solo6010_irq_on(solo_dev, SOLO_IRQ_VIDEO_IN); return 0; }
static int solo_set_input(struct file *file, void *priv, unsigned int index) { struct solo_filehandle *fh = priv; int ret = solo_v4l2_set_ch(fh->solo_dev, index); if (!ret) { while (erase_off(fh->solo_dev)) /* Do nothing */; } return ret; }
static int solo_set_input(struct file *file, void *priv, unsigned int index) { struct solo_dev *solo_dev = video_drvdata(file); int ret = solo_v4l2_set_ch(solo_dev, index); if (!ret) { while (erase_off(solo_dev)) /* Do nothing */; } return ret; }
int solo_set_video_type(struct solo_dev *solo_dev, bool is_50hz) { int i; /* Make sure all video nodes are idle */ if (vb2_is_busy(&solo_dev->vidq)) return -EBUSY; for (i = 0; i < solo_dev->nr_chans; i++) if (vb2_is_busy(&solo_dev->v4l2_enc[i]->vidq)) return -EBUSY; solo_dev->video_type = is_50hz ? SOLO_VO_FMT_TYPE_PAL : SOLO_VO_FMT_TYPE_NTSC; /* Reconfigure for the new standard */ solo_disp_init(solo_dev); solo_enc_init(solo_dev); solo_tw28_init(solo_dev); for (i = 0; i < solo_dev->nr_chans; i++) solo_update_mode(solo_dev->v4l2_enc[i]); return solo_v4l2_set_ch(solo_dev, solo_dev->cur_disp_ch); }
static int solo_set_input(struct file *file, void *priv, unsigned int index) { struct solo_filehandle *fh = priv; return solo_v4l2_set_ch(fh->solo_dev, index); }
int solo_v4l2_init(struct solo_dev *solo_dev, unsigned nr) { int ret; int i; init_waitqueue_head(&solo_dev->disp_thread_wait); spin_lock_init(&solo_dev->slock); mutex_init(&solo_dev->lock); INIT_LIST_HEAD(&solo_dev->vidq_active); solo_dev->vfd = video_device_alloc(); if (!solo_dev->vfd) return -ENOMEM; *solo_dev->vfd = solo_v4l2_template; solo_dev->vfd->v4l2_dev = &solo_dev->v4l2_dev; solo_dev->vfd->queue = &solo_dev->vidq; solo_dev->vfd->lock = &solo_dev->lock; v4l2_ctrl_handler_init(&solo_dev->disp_hdl, 1); v4l2_ctrl_new_custom(&solo_dev->disp_hdl, &solo_motion_trace_ctrl, NULL); if (solo_dev->disp_hdl.error) { ret = solo_dev->disp_hdl.error; goto fail; } solo_dev->vfd->ctrl_handler = &solo_dev->disp_hdl; video_set_drvdata(solo_dev->vfd, solo_dev); solo_dev->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; solo_dev->vidq.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; solo_dev->vidq.ops = &solo_video_qops; solo_dev->vidq.mem_ops = &vb2_dma_contig_memops; solo_dev->vidq.drv_priv = solo_dev; solo_dev->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; solo_dev->vidq.gfp_flags = __GFP_DMA32; solo_dev->vidq.buf_struct_size = sizeof(struct solo_vb2_buf); solo_dev->vidq.lock = &solo_dev->lock; ret = vb2_queue_init(&solo_dev->vidq); if (ret < 0) goto fail; solo_dev->alloc_ctx = vb2_dma_contig_init_ctx(&solo_dev->pdev->dev); if (IS_ERR(solo_dev->alloc_ctx)) { dev_err(&solo_dev->pdev->dev, "Can't allocate buffer context"); return PTR_ERR(solo_dev->alloc_ctx); } /* Cycle all the channels and clear */ for (i = 0; i < solo_dev->nr_chans; i++) { solo_v4l2_set_ch(solo_dev, i); while (erase_off(solo_dev)) /* Do nothing */; } /* Set the default display channel */ solo_v4l2_set_ch(solo_dev, 0); while (erase_off(solo_dev)) /* Do nothing */; ret = video_register_device(solo_dev->vfd, VFL_TYPE_GRABBER, nr); if (ret < 0) goto fail; snprintf(solo_dev->vfd->name, sizeof(solo_dev->vfd->name), "%s (%i)", SOLO6X10_NAME, solo_dev->vfd->num); dev_info(&solo_dev->pdev->dev, "Display as /dev/video%d with " "%d inputs (%d extended)\n", solo_dev->vfd->num, solo_dev->nr_chans, solo_dev->nr_ext); return 0; fail: video_device_release(solo_dev->vfd); vb2_dma_contig_cleanup_ctx(solo_dev->alloc_ctx); v4l2_ctrl_handler_free(&solo_dev->disp_hdl); solo_dev->vfd = NULL; return ret; }