参照元

説明

引数

返り値

参考

実装

/*
 * The initial setup of this device instance. Note that the initial state of
 * the driver should be complete. So the initial format, standard, timings
 * and video input should all be initialized to some reasonable value.
 */
static int skeleton_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
        /* The initial timings are chosen to be 720p60. */
        static const struct v4l2_dv_timings timings_def =
                V4L2_DV_BT_CEA_1280X720P60;
        struct skeleton *skel;
        struct video_device *vdev;
        struct v4l2_ctrl_handler *hdl;
        struct vb2_queue *q;
        int ret;
        /* Enable PCI */
        ret = pci_enable_device(pdev);
        if (ret)
                return ret;
        ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
        if (ret) {
                dev_err(&pdev->dev, "no suitable DMA available.\n");
                goto disable_pci;
        }
        /* Allocate a new instance */
        skel = devm_kzalloc(&pdev->dev, sizeof(struct skeleton), GFP_KERNEL);
        if (!skel)
                return -ENOMEM;
        /* Allocate the interrupt */
        ret = devm_request_irq(&pdev->dev, pdev->irq,
                               skeleton_irq, 0, KBUILD_MODNAME, skel);
        if (ret) {
                dev_err(&pdev->dev, "request_irq failed\n");
                goto disable_pci;
        }
        skel->pdev = pdev;
        /* Fill in the initial format-related settings */
        skel->timings = timings_def;
        skel->std = V4L2_STD_625_50;
        skeleton_fill_pix_format(skel, &skel->format);
        /* Initialize the top-level structure */
        ret = v4l2_device_register(&pdev->dev, &skel->v4l2_dev);
        if (ret)
                goto disable_pci;
        mutex_init(&skel->lock);
        /* Add the controls */
        hdl = &skel->ctrl_handler;
        v4l2_ctrl_handler_init(hdl, 4);
        v4l2_ctrl_new_std(hdl, &skel_ctrl_ops,
                          V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
        v4l2_ctrl_new_std(hdl, &skel_ctrl_ops,
                          V4L2_CID_CONTRAST, 0, 255, 1, 16);
        v4l2_ctrl_new_std(hdl, &skel_ctrl_ops,
                          V4L2_CID_SATURATION, 0, 255, 1, 127);
        v4l2_ctrl_new_std(hdl, &skel_ctrl_ops,
                          V4L2_CID_HUE, -128, 127, 1, 0);
        if (hdl->error) {
                ret = hdl->error;
                goto free_hdl;
        }
        skel->v4l2_dev.ctrl_handler = hdl;
        /* Initialize the vb2 queue */
        q = &skel->queue;
        q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ;
        q->drv_priv = skel;
        q->buf_struct_size = sizeof(struct skel_buffer);
        q->ops = &skel_qops;
        q->mem_ops = &vb2_dma_contig_memops;
        q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
        /*
         * Assume that this DMA engine needs to have at least two buffers
         * available before it can be started. The start_streaming() op
         * won't be called until at least this many buffers are queued up.
         */
        q->min_buffers_needed = 2;
        /*
         * The serialization lock for the streaming ioctls. This is the same
         * as the main serialization lock, but if some of the non-streaming
         * ioctls could take a long time to execute, then you might want to
         * have a different lock here to prevent VIDIOC_DQBUF from being
         * blocked while waiting for another action to finish. This is
         * generally not needed for PCI devices, but USB devices usually do
         * want a separate lock here.
         */
        q->lock = &skel->lock;
        /*
         * Since this driver can only do 32-bit DMA we must make sure that
         * the vb2 core will allocate the buffers in 32-bit DMA memory.
         */
        q->gfp_flags = GFP_DMA32;
        ret = vb2_queue_init(q);
        if (ret)
                goto free_hdl;
        skel->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
        if (IS_ERR(skel->alloc_ctx)) {
                dev_err(&pdev->dev, "Can't allocate buffer context");
                ret = PTR_ERR(skel->alloc_ctx);
                goto free_hdl;
        }
        INIT_LIST_HEAD(&skel->buf_list);
        spin_lock_init(&skel->qlock);
        /* Initialize the video_device structure */
        vdev = &skel->vdev;
        strlcpy(vdev->name, KBUILD_MODNAME, sizeof(vdev->name));
        /*
         * There is nothing to clean up, so release is set to an empty release
         * function. The release callback must be non-NULL.
         */
        vdev->release = video_device_release_empty;
        vdev->fops = &skel_fops,
        vdev->ioctl_ops = &skel_ioctl_ops,
        /*
         * The main serialization lock. All ioctls are serialized by this
         * lock. Exception: if q->lock is set, then the streaming ioctls
         * are serialized by that separate lock.
         */
        vdev->lock = &skel->lock;
        vdev->queue = q;
        vdev->v4l2_dev = &skel->v4l2_dev;
        /* Supported SDTV standards, if any */
        vdev->tvnorms = SKEL_TVNORMS;
        video_set_drvdata(vdev, skel);
        ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
        if (ret)
                goto free_ctx;
        dev_info(&pdev->dev, "V4L2 PCI Skeleton Driver loaded\n");
        return 0;
free_ctx:
        vb2_dma_contig_cleanup_ctx(skel->alloc_ctx);
free_hdl:
        v4l2_ctrl_handler_free(&skel->ctrl_handler);
        v4l2_device_unregister(&skel->v4l2_dev);
disable_pci:
        pci_disable_device(pdev);
        return ret;
}

コメント


トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2016-02-08 (月) 18:08:13