/* fimc->lock must be already initialized */ int fimc_register_capture_device(struct fimc_dev *fimc) { struct v4l2_device *v4l2_dev = &fimc->vid_cap.v4l2_dev; struct video_device *vfd; struct fimc_vid_cap *vid_cap; struct fimc_ctx *ctx; struct v4l2_format f; struct fimc_frame *fr; struct vb2_queue *q; int ret; ctx = kzalloc(sizeof *ctx, GFP_KERNEL); if (!ctx) return -ENOMEM; ctx->fimc_dev = fimc; ctx->in_path = FIMC_CAMERA; ctx->out_path = FIMC_DMA; ctx->state = FIMC_CTX_CAP; /* Default format of the output frames */ f.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB32; fr = &ctx->d_frame; fr->fmt = find_format(&f, FMT_FLAGS_M2M); fr->width = fr->f_width = fr->o_width = 640; fr->height = fr->f_height = fr->o_height = 480; if (!v4l2_dev->name[0]) snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s.capture", dev_name(&fimc->pdev->dev)); ret = v4l2_device_register(NULL, v4l2_dev); if (ret) goto err_info; vfd = video_device_alloc(); if (!vfd) { v4l2_err(v4l2_dev, "Failed to allocate video device\n"); goto err_v4l2_reg; } snprintf(vfd->name, sizeof(vfd->name), "%s:cap", dev_name(&fimc->pdev->dev)); vfd->fops = &fimc_capture_fops; vfd->ioctl_ops = &fimc_capture_ioctl_ops; vfd->minor = -1; vfd->release = video_device_release; vfd->lock = &fimc->lock; video_set_drvdata(vfd, fimc); vid_cap = &fimc->vid_cap; vid_cap->vfd = vfd; vid_cap->active_buf_cnt = 0; vid_cap->reqbufs_count = 0; vid_cap->refcnt = 0; /* Default color format for image sensor */ vid_cap->fmt.code = V4L2_MBUS_FMT_YUYV8_2X8; INIT_LIST_HEAD(&vid_cap->pending_buf_q); INIT_LIST_HEAD(&vid_cap->active_buf_q); spin_lock_init(&ctx->slock); vid_cap->ctx = ctx; q = &fimc->vid_cap.vbq; memset(q, 0, sizeof(*q)); q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; q->io_modes = VB2_MMAP | VB2_USERPTR; q->drv_priv = fimc->vid_cap.ctx; q->ops = &fimc_capture_qops; q->mem_ops = &vb2_dma_contig_memops; q->buf_struct_size = sizeof(struct fimc_vid_buffer); vb2_queue_init(q); ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); if (ret) { v4l2_err(v4l2_dev, "Failed to register video device\n"); goto err_vd_reg; } v4l2_info(v4l2_dev, "FIMC capture driver registered as /dev/video%d\n", vfd->num); return 0; err_vd_reg: video_device_release(vfd); err_v4l2_reg: v4l2_device_unregister(v4l2_dev); err_info: kfree(ctx); dev_err(&fimc->pdev->dev, "failed to install\n"); return ret; }
static int __devinit vcap_probe(struct platform_device *pdev) { struct vcap_dev *dev; struct video_device *vfd; int ret; dprintk(1, "Probe started\n"); dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) return -ENOMEM; vcap_ctrl = dev; dev->vcap_pdata = pdev->dev.platform_data; dev->vcapmem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vcap"); if (!dev->vcapmem) { pr_err("VCAP: %s: no mem resource?\n", __func__); ret = -ENODEV; goto free_dev; } dev->vcapio = request_mem_region(dev->vcapmem->start, resource_size(dev->vcapmem), pdev->name); if (!dev->vcapio) { pr_err("VCAP: %s: no valid mem region\n", __func__); ret = -EBUSY; goto free_dev; } dev->vcapbase = ioremap(dev->vcapmem->start, resource_size(dev->vcapmem)); if (!dev->vcapbase) { ret = -ENOMEM; pr_err("VCAP: %s: vcap ioremap failed\n", __func__); goto free_resource; } dev->vcirq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "vc_irq"); if (!dev->vcirq) { pr_err("%s: no vc irq resource?\n", __func__); ret = -ENODEV; goto free_resource; } dev->vpirq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "vp_irq"); if (!dev->vpirq) { pr_err("%s: no vp irq resource?\n", __func__); ret = -ENODEV; goto free_resource; } ret = request_irq(dev->vcirq->start, vcap_vc_handler, IRQF_TRIGGER_RISING, "vc_irq", 0); if (ret < 0) { pr_err("%s: vc irq request fail\n", __func__); ret = -EBUSY; goto free_resource; } disable_irq(dev->vcirq->start); ret = request_irq(dev->vpirq->start, vcap_vp_handler, IRQF_TRIGGER_RISING, "vp_irq", 0); if (ret < 0) { pr_err("%s: vp irq request fail\n", __func__); ret = -EBUSY; goto free_resource; } disable_irq(dev->vpirq->start); snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s", MSM_VCAP_DRV_NAME); ret = v4l2_device_register(NULL, &dev->v4l2_dev); if (ret) goto free_resource; ret = vcap_enable(dev, &pdev->dev); if (ret) goto unreg_dev; msm_bus_scale_client_update_request(dev->bus_client_handle, 3); ret = detect_vc(dev); if (ret) goto power_down; /* init video device*/ vfd = video_device_alloc(); if (!vfd) goto deinit_vc; *vfd = vcap_template; vfd->v4l2_dev = &dev->v4l2_dev; ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); if (ret < 0) goto rel_vdev; dev->vfd = vfd; video_set_drvdata(vfd, dev); dev->vcap_wq = create_workqueue("vcap"); if (!dev->vcap_wq) { pr_err("Could not create workqueue"); goto rel_vdev; } dev->ion_client = msm_ion_client_create(-1, "vcap"); if (IS_ERR((void *)dev->ion_client)) { pr_err("could not get ion client"); goto rel_vcap_wq; } atomic_set(&dev->vc_enabled, 0); atomic_set(&dev->vp_enabled, 0); dprintk(1, "Exit probe succesfully"); return 0; rel_vcap_wq: destroy_workqueue(dev->vcap_wq); rel_vdev: video_device_release(vfd); deinit_vc: deinit_vc(); power_down: vcap_disable(dev); unreg_dev: v4l2_device_unregister(&dev->v4l2_dev); free_resource: iounmap(dev->vcapbase); release_mem_region(dev->vcapmem->start, resource_size(dev->vcapmem)); free_dev: vcap_ctrl = NULL; kfree(dev); return ret; }
format.format.height = dev->height; format.format.field = dev->field; call_all(dev, pad, set_fmt, NULL, &format); return 0; } static struct video_device *cx23885_vdev_init(struct cx23885_dev *dev, struct pci_dev *pci, struct video_device *template, char *type) { struct video_device *vfd; dprintk(1, "%s()\n", __func__); vfd = video_device_alloc(); if (NULL == vfd) return NULL; *vfd = *template; vfd->v4l2_dev = &dev->v4l2_dev; vfd->release = video_device_release; vfd->lock = &dev->lock; snprintf(vfd->name, sizeof(vfd->name), "%s (%s)", cx23885_boards[dev->board].name, type); video_set_drvdata(vfd, dev); return vfd; } int cx23885_flatiron_write(struct cx23885_dev *dev, u8 reg, u8 data) { /* 8 bit registers, 8 bit values */
/*! * Probe routine for the framebuffer driver. It is called during the * driver binding process. The following functions are performed in * this routine: Framebuffer initialization, Memory allocation and * mapping, Framebuffer registration, IPU initialization. * * @return Appropriate error code to the kernel common code */ static int mxc_v4l2out_probe(struct device *dev) { int i; vout_data *vout; FUNC_START; /* * Allocate sufficient memory for the fb structure */ vout = kmalloc(sizeof(vout_data), GFP_KERNEL); if (!vout) return 0; memset(vout, 0, sizeof(vout_data)); vout->video_dev = video_device_alloc(); if (vout->video_dev == NULL) return -1; vout->video_dev->dev = dev; vout->video_dev->minor = -1; *(vout->video_dev) = mxc_v4l2out_template; /* register v4l device */ if (video_register_device(vout->video_dev, VFL_TYPE_GRABBER, video_nr) == -1) { printk(KERN_DEBUG "video_register_device failed\n"); return 0; } printk(KERN_INFO "mxc_v4l2out: registered device video%d\n", vout->video_dev->minor & 0x1f); video_set_drvdata(vout->video_dev, vout); init_MUTEX(&vout->param_lock); init_MUTEX(&vout->busy_lock); /* setup outputs and cropping */ vout->cur_disp_output = -1; for (i = 0; i < num_registered_fb; i++) { char *idstr = registered_fb[i]->fix.id; if (strncmp(idstr, "DISP", 4) == 0) { int disp_num = idstr[4] - '0'; if ((disp_num == 3) && (strncmp(idstr, "DISP3 BG", 8) != 0)) { continue; } vout->crop_bounds[disp_num].left = 0; vout->crop_bounds[disp_num].top = 0; vout->crop_bounds[disp_num].width = registered_fb[i]->var.xres; vout->crop_bounds[disp_num].height = registered_fb[i]->var.yres; vout->output_enabled[disp_num] = true; vout->output_fb_num[disp_num] = i; if (vout->cur_disp_output == -1) vout->cur_disp_output = disp_num; } } vout->crop_current = vout->crop_bounds[vout->cur_disp_output]; FUNC_END; return 0; }
static int si4703_probe(struct i2c_client *client) { uint16_t id; int ret; struct si4703_device *chip; struct si4703_platform_data *pdata = client->dev.platform_data; chip = kmalloc(sizeof(struct si4703_device), GFP_KERNEL); if (!chip) return -ENOMEM; chip->videodev = video_device_alloc(); if (!chip->videodev) { kfree(chip); return -ENOMEM; } chip->client = client; chip->irq = client->irq; init_waitqueue_head(&chip->wait); i2c_set_clientdata(client, chip); enable_oscc_tout_s0(); pdata->setup(client, pdata->context); if (chip->irq >= 0) { ret = request_irq(chip->irq, si4703_irq_handler, IRQF_TRIGGER_FALLING, "si4703", chip); if (ret) { kfree(chip->videodev); kfree(chip); printk(KERN_ERR "request IRQ for si4703 failed!\n"); return ret; } } /* init shadow registers */ if (si4703_read(chip, REG_READ_START - 1, &id)) { free_irq(chip->irq, chip); kfree(chip->videodev); kfree(chip); printk(KERN_ERR "%s: failed to init shadow registers\n", __FUNCTION__); disable_oscc_tout_s0(); return -EIO; } si4703_power_up(chip); ret = si4703_read(chip, REG_CHIPID, &id); if (ret) printk(KERN_ERR "%s: failed to detect si4703\n", __FUNCTION__); else printk(KERN_INFO "%s: si4703(0x%04x) detected\n", __FUNCTION__, id); si4703_power_down(chip); /* init volume to maxium */ chip->curvol = 0xf; memcpy(chip->videodev, &si4703_videodev_template, sizeof(si4703_videodev_template)); chip->removed = 0; chip->users = 0; chip->curfreq = FREQ_MIN*FREQ_MUL; video_set_drvdata(chip->videodev, chip); if (video_register_device(chip->videodev, VFL_TYPE_RADIO, 0)) { printk(KERN_ERR "Could not register video device"); free_irq(chip->irq, chip); video_device_release(chip->videodev); kfree(chip->videodev); kfree(chip); disable_oscc_tout_s0(); return -EIO; } disable_oscc_tout_s0(); return 0; }
static int empress_init(struct saa7134_dev *dev) { struct v4l2_ctrl_handler *hdl = &dev->empress_ctrl_handler; struct vb2_queue *q; int err; pr_debug("%s: %s\n", dev->name, __func__); dev->empress_dev = video_device_alloc(); if (NULL == dev->empress_dev) return -ENOMEM; *(dev->empress_dev) = saa7134_empress_template; dev->empress_dev->v4l2_dev = &dev->v4l2_dev; dev->empress_dev->release = video_device_release; dev->empress_dev->lock = &dev->lock; snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name), "%s empress (%s)", dev->name, saa7134_boards[dev->board].name); v4l2_ctrl_handler_init(hdl, 21); v4l2_ctrl_add_handler(hdl, &dev->ctrl_handler, empress_ctrl_filter); if (dev->empress_sd) v4l2_ctrl_add_handler(hdl, dev->empress_sd->ctrl_handler, NULL); if (hdl->error) { video_device_release(dev->empress_dev); return hdl->error; } dev->empress_dev->ctrl_handler = hdl; INIT_WORK(&dev->empress_workqueue, empress_signal_update); q = &dev->empress_vbq; q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; /* * Do not add VB2_USERPTR: the saa7134 DMA engine cannot handle * transfers that do not start at the beginning of a page. A USERPTR * can start anywhere in a page, so USERPTR support is a no-go. */ q->io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ; q->drv_priv = &dev->ts_q; q->ops = &saa7134_empress_qops; q->gfp_flags = GFP_DMA32; q->mem_ops = &vb2_dma_sg_memops; q->buf_struct_size = sizeof(struct saa7134_buf); q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; q->lock = &dev->lock; q->dev = &dev->pci->dev; err = vb2_queue_init(q); if (err) return err; dev->empress_dev->queue = q; video_set_drvdata(dev->empress_dev, dev); err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER, empress_nr[dev->nr]); if (err < 0) { pr_info("%s: can't register video device\n", dev->name); video_device_release(dev->empress_dev); dev->empress_dev = NULL; return err; } pr_info("%s: registered device %s [mpeg]\n", dev->name, video_device_node_name(dev->empress_dev)); empress_signal_update(&dev->empress_workqueue); return 0; }
static int fimc_lite_subdev_registered(struct v4l2_subdev *sd) { struct fimc_lite *fimc = v4l2_get_subdevdata(sd); struct vb2_queue *q = &fimc->vb_queue; struct video_device *vfd; int ret; fimc->fmt = &fimc_lite_formats[0]; fimc->out_path = FIMC_IO_DMA; vfd = video_device_alloc(); if (!vfd) { v4l2_err(sd->v4l2_dev, "Failed to allocate video device\n"); return -ENOMEM; } snprintf(vfd->name, sizeof(vfd->name), "fimc-lite.%d.capture", fimc->index); vfd->fops = &fimc_lite_fops; vfd->ioctl_ops = &fimc_lite_ioctl_ops; vfd->v4l2_dev = sd->v4l2_dev; vfd->minor = -1; vfd->release = video_device_release; vfd->lock = &fimc->lock; fimc->vfd = vfd; fimc->ref_count = 0; fimc->reqbufs_count = 0; INIT_LIST_HEAD(&fimc->pending_buf_q); INIT_LIST_HEAD(&fimc->active_buf_q); memset(q, 0, sizeof(*q)); q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; q->io_modes = VB2_MMAP | VB2_USERPTR; q->ops = &fimc_lite_qops; q->mem_ops = &vb2_dma_contig_memops; q->buf_struct_size = sizeof(struct flite_buffer); q->drv_priv = fimc; vb2_queue_init(q); fimc->vd_pad.flags = MEDIA_PAD_FL_SINK; ret = media_entity_init(&vfd->entity, 1, &fimc->vd_pad, 0); if (ret) goto err; video_set_drvdata(vfd, fimc); ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); if (ret) goto err_vd; v4l2_info(sd->v4l2_dev, "Registered %s as /dev/%s\n", vfd->name, video_device_node_name(vfd)); return 0; err_vd: media_entity_cleanup(&vfd->entity); err: video_device_release(vfd); return ret; }
static int g2d_probe(struct platform_device *pdev) { struct g2d_dev *dev; struct video_device *vfd; struct resource *res; int ret = 0; dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) return -ENOMEM; spin_lock_init(&dev->ctrl_lock); mutex_init(&dev->mutex); atomic_set(&dev->num_inst, 0); init_waitqueue_head(&dev->irq_queue); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "failed to find registers\n"); ret = -ENOENT; goto free_dev; } dev->res_regs = request_mem_region(res->start, resource_size(res), dev_name(&pdev->dev)); if (!dev->res_regs) { dev_err(&pdev->dev, "failed to obtain register region\n"); ret = -ENOENT; goto free_dev; } dev->regs = ioremap(res->start, resource_size(res)); if (!dev->regs) { dev_err(&pdev->dev, "failed to map registers\n"); ret = -ENOENT; goto rel_res_regs; } dev->clk = clk_get(&pdev->dev, "sclk_fimg2d"); if (IS_ERR_OR_NULL(dev->clk)) { dev_err(&pdev->dev, "failed to get g2d clock\n"); ret = -ENXIO; goto unmap_regs; } ret = clk_prepare(dev->clk); if (ret) { dev_err(&pdev->dev, "failed to prepare g2d clock\n"); goto put_clk; } dev->gate = clk_get(&pdev->dev, "fimg2d"); if (IS_ERR_OR_NULL(dev->gate)) { dev_err(&pdev->dev, "failed to get g2d clock gate\n"); ret = -ENXIO; goto unprep_clk; } ret = clk_prepare(dev->gate); if (ret) { dev_err(&pdev->dev, "failed to prepare g2d clock gate\n"); goto put_clk_gate; } res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { dev_err(&pdev->dev, "failed to find IRQ\n"); ret = -ENXIO; goto unprep_clk_gate; } dev->irq = res->start; ret = request_irq(dev->irq, g2d_isr, 0, pdev->name, dev); if (ret) { dev_err(&pdev->dev, "failed to install IRQ\n"); goto put_clk_gate; } dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); if (IS_ERR(dev->alloc_ctx)) { ret = PTR_ERR(dev->alloc_ctx); goto rel_irq; } ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); if (ret) goto alloc_ctx_cleanup; vfd = video_device_alloc(); if (!vfd) { v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n"); ret = -ENOMEM; goto unreg_v4l2_dev; } *vfd = g2d_videodev; vfd->lock = &dev->mutex; ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); if (ret) { v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); goto rel_vdev; } video_set_drvdata(vfd, dev); snprintf(vfd->name, sizeof(vfd->name), "%s", g2d_videodev.name); dev->vfd = vfd; v4l2_info(&dev->v4l2_dev, "device registered as /dev/video%d\n", vfd->num); platform_set_drvdata(pdev, dev); dev->m2m_dev = v4l2_m2m_init(&g2d_m2m_ops); if (IS_ERR(dev->m2m_dev)) { v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n"); ret = PTR_ERR(dev->m2m_dev); goto unreg_video_dev; } def_frame.stride = (def_frame.width * def_frame.fmt->depth) >> 3; return 0; unreg_video_dev: video_unregister_device(dev->vfd); rel_vdev: video_device_release(vfd); unreg_v4l2_dev: v4l2_device_unregister(&dev->v4l2_dev); alloc_ctx_cleanup: vb2_dma_contig_cleanup_ctx(dev->alloc_ctx); rel_irq: free_irq(dev->irq, dev); unprep_clk_gate: clk_unprepare(dev->gate); put_clk_gate: clk_put(dev->gate); unprep_clk: clk_unprepare(dev->clk); put_clk: clk_put(dev->clk); unmap_regs: iounmap(dev->regs); rel_res_regs: release_resource(dev->res_regs); free_dev: kfree(dev); return ret; }
static int create_pipe(int nr) { int minor_in, minor_out , ret; if (debug > LOG_NODEBUG) info("Video loopback %d", nr); if (dev_offset == -1) { minor_in = minor_out = -1; /* autoassign */ } else { minor_in = 2 * nr + dev_offset; minor_out = 2 * nr + 1 + dev_offset; } /* allocate space for this pipe */ loops[nr]= kmalloc(sizeof(struct vloopback_pipe), GFP_KERNEL); if (!loops[nr]) return -ENOMEM; /* set up a new video device plus our private area */ loops[nr]->vloopin = video_device_alloc(); if (loops[nr]->vloopin == NULL) return -ENOMEM; *loops[nr]->vloopin = vloopback_template; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) priv_ptr ptr_in = kmalloc(sizeof(struct vloopback_private), GFP_KERNEL); if (ptr_in == NULL) { kfree(ptr_in); #else loops[nr]->vloopin->vd_private_data = kmalloc(sizeof(struct vloopback_private), GFP_KERNEL); if (loops[nr]->vloopin->vd_private_data == NULL) { kfree(loops[nr]->vloopin); #endif return -ENOMEM; } /* repeat for the output device */ loops[nr]->vloopout = video_device_alloc(); if (loops[nr]->vloopout == NULL) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) kfree(ptr_in); #else kfree(loops[nr]->vloopin->vd_private_data); #endif kfree(loops[nr]->vloopin); return -ENOMEM; } *loops[nr]->vloopout = vloopback_template; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) priv_ptr ptr_out = kmalloc(sizeof(struct vloopback_private), GFP_KERNEL); if (ptr_out == NULL) { kfree(ptr_in); kfree(ptr_out); #else loops[nr]->vloopout->vd_private_data = kmalloc(sizeof(struct vloopback_private), GFP_KERNEL); if (loops[nr]->vloopout->vd_private_data == NULL) { kfree(loops[nr]->vloopin->vd_private_data); #endif kfree(loops[nr]->vloopin); kfree(loops[nr]->vloopout); return -ENOMEM; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) ptr_in->pipenr = nr; ptr_out->pipenr = nr; #else ((priv_ptr)loops[nr]->vloopin->vd_private_data)->pipenr = nr; ((priv_ptr)loops[nr]->vloopout->vd_private_data)->pipenr = nr; #endif loops[nr]->invalid_ioctl = 0; /* tibit */ loops[nr]->buffer = NULL; loops[nr]->width = 0; loops[nr]->height = 0; loops[nr]->palette = 0; loops[nr]->frameswrite = 0; loops[nr]->framesread = 0; loops[nr]->framesdumped = 0; loops[nr]->wopen = 0; loops[nr]->ropen = 0; loops[nr]->frame = 0; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) ptr_in->in = 1; ptr_out->in = 0; dev_set_drvdata(&loops[nr]->vloopin->dev, ptr_in); dev_set_drvdata(&loops[nr]->vloopout->dev, ptr_out); #else ((priv_ptr)loops[nr]->vloopin->vd_private_data)->in = 1; ((priv_ptr)loops[nr]->vloopout->vd_private_data)->in = 0; #endif sprintf(loops[nr]->vloopin->name, "Video loopback %d input", nr); sprintf(loops[nr]->vloopout->name, "Video loopback %d output", nr); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) loops[nr]->vloopin->type = 0; loops[nr]->vloopout->type = VID_TYPE_CAPTURE; #endif loops[nr]->vloopout->minor = minor_out; loops[nr]->vloopin->minor = minor_in; init_waitqueue_head(&loops[nr]->wait); init_MUTEX(&loops[nr]->lock); ret = video_register_device(loops[nr]->vloopin, VFL_TYPE_GRABBER, minor_in); if ((ret == -1 ) || ( ret == -23 )) { info("error registering device %s", loops[nr]->vloopin->name); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) kfree(ptr_in); dev_set_drvdata(&loops[nr]->vloopin->dev, NULL); #else kfree(loops[nr]->vloopin->vd_private_data); #endif kfree(loops[nr]->vloopin); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) kfree(ptr_out); dev_set_drvdata(&loops[nr]->vloopout->dev, NULL); #else kfree(loops[nr]->vloopout->vd_private_data); #endif kfree(loops[nr]->vloopout); kfree(loops[nr]); loops[nr] = NULL; return ret; } ret = video_register_device(loops[nr]->vloopout, VFL_TYPE_GRABBER, minor_out); if ((ret ==-1) || (ret == -23)) { info("error registering device %s", loops[nr]->vloopout->name); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) kfree(ptr_in); dev_set_drvdata(&loops[nr]->vloopin->dev, NULL); #else kfree(loops[nr]->vloopin->vd_private_data); #endif video_unregister_device(loops[nr]->vloopin); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32) kfree(ptr_out); dev_set_drvdata(&loops[nr]->vloopout->dev, NULL); #else kfree(loops[nr]->vloopout->vd_private_data); #endif kfree(loops[nr]->vloopout); kfree(loops[nr]); loops[nr] = NULL; return ret; } loops[nr]->ioctldata = kmalloc(1024, GFP_KERNEL); loops[nr]->ioctlretdata = kmalloc(1024, GFP_KERNEL); return 0; } /**************************************************************************** * init stuff ****************************************************************************/ MODULE_AUTHOR("J.B. Vreeken ([email protected])"); MODULE_DESCRIPTION("Video4linux loopback device."); #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) module_param(pipes, int, 000); #else MODULE_PARM(pipes, "i"); #endif MODULE_PARM_DESC(pipes, " Nr of pipes to create (each pipe uses two video devices)"); #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) module_param(spares, int, 000); #else MODULE_PARM(spares, "i"); #endif MODULE_PARM_DESC(spares, " Nr of spare pipes that should be created"); #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) module_param(num_buffers, int, 000); #else MODULE_PARM(num_buffers, "i"); #endif MODULE_PARM_DESC(num_buffers, " Prefered numbers of internal buffers to map (default 2)"); #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) module_param(dev_offset, int, 000); #else MODULE_PARM(dev_offset_param, "i"); #endif MODULE_PARM_DESC(dev_offset, " Prefered offset for video device numbers"); #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) module_param(debug, int, 000); #else MODULE_PARM(debug_param, "i"); #endif MODULE_PARM_DESC(debug, " Enable module debug level 0-3 (by default 0)"); MODULE_LICENSE("GPL"); MODULE_VERSION( VLOOPBACK_VERSION ); static int __init vloopback_init(void) { int i, ret; info("video4linux loopback driver v"VLOOPBACK_VERSION); if (pipes == -1) pipes = 1; if (pipes > MAX_PIPES) { pipes = MAX_PIPES; info("Nr of pipes is limited to: %d", MAX_PIPES); } if (num_buffers < N_BUFFS) { num_buffers = N_BUFFS; info("Nr of buffer set to default value %d", N_BUFFS); } for (i = 0; i < pipes; i++) { ret = create_pipe(i); if (ret == 0) { info("Loopback %d registered, input: video%d," " output: video%d", i, loops[i]->vloopin->minor, loops[i]->vloopout->minor); info("Loopback %d , Using %d buffers", i, num_buffers); nr_o_pipes = i + 1; } else { return ret; } } return 0; }
static int rot_register_m2m_device(struct rot_dev *rot) { struct v4l2_device *v4l2_dev; struct platform_device *pdev; struct video_device *vfd; int ret = 0; if (!rot) return -ENODEV; pdev = rot->pdev; v4l2_dev = &rot->m2m.v4l2_dev; /* Set name to "device name.m2m" if it is empty */ if (!v4l2_dev->name[0]) snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s.m2m", dev_name(&pdev->dev)); ret = v4l2_device_register(&pdev->dev, v4l2_dev); if (ret) { rot_err("failed to register v4l2 device\n"); return ret; } vfd = video_device_alloc(); if (!vfd) { rot_err("failed to allocate video device\n"); goto err_v4l2_dev; } vfd->fops = &rot_v4l2_fops; vfd->ioctl_ops = &rot_v4l2_ioctl_ops; vfd->release = video_device_release; video_set_drvdata(vfd, rot); platform_set_drvdata(pdev, rot); rot->m2m.vfd = vfd; rot->m2m.m2m_dev = v4l2_m2m_init(&rot_m2m_ops); if (IS_ERR(rot->m2m.m2m_dev)) { rot_err("failed to initialize v4l2-m2m device\n"); ret = PTR_ERR(rot->m2m.m2m_dev); goto err_dev_alloc; } ret = video_register_device(vfd, VFL_TYPE_GRABBER, EXYNOS_VIDEONODE_ROTATOR); if (ret) { rot_err("failed to register video device\n"); goto err_m2m_dev; } return 0; err_m2m_dev: v4l2_m2m_release(rot->m2m.m2m_dev); err_dev_alloc: video_device_release(rot->m2m.vfd); err_v4l2_dev: v4l2_device_unregister(v4l2_dev); return ret; }
/* return a list of available devices. the default device (if any) will be * the first in the list. */ static GList * device_list (GstOSXVideoSrc * src) { SeqGrabComponent component = NULL; SGChannel channel; SGDeviceList deviceList; SGDeviceName *deviceEntry; SGDeviceInputList inputList; SGDeviceInputName *inputEntry; ComponentResult err; int n, i; GList *list; video_device *dev, *default_dev; gchar sgname[256]; gchar friendly_name[256]; list = NULL; default_dev = NULL; if (src->video_chan) { /* if we already have a video channel allocated, use that */ GST_DEBUG_OBJECT (src, "reusing existing channel for device_list"); channel = src->video_chan; } else { /* otherwise, allocate a temporary one */ component = OpenDefaultComponent (SeqGrabComponentType, 0); if (!component) { err = paramErr; GST_ERROR_OBJECT (src, "OpenDefaultComponent failed. paramErr=%d", (int) err); goto end; } err = SGInitialize (component); if (err != noErr) { GST_ERROR_OBJECT (src, "SGInitialize returned %d", (int) err); goto end; } err = SGSetDataRef (component, 0, 0, seqGrabDontMakeMovie); if (err != noErr) { GST_ERROR_OBJECT (src, "SGSetDataRef returned %d", (int) err); goto end; } err = SGNewChannel (component, VideoMediaType, &channel); if (err != noErr) { GST_ERROR_OBJECT (src, "SGNewChannel returned %d", (int) err); goto end; } } err = SGGetChannelDeviceList (channel, sgDeviceListIncludeInputs, &deviceList); if (err != noErr) { GST_ERROR_OBJECT (src, "SGGetChannelDeviceList returned %d", (int) err); goto end; } for (n = 0; n < (*deviceList)->count; ++n) { deviceEntry = &(*deviceList)->entry[n]; if (deviceEntry->flags & sgDeviceNameFlagDeviceUnavailable) continue; p2cstrcpy (sgname, deviceEntry->name); inputList = deviceEntry->inputs; if (inputList && (*inputList)->count >= 1) { for (i = 0; i < (*inputList)->count; ++i) { inputEntry = &(*inputList)->entry[i]; p2cstrcpy (friendly_name, inputEntry->name); dev = video_device_alloc (); dev->id = create_device_id (sgname, i); if (!dev->id) { video_device_free (dev); i = -1; break; } dev->name = g_strdup (friendly_name); list = g_list_append (list, dev); /* if this is the default device, note it */ if (n == (*deviceList)->selectedIndex && i == (*inputList)->selectedIndex) { default_dev = dev; } } /* error */ if (i == -1) break; } else { /* ### can a device have no defined inputs? */ dev = video_device_alloc (); dev->id = create_device_id (sgname, -1); if (!dev->id) { video_device_free (dev); break; } dev->name = g_strdup (sgname); list = g_list_append (list, dev); /* if this is the default device, note it */ if (n == (*deviceList)->selectedIndex) { default_dev = dev; } } } /* move default device to the front */ if (default_dev) { list = g_list_remove (list, default_dev); list = g_list_prepend (list, default_dev); } end: if (!src->video_chan && component) { err = CloseComponent (component); if (err != noErr) GST_WARNING_OBJECT (src, "CloseComponent returned %d", (int) err); } return list; }
int __init vpp_init(void) { int ret = 0; struct video_device *video_dev = NULL; logi("in vpp_init: vpp_phymem = 0x%x, camera_phymem = 0x%x, codec_phymem = 0x%x\n", hisi_reserved_vpp_phymem, hisi_reserved_camera_phymem, hisi_reserved_codec_phymem); /* alloc memory for video device */ video_dev = video_device_alloc(); if (NULL == video_dev) { loge("alloc video device failed\n"); ret = -ENOMEM; goto err; } /* init v4l device */ s_interrupt_cond = false; *video_dev = s_vpp_device; /* register vpp device */ if (video_register_device(video_dev, 0, VPP_DEVICE_ID)) { loge("video device register failed\n"); ret = -EINVAL; goto err; } s_vpp_device_p = video_dev; /*init the wait queue*/ init_waitqueue_head(&s_wait_queue); /*register a irq for vpp*/ ret = request_irq(IRQ_VPP, vpp_isr, 0, "VPP", NULL); if(ret != 0) { loge("fail to request irq, ret = 0x%x\n",ret); goto err; } s_vdec_vcc = regulator_get(NULL, "vcc_vdec"); if (IS_ERR(s_vdec_vcc)) { loge("%s: failed to get vcc_vdec regulator\n", __func__); ret = PTR_ERR(s_vdec_vcc); s_vdec_vcc = NULL; goto err; } s_clk = clk_get(NULL, "clk_vpp"); if (IS_ERR(s_clk)) { loge("get clock failed\n"); ret = PTR_ERR(s_clk); goto err; } hal_init(); return ret; err: loge("module not inserted\n"); if (NULL != s_vpp_device_p) { video_unregister_device(video_dev); s_vpp_device_p = NULL; } if(NULL != video_dev) { kfree(video_dev); video_dev = NULL; } if (NULL != s_vdec_vcc) { regulator_put(s_vdec_vcc); s_vdec_vcc = NULL; } return ret; }
/* * vpif_probe: This function creates device entries by register itself to the * V4L2 driver and initializes fields of each channel objects */ static __init int vpif_probe(struct platform_device *pdev) { struct vpif_subdev_info *subdevdata; struct vpif_display_config *config; int i, j = 0, k, q, m, err = 0; struct i2c_adapter *i2c_adap; struct common_obj *common; struct channel_obj *ch; struct video_device *vfd; struct resource *res; int subdev_count; vpif_dev = &pdev->dev; err = initialize_vpif(); if (err) { v4l2_err(vpif_dev->driver, "Error initializing vpif\n"); return err; } err = v4l2_device_register(vpif_dev, &vpif_obj.v4l2_dev); if (err) { v4l2_err(vpif_dev->driver, "Error registering v4l2 device\n"); return err; } k = 0; while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, k))) { for (i = res->start; i <= res->end; i++) { if (request_irq(i, vpif_channel_isr, IRQF_DISABLED, "DM646x_Display", (void *)(&vpif_obj.dev[k]->channel_id))) { err = -EBUSY; goto vpif_int_err; } } k++; } for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) { /* Get the pointer to the channel object */ ch = vpif_obj.dev[i]; /* Allocate memory for video device */ vfd = video_device_alloc(); if (vfd == NULL) { for (j = 0; j < i; j++) { ch = vpif_obj.dev[j]; video_device_release(ch->video_dev); } err = -ENOMEM; goto vpif_int_err; } /* Initialize field of video device */ *vfd = vpif_video_template; vfd->v4l2_dev = &vpif_obj.v4l2_dev; vfd->release = video_device_release; snprintf(vfd->name, sizeof(vfd->name), "DM646x_VPIFDisplay_DRIVER_V%d.%d.%d", (VPIF_DISPLAY_VERSION_CODE >> 16) & 0xff, (VPIF_DISPLAY_VERSION_CODE >> 8) & 0xff, (VPIF_DISPLAY_VERSION_CODE) & 0xff); /* Set video_dev to the video device */ ch->video_dev = vfd; } for (j = 0; j < VPIF_DISPLAY_MAX_DEVICES; j++) { ch = vpif_obj.dev[j]; /* Initialize field of the channel objects */ atomic_set(&ch->usrs, 0); for (k = 0; k < VPIF_NUMOBJECTS; k++) { ch->common[k].numbuffers = 0; common = &ch->common[k]; common->io_usrs = 0; common->started = 0; spin_lock_init(&common->irqlock); mutex_init(&common->lock); common->numbuffers = 0; common->set_addr = NULL; common->ytop_off = common->ybtm_off = 0; common->ctop_off = common->cbtm_off = 0; common->cur_frm = common->next_frm = NULL; memset(&common->fmt, 0, sizeof(common->fmt)); common->numbuffers = config_params.numbuffers[k]; } ch->initialized = 0; ch->channel_id = j; if (j < 2) ch->common[VPIF_VIDEO_INDEX].numbuffers = config_params.numbuffers[ch->channel_id]; else ch->common[VPIF_VIDEO_INDEX].numbuffers = 0; memset(&ch->vpifparams, 0, sizeof(ch->vpifparams)); /* Initialize prio member of channel object */ v4l2_prio_init(&ch->prio); ch->common[VPIF_VIDEO_INDEX].fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; ch->video_dev->lock = &common->lock; /* register video device */ vpif_dbg(1, debug, "channel=%x,channel->video_dev=%x\n", (int)ch, (int)&ch->video_dev); err = video_register_device(ch->video_dev, VFL_TYPE_GRABBER, (j ? 3 : 2)); if (err < 0) goto probe_out; video_set_drvdata(ch->video_dev, ch); } i2c_adap = i2c_get_adapter(1); config = pdev->dev.platform_data; subdev_count = config->subdev_count; subdevdata = config->subdevinfo; vpif_obj.sd = kzalloc(sizeof(struct v4l2_subdev *) * subdev_count, GFP_KERNEL); if (vpif_obj.sd == NULL) { vpif_err("unable to allocate memory for subdevice pointers\n"); err = -ENOMEM; goto probe_out; } for (i = 0; i < subdev_count; i++) { vpif_obj.sd[i] = v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev, i2c_adap, &subdevdata[i].board_info, NULL); if (!vpif_obj.sd[i]) { vpif_err("Error registering v4l2 subdevice\n"); goto probe_subdev_out; } if (vpif_obj.sd[i]) vpif_obj.sd[i]->grp_id = 1 << i; } v4l2_info(&vpif_obj.v4l2_dev, "DM646x VPIF display driver initialized\n"); return 0; probe_subdev_out: kfree(vpif_obj.sd); probe_out: for (k = 0; k < j; k++) { ch = vpif_obj.dev[k]; video_unregister_device(ch->video_dev); video_device_release(ch->video_dev); ch->video_dev = NULL; } vpif_int_err: v4l2_device_unregister(&vpif_obj.v4l2_dev); vpif_err("VPIF IRQ request failed\n"); for (q = k; k >= 0; k--) { for (m = i; m >= res->start; m--) free_irq(m, (void *)(&vpif_obj.dev[k]->channel_id)); res = platform_get_resource(pdev, IORESOURCE_IRQ, k-1); m = res->end; } return err; }
int gsc_register_capture_device(struct gsc_dev *gsc) { struct video_device *vfd; struct gsc_capture_device *gsc_cap; struct gsc_ctx *ctx; struct vb2_queue *q; struct exynos_platform_gscaler *pdata = gsc->pdata; struct exynos_isp_info *isp_info; int ret = -ENOMEM; int i; ctx = kzalloc(sizeof *ctx, GFP_KERNEL); if (!ctx) return -ENOMEM; ctx->gsc_dev = gsc; ctx->in_path = GSC_CAMERA; ctx->out_path = GSC_DMA; ctx->state = GSC_CTX_CAP; vfd = video_device_alloc(); if (!vfd) { printk("Failed to allocate video device\n"); goto err_ctx_alloc; } snprintf(vfd->name, sizeof(vfd->name), "%s.capture", dev_name(&gsc->pdev->dev)); vfd->fops = &gsc_capture_fops; vfd->ioctl_ops = &gsc_capture_ioctl_ops; vfd->v4l2_dev = &gsc->mdev[MDEV_CAPTURE]->v4l2_dev; vfd->minor = -1; vfd->release = video_device_release; vfd->lock = &gsc->lock; video_set_drvdata(vfd, gsc); gsc_cap = &gsc->cap; gsc_cap->vfd = vfd; gsc_cap->refcnt = 0; gsc_cap->active_buf_cnt = 0; gsc_cap->reqbufs_cnt = 0; spin_lock_init(&ctx->slock); gsc_cap->ctx = ctx; q = &gsc->cap.vbq; memset(q, 0, sizeof(*q)); q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; q->drv_priv = gsc->cap.ctx; q->ops = &gsc_capture_qops; q->mem_ops = gsc->vb2->ops; vb2_queue_init(q); /* Get mipi-csis and fimc-lite subdev ptr using mdev */ for (i = 0; i < FLITE_MAX_ENTITIES; i++) gsc->cap.sd_flite[i] = gsc->mdev[MDEV_CAPTURE]->flite_sd[i]; for (i = 0; i < CSIS_MAX_ENTITIES; i++) gsc->cap.sd_csis[i] = gsc->mdev[MDEV_CAPTURE]->csis_sd[i]; if (soc_is_exynos5250()) { for (i = 0; i < pdata->num_clients; i++) { isp_info = pdata->isp_info[i]; ret = gsc_cap_config_camclk(gsc, isp_info, i); if (ret) { gsc_err("failed setup cam clk"); goto err_ctx_alloc; } } } ret = gsc_cap_register_sensor_entities(gsc); if (ret) { gsc_err("failed register sensor entities"); goto err_clk; } ret = video_register_device(vfd, VFL_TYPE_GRABBER, EXYNOS_VIDEONODE_GSC_CAP(gsc->id)); if (ret) { gsc_err("failed to register video device"); goto err_clk; } gsc->cap.vd_pad.flags = MEDIA_PAD_FL_SOURCE; ret = media_entity_init(&vfd->entity, 1, &gsc->cap.vd_pad, 0); if (ret) { gsc_err("failed to initialize entity"); goto err_ent; } ret = gsc_capture_create_subdev(gsc); if (ret) { gsc_err("failed create subdev"); goto err_sd_reg; } ret = gsc_capture_create_link(gsc); if (ret) { gsc_err("failed create link"); goto err_sd_reg; } vfd->ctrl_handler = &ctx->ctrl_handler; gsc_dbg("gsc capture driver registered as /dev/video%d", vfd->num); return 0; err_sd_reg: media_entity_cleanup(&vfd->entity); err_ent: video_device_release(vfd); err_clk: if (soc_is_exynos5250()) { for (i = 0; i < pdata->num_clients; i++) clk_put(gsc_cap->sensor[i].camclk); } err_ctx_alloc: kfree(ctx); return ret; }
int fm_v4l2_init_video_device(struct fmdev *fmdev, int radio_nr) { struct v4l2_ctrl *ctrl; int ret; /* Init mutex for core locking */ mutex_init(&fmdev->mutex); /* Allocate new video device */ gradio_dev = video_device_alloc(); if (NULL == gradio_dev) { fmerr("Can't allocate video device\n"); return -ENOMEM; } /* Setup FM driver's V4L2 properties */ memcpy(gradio_dev, &fm_viddev_template, sizeof(fm_viddev_template)); video_set_drvdata(gradio_dev, fmdev); gradio_dev->lock = &fmdev->mutex; /* Register with V4L2 subsystem as RADIO device */ if (video_register_device(gradio_dev, VFL_TYPE_RADIO, radio_nr)) { video_device_release(gradio_dev); fmerr("Could not register video device\n"); return -ENOMEM; } fmdev->radio_dev = gradio_dev; /* Register to v4l2 ctrl handler framework */ fmdev->radio_dev->ctrl_handler = &fmdev->ctrl_handler; ret = v4l2_ctrl_handler_init(&fmdev->ctrl_handler, 5); if (ret < 0) { fmerr("(fmdev): Can't init ctrl handler\n"); v4l2_ctrl_handler_free(&fmdev->ctrl_handler); return -EBUSY; } /* * Following controls are handled by V4L2 control framework. * Added in ascending ID order. */ v4l2_ctrl_new_std(&fmdev->ctrl_handler, &fm_ctrl_ops, V4L2_CID_AUDIO_VOLUME, FM_RX_VOLUME_MIN, FM_RX_VOLUME_MAX, 1, FM_RX_VOLUME_MAX); v4l2_ctrl_new_std(&fmdev->ctrl_handler, &fm_ctrl_ops, V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0); v4l2_ctrl_new_std(&fmdev->ctrl_handler, &fm_ctrl_ops, V4L2_CID_RDS_TX_PI, 0x0, 0xffff, 1, 0x0); v4l2_ctrl_new_std(&fmdev->ctrl_handler, &fm_ctrl_ops, V4L2_CID_RDS_TX_PTY, 0, 32, 1, 0); v4l2_ctrl_new_std(&fmdev->ctrl_handler, &fm_ctrl_ops, V4L2_CID_RDS_TX_PS_NAME, 0, 0xffff, 1, 0); v4l2_ctrl_new_std(&fmdev->ctrl_handler, &fm_ctrl_ops, V4L2_CID_RDS_TX_RADIO_TEXT, 0, 0xffff, 1, 0); v4l2_ctrl_new_std_menu(&fmdev->ctrl_handler, &fm_ctrl_ops, V4L2_CID_TUNE_PREEMPHASIS, V4L2_PREEMPHASIS_75_uS, 0, V4L2_PREEMPHASIS_75_uS); v4l2_ctrl_new_std(&fmdev->ctrl_handler, &fm_ctrl_ops, V4L2_CID_TUNE_POWER_LEVEL, FM_PWR_LVL_LOW, FM_PWR_LVL_HIGH, 1, FM_PWR_LVL_HIGH); ctrl = v4l2_ctrl_new_std(&fmdev->ctrl_handler, &fm_ctrl_ops, V4L2_CID_TUNE_ANTENNA_CAPACITOR, 0, 255, 1, 255); if (ctrl) ctrl->is_volatile = 1; return 0; }
static int32_t cam_dummy_platform_probe(struct platform_device *pdev) { int32_t rc = 0; const struct of_device_id *match; struct msm_video_device *pvdev; /* init_waitqueue_head(&cam_dummy_queue.state_wait);*/ pr_err("%s:%d\n", __func__, __LINE__); match = of_match_device(cam_dummy_dt_match, &pdev->dev); msm_v4l2_dev = kzalloc(sizeof(*msm_v4l2_dev), GFP_KERNEL); if (WARN_ON(!msm_v4l2_dev)) { rc = -ENOMEM; goto probe_end; } pvdev = kzalloc(sizeof(struct msm_video_device), GFP_KERNEL); if (WARN_ON(!pvdev)) { rc = -ENOMEM; goto pvdev_fail; } pvdev->vdev = video_device_alloc(); if (WARN_ON(!pvdev->vdev)) { rc = -ENOMEM; goto video_fail; } #if defined(CONFIG_MEDIA_CONTROLLER) msm_v4l2_dev->mdev = kzalloc(sizeof(struct media_device), GFP_KERNEL); if (!msm_v4l2_dev->mdev) { rc = -ENOMEM; goto mdev_fail; } strlcpy(msm_v4l2_dev->mdev->model, MSM_CAMERA_DUMMY_NAME, sizeof(msm_v4l2_dev->mdev->model)); msm_v4l2_dev->mdev->dev = &(pdev->dev); rc = media_device_register(msm_v4l2_dev->mdev); if (WARN_ON(rc < 0)) goto media_fail; if (WARN_ON((rc == media_entity_init(&pvdev->vdev->entity, 0, NULL, 0)) < 0)) goto entity_fail; pvdev->vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L; pvdev->vdev->entity.group_id = QCAMERA_VNODE_GROUP_ID; #endif pvdev->vdev->v4l2_dev = msm_v4l2_dev; rc = v4l2_device_register(&(pdev->dev), pvdev->vdev->v4l2_dev); if (WARN_ON(rc < 0)) goto register_fail; strlcpy(pvdev->vdev->name, "msm-camdummy", sizeof(pvdev->vdev->name)); pvdev->vdev->release = video_device_release; pvdev->vdev->fops = &msm_fops_config; pvdev->vdev->minor = -1; pvdev->vdev->vfl_type = VFL_TYPE_GRABBER; rc = video_register_device(pvdev->vdev, VFL_TYPE_GRABBER, -1); if (WARN_ON(rc < 0)) goto v4l2_fail; #if defined(CONFIG_MEDIA_CONTROLLER) /* FIXME: How to get rid of this messy? */ pvdev->vdev->entity.name = video_device_node_name(pvdev->vdev); #endif atomic_set(&pvdev->opened, 0); video_set_drvdata(pvdev->vdev, pvdev); goto probe_end; v4l2_fail: v4l2_device_unregister(pvdev->vdev->v4l2_dev); register_fail: #if defined(CONFIG_MEDIA_CONTROLLER) media_entity_cleanup(&pvdev->vdev->entity); entity_fail: media_device_unregister(msm_v4l2_dev->mdev); media_fail: kzfree(msm_v4l2_dev->mdev); mdev_fail: #endif video_device_release(pvdev->vdev); video_fail: kzfree(pvdev); pvdev_fail: kzfree(msm_v4l2_dev); probe_end: return rc; }
static int create_pipe(int nr) { int minor_in, minor_out , ret; if (dev_offset == -1) { if (inminor == -1) { minor_in = -1; } else { minor_in = inminor+nr; } if (outminor == -1) { minor_out = -1; } else { minor_out = outminor+nr; } } else { minor_in = 2*nr + dev_offset; minor_out = 2*nr+1 + dev_offset; } /* allocate space for this pipe */ loops[nr]= kmalloc(sizeof(struct vloopback_pipe), GFP_KERNEL); if (!loops[nr]) return -ENOMEM; /* set up a new video device plus our private area */ loops[nr]->vloopin= video_device_alloc(); if (loops[nr]->vloopin == NULL) return -ENOMEM; *loops[nr]->vloopin = vloopback_template; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) video_set_drvdata(loops[nr]->vloopin,kmalloc(sizeof(struct vloopback_private),GFP_KERNEL)); #else loops[nr]->vloopin->priv= kmalloc(sizeof(struct vloopback_private),GFP_KERNEL); #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) if ((priv_ptr)video_get_drvdata(loops[nr]->vloopin) == NULL) { #else if (loops[nr]->vloopin->priv == NULL) { #endif kfree(loops[nr]->vloopin); return -ENOMEM; } /* repeat for the output device */ loops[nr]->vloopout= video_device_alloc(); if (loops[nr]->vloopout == NULL) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) kfree((priv_ptr)video_get_drvdata(loops[nr]->vloopin)); #else kfree(loops[nr]->vloopin->priv); #endif kfree(loops[nr]->vloopin); return -ENOMEM; } *loops[nr]->vloopout = vloopback_template; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) video_set_drvdata(loops[nr]->vloopout,kmalloc(sizeof(struct vloopback_private),GFP_KERNEL)); #else loops[nr]->vloopout->priv= kmalloc(sizeof(struct vloopback_private),GFP_KERNEL); #endif if ((priv_ptr)video_get_drvdata(loops[nr]->vloopout) == NULL) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) kfree((priv_ptr)video_get_drvdata(loops[nr]->vloopin)); #else kfree(loops[nr]->vloopin->priv); #endif kfree(loops[nr]->vloopin); kfree(loops[nr]->vloopout); return -ENOMEM; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) ((priv_ptr)video_get_drvdata(loops[nr]->vloopin))->pipenr=nr; ((priv_ptr)video_get_drvdata(loops[nr]->vloopout))->pipenr=nr; #else ((priv_ptr)loops[nr]->vloopin->priv)->pipenr=nr; ((priv_ptr)loops[nr]->vloopout->priv)->pipenr=nr; #endif loops[nr]->invalid_ioctl = 0; /* tibit */ loops[nr]->buffer=NULL; loops[nr]->width=0; loops[nr]->height=0; loops[nr]->palette=0; loops[nr]->frameswrite=0; loops[nr]->framesread=0; loops[nr]->framesdumped=0; loops[nr]->wopen=0; loops[nr]->ropen=0; loops[nr]->frame=0; loops[nr]->pendingread=0; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) ((priv_ptr)video_get_drvdata(loops[nr]->vloopin))->in=1; ((priv_ptr)video_get_drvdata(loops[nr]->vloopout))->in=0; #else ((priv_ptr)loops[nr]->vloopin->priv)->in=1; ((priv_ptr)loops[nr]->vloopout->priv)->in=0; #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) loops[nr]->vloopin->type=0; #endif sprintf(loops[nr]->vloopin->name, "Video loopback %d input", nr); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) loops[nr]->vloopout->type=VID_TYPE_CAPTURE; #endif sprintf(loops[nr]->vloopout->name, "Video loopback %d output", nr); init_waitqueue_head(&loops[nr]->wait); init_MUTEX(&loops[nr]->lock); ret = video_register_device(loops[nr]->vloopout, VFL_TYPE_GRABBER, minor_out); if ((ret ==-1) || (ret == -23)) { info("error registering device %s", loops[nr]->vloopout->name); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) kfree(((priv_ptr)video_get_drvdata(loops[nr]->vloopin))); video_unregister_device(loops[nr]->vloopin); kfree(((priv_ptr)video_get_drvdata(loops[nr]->vloopout))); #else kfree(loops[nr]->vloopin->priv); video_unregister_device(loops[nr]->vloopin); kfree(loops[nr]->vloopout->priv); #endif kfree(loops[nr]->vloopout); kfree(loops[nr]); loops[nr]=NULL; return ret; } ret = video_register_device(loops[nr]->vloopin, VFL_TYPE_GRABBER, minor_in); if ((ret == -1 ) || ( ret == -23 )) { info("error registering device %s",loops[nr]->vloopin->name); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) kfree(((priv_ptr)video_get_drvdata(loops[nr]->vloopin))); kfree(((priv_ptr)video_get_drvdata(loops[nr]->vloopout))); #else kfree(loops[nr]->vloopin->priv); kfree(loops[nr]->vloopout->priv); #endif kfree(loops[nr]->vloopin); kfree(loops[nr]->vloopout); kfree(loops[nr]); loops[nr]=NULL; return ret; } loops[nr]->ioctldata=kmalloc(1024, GFP_KERNEL); loops[nr]->ioctlretdata=kmalloc(1024, GFP_KERNEL); return 0; } /**************************************************************************** * init stuff ****************************************************************************/ MODULE_AUTHOR("J.B. Vreeken ([email protected])"); MODULE_DESCRIPTION("Video4linux loopback device."); #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) module_param(pipes, int, 000); #else MODULE_PARM(pipes, "i"); #endif MODULE_PARM_DESC(pipes, "Nr of pipes to create (each pipe uses two video devices)"); #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) module_param(spares, int, 000); #else MODULE_PARM(spares, "i"); #endif MODULE_PARM_DESC(spares, "Nr of spare pipes that should be created"); #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) module_param(dev_offset, int, 000); #else MODULE_PARM(dev_offset_param, "i"); #endif #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) module_param(inminor, int, 000); #else MODULE_PARM(inminor, "i"); #endif #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) module_param(outminor, int, 000); #else MODULE_PARM(outminor, "i"); #endif MODULE_PARM_DESC(dev_offset, "Prefered offset for video device numbers"); MODULE_LICENSE("GPL"); MODULE_VERSION( VLOOPBACK_VERSION ); static int __init vloopback_init(void) { int i,ret; info("Video4linux loopback driver v"VLOOPBACK_VERSION); if (pipes==-1) pipes=1; if (pipes > MAX_PIPES) { pipes=MAX_PIPES; info("Nr of pipes is limited to: %d", MAX_PIPES); } for (i=0; i<pipes; i++) { ret = create_pipe(i); if (ret == 0) { info("Loopback %d registered, input: video%d, output: video%d", i, loops[i]->vloopin->minor, loops[i]->vloopout->minor); nr_o_pipes=i+1; }else{ return ret; } } return 0; }
int __init camera_core_init(void) { struct camera_device *cam; struct video_device *vfd; cam = kmalloc(sizeof(struct camera_device), GFP_KERNEL); if (!cam) { printk(KERN_ERR CAM_NAME ": could not allocate memory\n"); goto init_error; } memset(cam, 0, sizeof(struct camera_device)); /* Save the pointer to camera device in a global variable */ camera_dev = cam; cam->active = 0; /* initialize the video_device struct */ vfd = cam->vfd = video_device_alloc(); if (!vfd) { printk(KERN_ERR CAM_NAME ": could not allocate video device struct\n"); goto init_error; } vfd->release = video_device_release; strlcpy(vfd->name, CAM_NAME, sizeof(vfd->name)); vfd->type = VID_TYPE_CAPTURE | VID_TYPE_OVERLAY | VID_TYPE_CHROMAKEY; /* need to register for a VID_HARDWARE_* ID in videodev.h */ vfd->hardware = 0; vfd->fops = &camera_core_fops; video_set_drvdata(vfd, cam); vfd->minor = -1; /* initialize the videobuf queue ops */ cam->vbq_ops.buf_setup = camera_core_vbq_setup; cam->vbq_ops.buf_prepare = camera_core_vbq_prepare; cam->vbq_ops.buf_queue = camera_core_vbq_queue; cam->vbq_ops.buf_release = camera_core_vbq_release; /* initilize the overlay interface */ cam->overlay_size = overlay_mem; if (cam->overlay_size > 0) { cam->overlay_base = (unsigned long) dma_alloc_coherent(NULL, cam->overlay_size, (dma_addr_t *) &cam->overlay_base_phys, GFP_KERNEL | GFP_DMA); if (!cam->overlay_base) { printk(KERN_ERR CAM_NAME ": cannot allocate overlay framebuffer\n"); goto init_error; } } memset((void*)cam->overlay_base, 0, cam->overlay_size); spin_lock_init(&cam->overlay_lock); spin_lock_init(&cam->capture_lock); /*Initialise the pointer to the sensor interface and camera interface */ cam->cam_sensor = &camera_sensor_if; cam->cam_hardware = &camera_hardware_if; /* initialize the camera interface */ cam->hardware_data = cam->cam_hardware->init(); if (!cam->hardware_data) { printk(KERN_ERR CAM_NAME ": cannot initialize interface hardware\n"); goto init_error; } /* initialize the spinlock used to serialize access to the image * parameters */ spin_lock_init(&cam->img_lock); /* initialize the streaming capture parameters */ cam->cparm.capability = V4L2_CAP_TIMEPERFRAME; cam->cparm.readbuffers = 1; /* Enable the xclk output. The sensor may (and does, in the case of * the OV9640) require an xclk input in order for its initialization * routine to work. */ cam->xclk = 21000000; /* choose an arbitrary xclk frequency */ cam->xclk = cam->cam_hardware->set_xclk(cam->xclk, cam->hardware_data); /* initialize the sensor and define a default capture format cam->pix */ cam->sensor_data = cam->cam_sensor->init(&cam->pix); if (!cam->sensor_data) { cam->cam_hardware->disable(cam->hardware_data); printk(KERN_ERR CAM_NAME ": cannot initialize sensor\n"); goto init_error; } printk(KERN_INFO CAM_NAME ": %s interface with %s sensor\n", cam->cam_hardware->name, cam->cam_sensor->name); /* select an arbitrary default capture frame rate of 15fps */ cam->nominal_timeperframe.numerator = 1; cam->nominal_timeperframe.denominator = 15; /* calculate xclk based on the default capture format and default * frame rate */ cam->xclk = cam->cam_sensor->calc_xclk(&cam->pix, &cam->nominal_timeperframe, cam->sensor_data); cam->cparm.timeperframe = cam->nominal_timeperframe; /* initialise the wait queue */ init_waitqueue_head(&cam->new_video_frame); /* Initialise the DMA structures */ camera_core_sgdma_init(cam); /* Disable the Camera after detection */ cam->cam_hardware->disable(cam->hardware_data); dev_set_drvdata(&camera_core_device.dev, (void *)cam); if (platform_device_register(&camera_core_device) < 0) { printk(KERN_ERR CAM_NAME ": could not register platform_device\n"); goto init_error; } if (driver_register(&camera_core_driver) < 0) { printk(KERN_ERR CAM_NAME ": could not register driver\n"); platform_device_unregister(&camera_core_device); goto init_error; } if (video_register_device(vfd, VFL_TYPE_GRABBER, video_nr) < 0) { printk(KERN_ERR CAM_NAME ": could not register Video for Linux device\n"); platform_device_unregister(&camera_core_device); driver_unregister(&camera_core_driver); goto init_error; } printk(KERN_INFO CAM_NAME ": registered device video%d [v4l2]\n", vfd->minor); return 0; init_error: camera_core_cleanup(); return -ENODEV; }
static int __init ar_init(void) { struct ar_device *ar; int ret; int i; DEBUG(1, "ar_init:\n"); ret = -EIO; printk(KERN_INFO "arv: Colour AR VGA driver %s\n", VERSION); ar = &ardev; memset(ar, 0, sizeof(struct ar_device)); #if USE_INT /* allocate a DMA buffer for 1 line. */ ar->line_buff = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL | GFP_DMA); if (ar->line_buff == NULL || ! ALIGN4(ar->line_buff)) { printk("arv: buffer allocation failed for DMA.\n"); ret = -ENOMEM; goto out_end; } #endif /* allocate buffers for a frame */ for (i = 0; i < MAX_AR_HEIGHT; i++) { ar->frame[i] = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL); if (ar->frame[i] == NULL || ! ALIGN4(ar->frame[i])) { printk("arv: buffer allocation failed for frame.\n"); ret = -ENOMEM; goto out_line_buff; } } ar->vdev = video_device_alloc(); if (!ar->vdev) { printk(KERN_ERR "arv: video_device_alloc() failed\n"); return -ENOMEM; } memcpy(ar->vdev, &ar_template, sizeof(ar_template)); ar->vdev->priv = ar; if (vga) { ar->width = AR_WIDTH_VGA; ar->height = AR_HEIGHT_VGA; ar->size = AR_SIZE_VGA; ar->frame_bytes = AR_FRAME_BYTES_VGA; ar->line_bytes = AR_LINE_BYTES_VGA; if (vga_interlace) ar->mode = AR_MODE_INTERLACE; else ar->mode = AR_MODE_NORMAL; } else { ar->width = AR_WIDTH_QVGA; ar->height = AR_HEIGHT_QVGA; ar->size = AR_SIZE_QVGA; ar->frame_bytes = AR_FRAME_BYTES_QVGA; ar->line_bytes = AR_LINE_BYTES_QVGA; ar->mode = AR_MODE_INTERLACE; } init_MUTEX(&ar->lock); init_waitqueue_head(&ar->wait); #if USE_INT if (request_irq(M32R_IRQ_INT3, ar_interrupt, 0, "arv", ar)) { printk("arv: request_irq(%d) failed.\n", M32R_IRQ_INT3); ret = -EIO; goto out_irq; } #endif if (ar_initialize(ar->vdev) != 0) { printk("arv: M64278 not found.\n"); ret = -ENODEV; goto out_dev; } /* * ok, we can initialize h/w according to parameters, * so register video device as a frame grabber type. * device is named "video[0-64]". * video_register_device() initializes h/w using ar_initialize(). */ if (video_register_device(ar->vdev, VFL_TYPE_GRABBER, video_nr) != 0) { /* return -1, -ENFILE(full) or others */ printk("arv: register video (Colour AR) failed.\n"); ret = -ENODEV; goto out_dev; } printk("video%d: Found M64278 VGA (IRQ %d, Freq %dMHz).\n", ar->vdev->minor, M32R_IRQ_INT3, freq); return 0; out_dev: #if USE_INT free_irq(M32R_IRQ_INT3, ar); out_irq: #endif for (i = 0; i < MAX_AR_HEIGHT; i++) kfree(ar->frame[i]); out_line_buff: #if USE_INT kfree(ar->line_buff); out_end: #endif return ret; }
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; }
/* * si470x_i2c_probe - probe for the device */ static int __devinit si470x_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct si470x_device *radio; int retval = 0; unsigned char version_warning = 0; /* private data allocation and initialization */ radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL); if (!radio) { retval = -ENOMEM; goto err_initial; } radio->users = 0; radio->client = client; mutex_init(&radio->lock); /* video device allocation and initialization */ radio->videodev = video_device_alloc(); if (!radio->videodev) { retval = -ENOMEM; goto err_radio; } memcpy(radio->videodev, &si470x_viddev_template, sizeof(si470x_viddev_template)); video_set_drvdata(radio->videodev, radio); /* power up : need 110ms */ radio->registers[POWERCFG] = POWERCFG_ENABLE; if (si470x_set_register(radio, POWERCFG) < 0) { retval = -EIO; goto err_video; } msleep(110); /* get device and chip versions */ if (si470x_get_all_registers(radio) < 0) { retval = -EIO; goto err_video; } dev_info(&client->dev, "DeviceID=0x%4.4hx ChipID=0x%4.4hx\n", radio->registers[DEVICEID], radio->registers[CHIPID]); if ((radio->registers[CHIPID] & CHIPID_FIRMWARE) < RADIO_FW_VERSION) { dev_warn(&client->dev, "This driver is known to work with " "firmware version %hu,\n", RADIO_FW_VERSION); dev_warn(&client->dev, "but the device has firmware version %hu.\n", radio->registers[CHIPID] & CHIPID_FIRMWARE); version_warning = 1; } /* give out version warning */ if (version_warning == 1) { dev_warn(&client->dev, "If you have some trouble using this driver,\n"); dev_warn(&client->dev, "please report to V4L ML at " "[email protected]\n"); } /* set initial frequency */ si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */ /* rds buffer allocation */ radio->buf_size = rds_buf * 3; radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL); if (!radio->buffer) { retval = -EIO; goto err_video; } /* rds buffer configuration */ radio->wr_index = 0; radio->rd_index = 0; init_waitqueue_head(&radio->read_queue); /* mark Seek/Tune Complete Interrupt enabled */ radio->stci_enabled = true; init_completion(&radio->completion); retval = request_threaded_irq(client->irq, NULL, si470x_i2c_interrupt, IRQF_TRIGGER_FALLING, DRIVER_NAME, radio); if (retval) { dev_err(&client->dev, "Failed to register interrupt\n"); goto err_rds; } /* register video device */ retval = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr); if (retval) { dev_warn(&client->dev, "Could not register video device\n"); goto err_all; } i2c_set_clientdata(client, radio); return 0; err_all: free_irq(client->irq, radio); err_rds: kfree(radio->buffer); err_video: video_device_release(radio->videodev); err_radio: kfree(radio); err_initial: return retval; }
static int cx18_prep_dev(struct cx18 *cx, int type) { struct cx18_stream *s = &cx->streams[type]; u32 cap = cx->v4l2_cap; int num_offset = cx18_stream_info[type].num_offset; int num = cx->instance + cx18_first_minor + num_offset; s->video_dev = NULL; s->dvb = NULL; s->cx = cx; s->type = type; s->name = cx18_stream_info[type].name; if (type == CX18_ENC_STREAM_TYPE_RAD && !(cap & V4L2_CAP_RADIO)) return 0; if (type == CX18_ENC_STREAM_TYPE_VBI && !(cap & (V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE))) return 0; if (cx18_stream_info[type].dma != PCI_DMA_NONE && cx->stream_buffers[type] == 0) { CX18_INFO("Disabled %s device\n", cx18_stream_info[type].name); return 0; } cx18_stream_init(cx, type); if (type == CX18_ENC_STREAM_TYPE_TS) { if (cx->card->hw_all & CX18_HW_DVB) { s->dvb = kzalloc(sizeof(struct cx18_dvb), GFP_KERNEL); if (s->dvb == NULL) { CX18_ERR("Couldn't allocate cx18_dvb structure" " for %s\n", s->name); return -ENOMEM; } } else { s->buffers = 0; } } if (num_offset == -1) return 0; s->video_dev = video_device_alloc(); if (s->video_dev == NULL) { CX18_ERR("Couldn't allocate v4l2 video_device for %s\n", s->name); return -ENOMEM; } snprintf(s->video_dev->name, sizeof(s->video_dev->name), "%s %s", cx->v4l2_dev.name, s->name); s->video_dev->num = num; s->video_dev->v4l2_dev = &cx->v4l2_dev; s->video_dev->fops = &cx18_v4l2_enc_fops; s->video_dev->release = video_device_release; s->video_dev->tvnorms = V4L2_STD_ALL; set_bit(V4L2_FL_USE_FH_PRIO, &s->video_dev->flags); cx18_set_funcs(s->video_dev); return 0; }
static __init int vpif_probe(struct platform_device *pdev) { struct vpif_subdev_info *subdevdata; struct vpif_capture_config *config; int i, j, k, m, q, err; struct i2c_adapter *i2c_adap; struct channel_obj *ch; struct common_obj *common; struct video_device *vfd; struct resource *res; int subdev_count; vpif_dev = &pdev->dev; err = initialize_vpif(); if (err) { v4l2_err(vpif_dev->driver, "Error initializing vpif\n"); return err; } k = 0; while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, k))) { for (i = res->start; i <= res->end; i++) { if (request_irq(i, vpif_channel_isr, IRQF_DISABLED, "DM646x_Capture", (void *)(&vpif_obj.dev[k]->channel_id))) { err = -EBUSY; i--; goto vpif_int_err; } } k++; } for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) { /* Get the pointer to the channel object */ ch = vpif_obj.dev[i]; /* Allocate memory for video device */ vfd = video_device_alloc(); if (NULL == vfd) { for (j = 0; j < i; j++) { ch = vpif_obj.dev[j]; video_device_release(ch->video_dev); } err = -ENOMEM; goto vpif_dev_alloc_err; } /* Initialize field of video device */ *vfd = vpif_video_template; vfd->v4l2_dev = &vpif_obj.v4l2_dev; vfd->release = video_device_release; snprintf(vfd->name, sizeof(vfd->name), "DM646x_VPIFCapture_DRIVER_V%d.%d.%d", (VPIF_CAPTURE_VERSION_CODE >> 16) & 0xff, (VPIF_CAPTURE_VERSION_CODE >> 8) & 0xff, (VPIF_CAPTURE_VERSION_CODE) & 0xff); /* Set video_dev to the video device */ ch->video_dev = vfd; } for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) { ch = vpif_obj.dev[j]; ch->channel_id = j; common = &(ch->common[VPIF_VIDEO_INDEX]); spin_lock_init(&common->irqlock); mutex_init(&common->lock); /* Initialize prio member of channel object */ v4l2_prio_init(&ch->prio); err = video_register_device(ch->video_dev, VFL_TYPE_GRABBER, (j ? 1 : 0)); if (err) goto probe_out; video_set_drvdata(ch->video_dev, ch); } i2c_adap = i2c_get_adapter(1); config = pdev->dev.platform_data; subdev_count = config->subdev_count; vpif_obj.sd = kmalloc(sizeof(struct v4l2_subdev *) * subdev_count, GFP_KERNEL); if (vpif_obj.sd == NULL) { vpif_err("unable to allocate memory for subdevice pointers\n"); err = -ENOMEM; goto probe_out; } err = v4l2_device_register(vpif_dev, &vpif_obj.v4l2_dev); if (err) { v4l2_err(vpif_dev->driver, "Error registering v4l2 device\n"); goto probe_subdev_out; } for (i = 0; i < subdev_count; i++) { subdevdata = &config->subdev_info[i]; vpif_obj.sd[i] = v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev, i2c_adap, subdevdata->name, &subdevdata->board_info, NULL); if (!vpif_obj.sd[i]) { vpif_err("Error registering v4l2 subdevice\n"); goto probe_subdev_out; } v4l2_info(&vpif_obj.v4l2_dev, "registered sub device %s\n", subdevdata->name); if (vpif_obj.sd[i]) vpif_obj.sd[i]->grp_id = 1 << i; } v4l2_info(&vpif_obj.v4l2_dev, "DM646x VPIF Capture driver" " initialized\n"); return 0; probe_subdev_out: /* free sub devices memory */ kfree(vpif_obj.sd); j = VPIF_CAPTURE_MAX_DEVICES; probe_out: v4l2_device_unregister(&vpif_obj.v4l2_dev); for (k = 0; k < j; k++) { /* Get the pointer to the channel object */ ch = vpif_obj.dev[k]; /* Unregister video device */ video_unregister_device(ch->video_dev); } vpif_dev_alloc_err: k = VPIF_CAPTURE_MAX_DEVICES-1; res = platform_get_resource(pdev, IORESOURCE_IRQ, k); i = res->end; vpif_int_err: for (q = k; q >= 0; q--) { for (m = i; m >= (int)res->start; m--) free_irq(m, (void *)(&vpif_obj.dev[q]->channel_id)); res = platform_get_resource(pdev, IORESOURCE_IRQ, q-1); if (res) i = res->end; } return err; }
int fthd_v4l2_register(struct fthd_private *dev_priv) { struct v4l2_device *v4l2_dev = &dev_priv->v4l2_dev; struct video_device *vdev; struct vb2_queue *q; int ret; ret = v4l2_device_register(&dev_priv->pdev->dev, v4l2_dev); if (ret) { pr_err("v4l2_device_register: %d\n", ret); return ret; } vdev = video_device_alloc(); if (!vdev) { ret = -ENOMEM; goto fail; } dev_priv->videodev = vdev; q = &dev_priv->vb2_queue; q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ; q->drv_priv = dev_priv; q->ops = &vb2_queue_ops; q->mem_ops = &vb2_dma_sg_memops; q->buf_struct_size = 0;//sizeof(struct vpif_cap_buffer); q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; q->min_buffers_needed = 1; q->lock = &dev_priv->vb2_queue_lock; ret = vb2_queue_init(q); if (ret) goto fail; v4l2_ctrl_handler_init(&dev_priv->v4l2_ctrl_handler, 4); v4l2_ctrl_new_std(&dev_priv->v4l2_ctrl_handler, &fthd_ctrl_ops, V4L2_CID_BRIGHTNESS, 0, 0xff, 1, 0x80); v4l2_ctrl_new_std(&dev_priv->v4l2_ctrl_handler, &fthd_ctrl_ops, V4L2_CID_CONTRAST, 0, 0xff, 1, 0x80); v4l2_ctrl_new_std(&dev_priv->v4l2_ctrl_handler, &fthd_ctrl_ops, V4L2_CID_SATURATION, 0, 0xff, 1, 0x80); v4l2_ctrl_new_std(&dev_priv->v4l2_ctrl_handler, &fthd_ctrl_ops, V4L2_CID_HUE, 0, 0xff, 1, 0x80); v4l2_ctrl_new_std(&dev_priv->v4l2_ctrl_handler, &fthd_ctrl_ops, V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1); if (dev_priv->v4l2_ctrl_handler.error) { pr_err("failed to setup control handlers\n"); v4l2_ctrl_handler_free(&dev_priv->v4l2_ctrl_handler); goto fail; } dev_priv->alloc_ctx = vb2_dma_sg_init_ctx(&dev_priv->pdev->dev); vdev->v4l2_dev = v4l2_dev; strcpy(vdev->name, "Apple Facetime HD"); // XXX: Length? vdev->vfl_dir = VFL_DIR_RX; vdev->fops = &fthd_vdev_fops; vdev->ioctl_ops = &fthd_ioctl_ops; vdev->queue = q; vdev->release = video_device_release; vdev->ctrl_handler = &dev_priv->v4l2_ctrl_handler; video_set_drvdata(vdev, dev_priv); ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); if (ret) { video_device_release(vdev); goto fail_vdev; } dev_priv->fmt.fmt.sizeimage = 1280 * 720 * 2; dev_priv->fmt.fmt.pixelformat = V4L2_PIX_FMT_YUYV; dev_priv->fmt.fmt.width = 1280; dev_priv->fmt.fmt.height = 720; dev_priv->fmt.planes = 1; fthd_v4l2_adjust_format(dev_priv, &dev_priv->fmt.fmt); return 0; fail_vdev: v4l2_ctrl_handler_free(&dev_priv->v4l2_ctrl_handler); fail: v4l2_device_unregister(&dev_priv->v4l2_dev); return ret; }
int camera_init_v4l2(struct device *dev, unsigned int *session) { struct msm_video_device *pvdev; struct v4l2_device *v4l2_dev; int rc = 0; pvdev = kzalloc(sizeof(struct msm_video_device), GFP_KERNEL); if (WARN_ON(!pvdev)) { rc = -ENOMEM; goto init_end; } pvdev->vdev = video_device_alloc(); if (WARN_ON(!pvdev->vdev)) { rc = -ENOMEM; goto video_fail; } v4l2_dev = kzalloc(sizeof(struct v4l2_device), GFP_KERNEL); if (WARN_ON(!v4l2_dev)) { rc = -ENOMEM; goto v4l2_fail; } #if defined(CONFIG_MEDIA_CONTROLLER) v4l2_dev->mdev = kzalloc(sizeof(struct media_device), GFP_KERNEL); if (!v4l2_dev->mdev) { rc = -ENOMEM; goto mdev_fail; } strlcpy(v4l2_dev->mdev->model, MSM_CAMERA_NAME, sizeof(v4l2_dev->mdev->model)); v4l2_dev->mdev->dev = dev; rc = media_device_register(v4l2_dev->mdev); if (WARN_ON(rc < 0)) goto media_fail; rc = media_entity_init(&pvdev->vdev->entity, 0, NULL, 0); if (WARN_ON(rc < 0)) goto entity_fail; pvdev->vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L; pvdev->vdev->entity.group_id = QCAMERA_VNODE_GROUP_ID; #endif v4l2_dev->notify = NULL; pvdev->vdev->v4l2_dev = v4l2_dev; rc = v4l2_device_register(dev, pvdev->vdev->v4l2_dev); if (WARN_ON(rc < 0)) goto register_fail; strlcpy(pvdev->vdev->name, "msm-sensor", sizeof(pvdev->vdev->name)); pvdev->vdev->release = video_device_release; pvdev->vdev->fops = &camera_v4l2_fops; pvdev->vdev->ioctl_ops = &camera_v4l2_ioctl_ops; pvdev->vdev->minor = -1; pvdev->vdev->vfl_type = VFL_TYPE_GRABBER; rc = video_register_device(pvdev->vdev, VFL_TYPE_GRABBER, -1); if (WARN_ON(rc < 0)) goto video_register_fail; #if defined(CONFIG_MEDIA_CONTROLLER) /* FIXME: How to get rid of this messy? */ pvdev->vdev->entity.name = video_device_node_name(pvdev->vdev); #endif *session = pvdev->vdev->num; atomic_set(&pvdev->opened, 0); atomic_set(&pvdev->stream_cnt, 0); video_set_drvdata(pvdev->vdev, pvdev); device_init_wakeup(&pvdev->vdev->dev, 1); if(!cam_wakelock_init) { cam_wakelock_init = 1; wake_lock_init(&cam_wakelock, WAKE_LOCK_SUSPEND, "cam_wakelock"); } goto init_end; video_register_fail: v4l2_device_unregister(pvdev->vdev->v4l2_dev); register_fail: #if defined(CONFIG_MEDIA_CONTROLLER) media_entity_cleanup(&pvdev->vdev->entity); entity_fail: media_device_unregister(v4l2_dev->mdev); media_fail: kzfree(v4l2_dev->mdev); mdev_fail: #endif kzfree(v4l2_dev); v4l2_fail: video_device_release(pvdev->vdev); video_fail: kzfree(pvdev); init_end: return rc; }
static int g2d_probe(struct platform_device *pdev) { struct g2d_dev *dev; struct video_device *vfd; struct resource *res; const struct of_device_id *of_id; int ret = 0; dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); if (!dev) return -ENOMEM; spin_lock_init(&dev->ctrl_lock); mutex_init(&dev->mutex); atomic_set(&dev->num_inst, 0); init_waitqueue_head(&dev->irq_queue); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); dev->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(dev->regs)) return PTR_ERR(dev->regs); dev->clk = clk_get(&pdev->dev, "sclk_fimg2d"); if (IS_ERR(dev->clk)) { dev_err(&pdev->dev, "failed to get g2d clock\n"); return -ENXIO; } ret = clk_prepare(dev->clk); if (ret) { dev_err(&pdev->dev, "failed to prepare g2d clock\n"); goto put_clk; } dev->gate = clk_get(&pdev->dev, "fimg2d"); if (IS_ERR(dev->gate)) { dev_err(&pdev->dev, "failed to get g2d clock gate\n"); ret = -ENXIO; goto unprep_clk; } ret = clk_prepare(dev->gate); if (ret) { dev_err(&pdev->dev, "failed to prepare g2d clock gate\n"); goto put_clk_gate; } res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { dev_err(&pdev->dev, "failed to find IRQ\n"); ret = -ENXIO; goto unprep_clk_gate; } dev->irq = res->start; ret = devm_request_irq(&pdev->dev, dev->irq, g2d_isr, 0, pdev->name, dev); if (ret) { dev_err(&pdev->dev, "failed to install IRQ\n"); goto put_clk_gate; } dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev); if (IS_ERR(dev->alloc_ctx)) { ret = PTR_ERR(dev->alloc_ctx); goto unprep_clk_gate; } ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); if (ret) goto alloc_ctx_cleanup; vfd = video_device_alloc(); if (!vfd) { v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n"); ret = -ENOMEM; goto unreg_v4l2_dev; } *vfd = g2d_videodev; vfd->lock = &dev->mutex; vfd->v4l2_dev = &dev->v4l2_dev; ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); if (ret) { v4l2_err(&dev->v4l2_dev, "Failed to register video device\n"); goto rel_vdev; } video_set_drvdata(vfd, dev); snprintf(vfd->name, sizeof(vfd->name), "%s", g2d_videodev.name); dev->vfd = vfd; v4l2_info(&dev->v4l2_dev, "device registered as /dev/video%d\n", vfd->num); platform_set_drvdata(pdev, dev); dev->m2m_dev = v4l2_m2m_init(&g2d_m2m_ops); if (IS_ERR(dev->m2m_dev)) { v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n"); ret = PTR_ERR(dev->m2m_dev); goto unreg_video_dev; } def_frame.stride = (def_frame.width * def_frame.fmt->depth) >> 3; if (!pdev->dev.of_node) { dev->variant = g2d_get_drv_data(pdev); } else { of_id = of_match_node(exynos_g2d_match, pdev->dev.of_node); if (!of_id) { ret = -ENODEV; goto unreg_video_dev; } dev->variant = (struct g2d_variant *)of_id->data; } return 0; unreg_video_dev: video_unregister_device(dev->vfd); rel_vdev: video_device_release(vfd); unreg_v4l2_dev: v4l2_device_unregister(&dev->v4l2_dev); alloc_ctx_cleanup: vb2_dma_contig_cleanup_ctx(dev->alloc_ctx); unprep_clk_gate: clk_unprepare(dev->gate); put_clk_gate: clk_put(dev->gate); unprep_clk: clk_unprepare(dev->clk); put_clk: clk_put(dev->clk); return ret; }
static int zr364xx_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(intf); struct zr364xx_camera *cam = NULL; int err; DBG("probing..."); dev_info(&intf->dev, DRIVER_DESC " compatible webcam plugged\n"); dev_info(&intf->dev, "model %04x:%04x detected\n", le16_to_cpu(udev->descriptor.idVendor), le16_to_cpu(udev->descriptor.idProduct)); cam = kzalloc(sizeof(struct zr364xx_camera), GFP_KERNEL); if (cam == NULL) { dev_err(&udev->dev, "cam: out of memory !\n"); return -ENOMEM; } /* save the init method used by this camera */ cam->method = id->driver_info; cam->vdev = video_device_alloc(); if (cam->vdev == NULL) { dev_err(&udev->dev, "cam->vdev: out of memory !\n"); kfree(cam); return -ENOMEM; } memcpy(cam->vdev, &zr364xx_template, sizeof(zr364xx_template)); video_set_drvdata(cam->vdev, cam); if (debug) cam->vdev->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; cam->udev = udev; if ((cam->buffer = kmalloc(BUFFER_SIZE, GFP_KERNEL)) == NULL) { dev_info(&udev->dev, "cam->buffer: out of memory !\n"); video_device_release(cam->vdev); kfree(cam); return -ENODEV; } switch (mode) { case 1: dev_info(&udev->dev, "160x120 mode selected\n"); cam->width = 160; cam->height = 120; break; case 2: dev_info(&udev->dev, "640x480 mode selected\n"); cam->width = 640; cam->height = 480; break; default: dev_info(&udev->dev, "320x240 mode selected\n"); cam->width = 320; cam->height = 240; break; } m0d1[0] = mode; m1[2].value = 0xf000 + mode; m2[1].value = 0xf000 + mode; header2[437] = cam->height / 256; header2[438] = cam->height % 256; header2[439] = cam->width / 256; header2[440] = cam->width % 256; cam->nb = 0; cam->brightness = 64; mutex_init(&cam->lock); err = video_register_device(cam->vdev, VFL_TYPE_GRABBER, -1); if (err) { dev_err(&udev->dev, "video_register_device failed\n"); video_device_release(cam->vdev); kfree(cam->buffer); kfree(cam); return err; } usb_set_intfdata(intf, cam); dev_info(&udev->dev, DRIVER_DESC " controlling video device %d\n", cam->vdev->num); return 0; }
/* * si470x_usb_driver_probe - probe for the device */ static int si470x_usb_driver_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct si470x_device *radio; int retval = 0; /* private data allocation and initialization */ radio = kzalloc(sizeof(struct si470x_device), GFP_KERNEL); if (!radio) { retval = -ENOMEM; goto err_initial; } radio->users = 0; radio->disconnected = 0; radio->usbdev = interface_to_usbdev(intf); radio->intf = intf; mutex_init(&radio->disconnect_lock); mutex_init(&radio->lock); /* video device allocation and initialization */ radio->videodev = video_device_alloc(); if (!radio->videodev) { retval = -ENOMEM; goto err_radio; } memcpy(radio->videodev, &si470x_viddev_template, sizeof(si470x_viddev_template)); video_set_drvdata(radio->videodev, radio); /* show some infos about the specific si470x device */ if (si470x_get_all_registers(radio) < 0) { retval = -EIO; goto err_video; } printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4hx ChipID=0x%4.4hx\n", radio->registers[DEVICEID], radio->registers[CHIPID]); /* get software and hardware versions */ if (si470x_get_scratch_page_versions(radio) < 0) { retval = -EIO; goto err_video; } printk(KERN_INFO DRIVER_NAME ": software version %d, hardware version %d\n", radio->software_version, radio->hardware_version); /* check if device and firmware is current */ if ((radio->registers[CHIPID] & CHIPID_FIRMWARE) < RADIO_SW_VERSION_CURRENT) { printk(KERN_WARNING DRIVER_NAME ": This driver is known to work with " "firmware version %hu,\n", RADIO_SW_VERSION_CURRENT); printk(KERN_WARNING DRIVER_NAME ": but the device has firmware version %hu.\n", radio->registers[CHIPID] & CHIPID_FIRMWARE); printk(KERN_WARNING DRIVER_NAME ": If you have some trouble using this driver,\n"); printk(KERN_WARNING DRIVER_NAME ": please report to V4L ML at " "[email protected]\n"); } /* set initial frequency */ si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */ /* set led to connect state */ si470x_set_led_state(radio, BLINK_GREEN_LED); /* rds buffer allocation */ radio->buf_size = rds_buf * 3; radio->buffer = kmalloc(radio->buf_size, GFP_KERNEL); if (!radio->buffer) { retval = -EIO; goto err_video; } /* rds buffer configuration */ radio->wr_index = 0; radio->rd_index = 0; init_waitqueue_head(&radio->read_queue); /* prepare rds work function */ INIT_DELAYED_WORK(&radio->work, si470x_work); /* register video device */ retval = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr); if (retval) { printk(KERN_WARNING DRIVER_NAME ": Could not register video device\n"); goto err_all; } usb_set_intfdata(intf, radio); return 0; err_all: kfree(radio->buffer); err_video: video_device_release(radio->videodev); err_radio: kfree(radio); err_initial: return retval; }
static int cx18_prep_dev(struct cx18 *cx, int type) { struct cx18_stream *s = &cx->streams[type]; u32 cap = cx->v4l2_cap; int num_offset = cx18_stream_info[type].num_offset; int num = cx->instance + cx18_first_minor + num_offset; /* * These five fields are always initialized. * For analog capture related streams, if video_dev == NULL then the * stream is not in use. * For the TS stream, if dvb == NULL then the stream is not in use. * In those cases no other fields but these four can be used. */ s->video_dev = NULL; s->dvb = NULL; s->cx = cx; s->type = type; s->name = cx18_stream_info[type].name; /* Check whether the radio is supported */ if (type == CX18_ENC_STREAM_TYPE_RAD && !(cap & V4L2_CAP_RADIO)) return 0; /* Check whether VBI is supported */ if (type == CX18_ENC_STREAM_TYPE_VBI && !(cap & (V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE))) return 0; /* User explicitly selected 0 buffers for these streams, so don't create them. */ if (cx18_stream_info[type].dma != PCI_DMA_NONE && cx->stream_buffers[type] == 0) { CX18_INFO("Disabled %s device\n", cx18_stream_info[type].name); return 0; } cx18_stream_init(cx, type); /* Allocate the cx18_dvb struct only for the TS on cards with DTV */ if (type == CX18_ENC_STREAM_TYPE_TS) { if (cx->card->hw_all & CX18_HW_DVB) { s->dvb = kzalloc(sizeof(struct cx18_dvb), GFP_KERNEL); if (s->dvb == NULL) { CX18_ERR("Couldn't allocate cx18_dvb structure" " for %s\n", s->name); return -ENOMEM; } } else { /* Don't need buffers for the TS, if there is no DVB */ s->buffers = 0; } } if (num_offset == -1) return 0; /* allocate and initialize the v4l2 video device structure */ s->video_dev = video_device_alloc(); if (s->video_dev == NULL) { CX18_ERR("Couldn't allocate v4l2 video_device for %s\n", s->name); return -ENOMEM; } snprintf(s->video_dev->name, sizeof(s->video_dev->name), "%s %s", cx->v4l2_dev.name, s->name); s->video_dev->num = num; s->video_dev->v4l2_dev = &cx->v4l2_dev; s->video_dev->fops = &cx18_v4l2_enc_fops; s->video_dev->release = video_device_release; s->video_dev->tvnorms = V4L2_STD_ALL; s->video_dev->lock = &cx->serialize_lock; set_bit(V4L2_FL_USE_FH_PRIO, &s->video_dev->flags); cx18_set_funcs(s->video_dev); return 0; }
static int jpeg_probe(struct platform_device *pdev) { struct jpeg_dev *dev; struct video_device *vfd; struct resource *res; int ret; /* global structure */ dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { dev_err(&pdev->dev, "%s: not enough memory\n", __func__); ret = -ENOMEM; goto err_alloc; } dev->plat_dev = pdev; /* setup jpeg control */ ret = jpeg_setup_controller(dev); if (ret) { jpeg_err("failed to setup controller\n"); goto err_setup; } /* memory region */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { jpeg_err("failed to get jpeg memory region resource\n"); ret = -ENOENT; goto err_res; } res = request_mem_region(res->start, resource_size(res), pdev->name); if (!res) { jpeg_err("failed to request jpeg io memory region\n"); ret = -ENOMEM; goto err_region; } /* ioremap */ dev->reg_base = ioremap(res->start, resource_size(res)); if (!dev->reg_base) { jpeg_err("failed to remap jpeg io region\n"); ret = -ENOENT; goto err_map; } spin_lock_init(&dev->slock); /* irq */ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { jpeg_err("failed to request jpeg irq resource\n"); ret = -ENOENT; goto err_irq; } dev->irq_no = res->start; ret = request_irq(dev->irq_no, (void *)jpeg_irq, IRQF_DISABLED, pdev->name, dev); if (ret != 0) { jpeg_err("failed to jpeg request irq\n"); ret = -ENOENT; goto err_irq; } /* clock */ dev->clk = clk_get(&pdev->dev, "jpeg"); if (IS_ERR(dev->clk)) { jpeg_err("failed to find jpeg clock source\n"); ret = -ENOENT; goto err_clk; } #ifdef CONFIG_PM_RUNTIME pm_runtime_enable(&pdev->dev); #endif /* clock enable */ clk_enable(dev->clk); ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); if (ret) { v4l2_err(&dev->v4l2_dev, "Failed to register v4l2 device\n"); goto err_v4l2; } /* encoder */ vfd = video_device_alloc(); if (!vfd) { v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n"); ret = -ENOMEM; goto err_vd_alloc_enc; } *vfd = jpeg_enc_videodev; vfd->ioctl_ops = get_jpeg_enc_v4l2_ioctl_ops(); ret = video_register_device(vfd, VFL_TYPE_GRABBER, 12); if (ret) { v4l2_err(&dev->v4l2_dev, "%s(): failed to register video device\n", __func__); video_device_release(vfd); goto err_vd_alloc_enc; } v4l2_info(&dev->v4l2_dev, "JPEG driver is registered to /dev/video%d\n", vfd->num); dev->vfd_enc = vfd; dev->m2m_dev_enc = v4l2_m2m_init(&jpeg_m2m_enc_ops); if (IS_ERR(dev->m2m_dev_enc)) { v4l2_err(&dev->v4l2_dev, "failed to initialize v4l2-m2m device\n"); ret = PTR_ERR(dev->m2m_dev_enc); goto err_m2m_init_enc; } video_set_drvdata(vfd, dev); /* decoder */ vfd = video_device_alloc(); if (!vfd) { v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n"); ret = -ENOMEM; goto err_vd_alloc_dec; } *vfd = jpeg_dec_videodev; vfd->ioctl_ops = get_jpeg_dec_v4l2_ioctl_ops(); ret = video_register_device(vfd, VFL_TYPE_GRABBER, 11); if (ret) { v4l2_err(&dev->v4l2_dev, "%s(): failed to register video device\n", __func__); video_device_release(vfd); goto err_vd_alloc_dec; } v4l2_info(&dev->v4l2_dev, "JPEG driver is registered to /dev/video%d\n", vfd->num); dev->vfd_dec = vfd; dev->m2m_dev_dec = v4l2_m2m_init(&jpeg_m2m_dec_ops); if (IS_ERR(dev->m2m_dev_dec)) { v4l2_err(&dev->v4l2_dev, "failed to initialize v4l2-m2m device\n"); ret = PTR_ERR(dev->m2m_dev_dec); goto err_m2m_init_dec; } video_set_drvdata(vfd, dev); platform_set_drvdata(pdev, dev); #ifdef CONFIG_VIDEOBUF2_CMA_PHYS dev->vb2 = &jpeg_vb2_cma; #elif defined(CONFIG_VIDEOBUF2_ION) dev->vb2 = &jpeg_vb2_ion; #endif dev->alloc_ctx = dev->vb2->init(dev); if (IS_ERR(dev->alloc_ctx)) { ret = PTR_ERR(dev->alloc_ctx); goto err_video_reg; } #ifdef CONFIG_BUSFREQ_OPP /* To lock bus frequency in OPP mode */ dev->bus_dev = dev_get("exynos-busfreq"); #endif dev->watchdog_workqueue = create_singlethread_workqueue(JPEG_NAME); INIT_WORK(&dev->watchdog_work, jpeg_watchdog_worker); atomic_set(&dev->watchdog_cnt, 0); init_timer(&dev->watchdog_timer); dev->watchdog_timer.data = (unsigned long)dev; dev->watchdog_timer.function = jpeg_watchdog; /* clock disable */ clk_disable(dev->clk); return 0; err_video_reg: v4l2_m2m_release(dev->m2m_dev_dec); err_m2m_init_dec: video_unregister_device(dev->vfd_dec); video_device_release(dev->vfd_dec); err_vd_alloc_dec: v4l2_m2m_release(dev->m2m_dev_enc); err_m2m_init_enc: video_unregister_device(dev->vfd_enc); video_device_release(dev->vfd_enc); err_vd_alloc_enc: v4l2_device_unregister(&dev->v4l2_dev); err_v4l2: clk_disable(dev->clk); clk_put(dev->clk); err_clk: free_irq(dev->irq_no, NULL); err_irq: iounmap(dev->reg_base); err_map: err_region: kfree(res); err_res: mutex_destroy(&dev->lock); err_setup: kfree(dev); err_alloc: return ret; }