static int rockchip_vpu_video_device_register(struct rockchip_vpu_dev *vpu) { const struct of_device_id *match; struct video_device *vfd; int function, ret; match = of_match_node(of_rockchip_vpu_match, vpu->dev->of_node); vfd = video_device_alloc(); if (!vfd) { v4l2_err(&vpu->v4l2_dev, "Failed to allocate video device\n"); return -ENOMEM; } vfd->fops = &rockchip_vpu_fops; vfd->release = video_device_release; vfd->lock = &vpu->vpu_mutex; vfd->v4l2_dev = &vpu->v4l2_dev; vfd->vfl_dir = VFL_DIR_M2M; vfd->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE; vfd->ioctl_ops = &rockchip_vpu_enc_ioctl_ops; snprintf(vfd->name, sizeof(vfd->name), "%s-enc", match->compatible); vpu->vfd_enc = vfd; video_set_drvdata(vfd, vpu); ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0); if (ret) { v4l2_err(&vpu->v4l2_dev, "Failed to register video device\n"); goto err_free_dev; } v4l2_info(&vpu->v4l2_dev, "registered as /dev/video%d\n", vfd->num); function = MEDIA_ENT_F_PROC_VIDEO_ENCODER; ret = v4l2_m2m_register_media_controller(vpu->m2m_dev, vfd, function); if (ret) { v4l2_err(&vpu->v4l2_dev, "Failed to init mem2mem media controller\n"); goto err_unreg_video; } return 0; err_unreg_video: video_unregister_device(vfd); err_free_dev: video_device_release(vfd); return ret; }
int isp_video_init(struct isp_video *video, const char *name) { const char *direction; int ret; switch (video->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: direction = "output"; video->pad.type = MEDIA_PAD_TYPE_INPUT; break; case V4L2_BUF_TYPE_VIDEO_OUTPUT: direction = "input"; video->pad.type = MEDIA_PAD_TYPE_OUTPUT; break; default: return -EINVAL; } ret = media_entity_init(&video->video.entity, 1, &video->pad, 0); if (ret < 0) return ret; mutex_init(&video->mutex); atomic_set(&video->active, 0); atomic_set(&video->users, 0); spin_lock_init(&video->__pipe.lock); mutex_init(&video->stream_lock); /* Initialize the video device. */ if (video->ops == NULL) video->ops = &isp_video_dummy_ops; video->video.fops = &isp_video_fops; snprintf(video->video.name, sizeof(video->video.name), "OMAP3 ISP %s %s", name, direction); video->video.vfl_type = VFL_TYPE_GRABBER; video->video.release = video_device_release_empty; video->video.ioctl_ops = &isp_video_ioctl_ops; video_set_drvdata(&video->video, video); return 0; }
static int uvc_register_video(struct uvc_device *uvc) { struct usb_composite_dev *cdev = uvc->func.config->cdev; /* TODO reference counting. */ uvc->vdev.v4l2_dev = &uvc->v4l2_dev; uvc->vdev.fops = &uvc_v4l2_fops; uvc->vdev.ioctl_ops = &uvc_v4l2_ioctl_ops; uvc->vdev.release = video_device_release_empty; uvc->vdev.vfl_dir = VFL_DIR_TX; uvc->vdev.lock = &uvc->video.mutex; strlcpy(uvc->vdev.name, cdev->gadget->name, sizeof(uvc->vdev.name)); video_set_drvdata(&uvc->vdev, uvc); return video_register_device(&uvc->vdev, VFL_TYPE_GRABBER, -1); }
int fimc_register_m2m_device(struct fimc_dev *fimc, struct v4l2_device *v4l2_dev) { struct video_device *vfd = &fimc->m2m.vfd; int ret; fimc->v4l2_dev = v4l2_dev; memset(vfd, 0, sizeof(*vfd)); vfd->fops = &fimc_m2m_fops; vfd->ioctl_ops = &fimc_m2m_ioctl_ops; vfd->v4l2_dev = v4l2_dev; vfd->minor = -1; vfd->release = video_device_release_empty; vfd->lock = &fimc->lock; vfd->vfl_dir = VFL_DIR_M2M; snprintf(vfd->name, sizeof(vfd->name), "fimc.%d.m2m", fimc->id); video_set_drvdata(vfd, fimc); fimc->m2m.m2m_dev = v4l2_m2m_init(&m2m_ops); if (IS_ERR(fimc->m2m.m2m_dev)) { v4l2_err(v4l2_dev, "failed to initialize v4l2-m2m device\n"); return PTR_ERR(fimc->m2m.m2m_dev); } ret = media_entity_init(&vfd->entity, 0, NULL, 0); if (ret) goto err_me; ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); if (ret) goto err_vd; v4l2_info(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_me: v4l2_m2m_release(fimc->m2m.m2m_dev); return ret; }
int stk1160_video_register(struct stk1160 *dev) { int rc; /* Initialize video_device with a template structure */ dev->vdev = v4l_template; dev->vdev.debug = vidioc_debug; dev->vdev.queue = &dev->vb_vidq; /* * Provide mutexes for v4l2 core and for videobuf2 queue. * It will be used to protect *only* v4l2 ioctls. */ dev->vdev.lock = &dev->v4l_lock; dev->vdev.queue->lock = &dev->vb_queue_lock; /* This will be used to set video_device parent */ dev->vdev.v4l2_dev = &dev->v4l2_dev; set_bit(V4L2_FL_USE_FH_PRIO, &dev->vdev.flags); /* NTSC is default */ dev->norm = V4L2_STD_NTSC_M; dev->width = 720; dev->height = 480; /* set default format */ dev->fmt = &format[0]; stk1160_set_std(dev); v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm); video_set_drvdata(&dev->vdev, dev); rc = video_register_device(&dev->vdev, VFL_TYPE_GRABBER, -1); if (rc < 0) { stk1160_err("video_register_device failed (%d)\n", rc); return rc; } v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n", video_device_node_name(&dev->vdev)); return 0; }
static int register_v4l2_device(void) { int ret; struct fmdev *fmdev = NULL; struct video_device *radio = video_device_alloc(); if (!radio) { TROUT_PRINT("Could not allocate video_device"); return -EINVAL; } strlcpy(radio->name, DRIVER_NAME, sizeof(radio->name)); radio->fops = &trout_fops; radio->release = video_device_release; radio->ioctl_ops = &trout_ioctl_ops; if (video_register_device(radio, VFL_TYPE_RADIO, -1)) { TROUT_PRINT("Could not register video_device"); video_device_release(radio); return -EINVAL; } s_radio = radio; fmdev = (struct fmdev *)kzalloc(sizeof(struct fmdev), GFP_KERNEL); if (!fmdev) { TROUT_PRINT("Could not allocate fmdev"); return -EINVAL; } video_set_drvdata(radio, fmdev); radio->ctrl_handler = &fmdev->ctrl_handler; ret = v4l2_ctrl_handler_init(&fmdev->ctrl_handler, 1); if (ret < 0) { TROUT_PRINT("Failed to int v4l2_ctrl_handler"); v4l2_ctrl_handler_free(&fmdev->ctrl_handler); return -EINVAL; } v4l2_ctrl_new_std(&fmdev->ctrl_handler, &trout_ctrl_ops, V4L2_CID_PRIVATE_FM_AUDIO, 0, 1, 1, 0); TROUT_PRINT("Registered Trout FM Receiver."); return 0; }
int fimc_is_video_probe(struct fimc_is_video *video, char *video_name, u32 video_number, u32 vfl_dir, struct fimc_is_mem *mem, struct v4l2_device *v4l2_dev, struct mutex *lock, const struct v4l2_file_operations *fops, const struct v4l2_ioctl_ops *ioctl_ops) { int ret = 0; u32 video_id; vref_init(video); mutex_init(&video->lock); snprintf(video->vd.name, sizeof(video->vd.name), "%s", video_name); video->id = video_number; video->vb2 = mem->vb2; video->alloc_ctx = mem->alloc_ctx; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,0)) video->vd.vfl_dir = vfl_dir; #endif video->vd.v4l2_dev = v4l2_dev; video->vd.fops = fops; video->vd.ioctl_ops = ioctl_ops; video->vd.minor = -1; video->vd.release = video_device_release; video->vd.lock = lock; video_set_drvdata(&video->vd, video); video_id = EXYNOS_VIDEONODE_FIMC_IS + video_number; ret = video_register_device(&video->vd, VFL_TYPE_GRABBER, (EXYNOS_VIDEONODE_FIMC_IS + video_number)); if (ret) { err("Failed to register video device"); goto p_err; } p_err: info("[VID] %s(%d) is created\n", video_name, video_id); return ret; }
int gsc_register_m2m_device(struct gsc_dev *gsc) { struct platform_device *pdev; int ret; if (!gsc) return -ENODEV; pdev = gsc->pdev; gsc->vdev.fops = &gsc_m2m_fops; gsc->vdev.ioctl_ops = &gsc_m2m_ioctl_ops; gsc->vdev.release = video_device_release_empty; gsc->vdev.lock = &gsc->lock; gsc->vdev.vfl_dir = VFL_DIR_M2M; gsc->vdev.v4l2_dev = &gsc->v4l2_dev; snprintf(gsc->vdev.name, sizeof(gsc->vdev.name), "%s.%d:m2m", GSC_MODULE_NAME, gsc->id); video_set_drvdata(&gsc->vdev, gsc); gsc->m2m.vfd = &gsc->vdev; gsc->m2m.m2m_dev = v4l2_m2m_init(&gsc_m2m_ops); if (IS_ERR(gsc->m2m.m2m_dev)) { dev_err(&pdev->dev, "failed to initialize v4l2-m2m device\n"); return PTR_ERR(gsc->m2m.m2m_dev); } ret = video_register_device(&gsc->vdev, VFL_TYPE_GRABBER, -1); if (ret) { dev_err(&pdev->dev, "%s(): failed to register video device\n", __func__); goto err_m2m_release; } pr_debug("gsc m2m driver registered as /dev/video%d", gsc->vdev.num); return 0; err_m2m_release: v4l2_m2m_release(gsc->m2m.m2m_dev); return ret; }
static int uvc_register_video(struct uvc_device *uvc) { struct usb_composite_dev *cdev = uvc->func.config->cdev; struct video_device *video; /* TODO reference counting. */ video = video_device_alloc(); if (video == NULL) return -ENOMEM; video->v4l2_dev = &uvc->v4l2_dev; video->fops = &uvc_v4l2_fops; video->release = video_device_release; strlcpy(video->name, cdev->gadget->name, sizeof(video->name)); uvc->vdev = video; video_set_drvdata(video, uvc); return video_register_device(video, VFL_TYPE_GRABBER, -1); }
static int empress_init(struct saa7134_dev *dev) { int err; dprintk("%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->parent = &dev->pci->dev; dev->empress_dev->release = video_device_release; snprintf(dev->empress_dev->name, sizeof(dev->empress_dev->name), "%s empress (%s)", dev->name, saa7134_boards[dev->board].name); INIT_WORK(&dev->empress_workqueue, empress_signal_update); video_set_drvdata(dev->empress_dev, dev); err = video_register_device(dev->empress_dev,VFL_TYPE_GRABBER, empress_nr[dev->nr]); if (err < 0) { printk(KERN_INFO "%s: can't register video device\n", dev->name); video_device_release(dev->empress_dev); dev->empress_dev = NULL; return err; } printk(KERN_INFO "%s: registered device %s [mpeg]\n", dev->name, video_device_node_name(dev->empress_dev)); videobuf_queue_sg_init(&dev->empress_tsq, &saa7134_ts_qops, &dev->pci->dev, &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_ALTERNATE, sizeof(struct saa7134_buf), dev); empress_signal_update(&dev->empress_workqueue); return 0; }
/* * initialize all the tea575x chips */ void snd_tea575x_init(struct snd_tea575x *tea) { unsigned int val; val = tea->ops->read(tea); if (val == 0x1ffffff || val == 0) { snd_printk(KERN_ERR "Cannot find TEA575x chip\n"); return; } memset(&tea->vd, 0, sizeof(tea->vd)); tea->vd.owner = tea->card->module; strcpy(tea->vd.name, tea->tea5759 ? "TEA5759 radio" : "TEA5757 radio"); tea->vd.type = VID_TYPE_TUNER; tea->vd.release = snd_tea575x_release; video_set_drvdata(&tea->vd, tea); tea->vd.fops = &tea->fops; tea->fops.owner = tea->card->module; tea->fops.open = video_exclusive_open; tea->fops.release = video_exclusive_release; tea->fops.ioctl = snd_tea575x_ioctl; if (video_register_device(&tea->vd, VFL_TYPE_RADIO, tea->dev_nr - 1) < 0) { snd_printk(KERN_ERR "unable to register tea575x tuner\n"); return; } tea->vd_registered = 1; tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_10_40; tea->freq = 90500 * 16; /* 90.5Mhz default */ snd_tea575x_set_freq(tea); /* mute on init */ if (tea->ops->mute) tea->ops->mute(tea, 1); }
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; }
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; }
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; }
/* Initialize camera device. Setup all internal flags, set a default video mode, setup ccd-chip, register v4l device etc.. Also used for 'probing' of hardware. -1 on error */ static int w9966_init(struct w9966 *cam, struct parport *port) { struct v4l2_device *v4l2_dev = &cam->v4l2_dev; if (cam->dev_state != 0) return -1; strlcpy(v4l2_dev->name, "w9966", sizeof(v4l2_dev->name)); if (v4l2_device_register(NULL, v4l2_dev) < 0) { v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); return -1; } cam->pport = port; cam->brightness = 128; cam->contrast = 64; cam->color = 64; cam->hue = 0; /* Select requested transfer mode */ switch (parmode) { default: /* Auto-detect (priority: hw-ecp, hw-epp, sw-ecp) */ case 0: if (port->modes & PARPORT_MODE_ECP) cam->ppmode = IEEE1284_MODE_ECP; else if (port->modes & PARPORT_MODE_EPP) cam->ppmode = IEEE1284_MODE_EPP; else cam->ppmode = IEEE1284_MODE_ECP; break; case 1: /* hw- or sw-ecp */ cam->ppmode = IEEE1284_MODE_ECP; break; case 2: /* hw- or sw-epp */ cam->ppmode = IEEE1284_MODE_EPP; break; } /* Tell the parport driver that we exists */ cam->pdev = parport_register_device(port, "w9966", NULL, NULL, NULL, 0, NULL); if (cam->pdev == NULL) { DPRINTF("parport_register_device() failed\n"); return -1; } w9966_set_state(cam, W9966_STATE_PDEV, W9966_STATE_PDEV); w9966_pdev_claim(cam); /* Setup a default capture mode */ if (w9966_setup(cam, 0, 0, 1023, 1023, 200, 160) != 0) { DPRINTF("w9966_setup() failed.\n"); return -1; } w9966_pdev_release(cam); /* Fill in the video_device struct and register us to v4l */ strlcpy(cam->vdev.name, W9966_DRIVERNAME, sizeof(cam->vdev.name)); cam->vdev.v4l2_dev = v4l2_dev; cam->vdev.fops = &w9966_fops; cam->vdev.ioctl_ops = &w9966_ioctl_ops; cam->vdev.release = video_device_release_empty; video_set_drvdata(&cam->vdev, cam); mutex_init(&cam->lock); if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) return -1; w9966_set_state(cam, W9966_STATE_VDEV, W9966_STATE_VDEV); /* All ok */ v4l2_info(v4l2_dev, "Found and initialized a webcam on %s.\n", cam->pport->name); return 0; }
int hwcam_dev_create( struct device* dev, int* dev_num) { int rc = 0; struct v4l2_device* v4l2 = NULL; struct video_device* vdev = NULL; struct media_device* mdev = NULL; hwcam_dev_t* cam = NULL; cam = kzalloc(sizeof(hwcam_dev_t), GFP_KERNEL); if (WARN_ON(!cam)) { rc = -ENOMEM; goto init_end; } v4l2 = &cam->v4l2; vdev = video_device_alloc(); if (!vdev) { rc = -ENOMEM; goto video_alloc_fail; } mdev = kzalloc(sizeof(struct media_device), GFP_KERNEL); if (!mdev) { rc = -ENOMEM; goto media_alloc_fail; } strlcpy(mdev->model, HWCAM_MODEL_USER, sizeof(mdev->model)); mdev->dev = dev; rc = media_device_register(mdev); if (rc < 0) { goto media_register_fail; } rc = media_entity_init(&vdev->entity, 0, NULL, 0); if (rc < 0) { goto entity_init_fail; } v4l2->mdev = mdev; v4l2->notify = NULL; rc = v4l2_device_register(dev, v4l2); if (rc < 0) { goto v4l2_register_fail; } strlcpy(vdev->name, "hwcam-userdev", sizeof(vdev->name)); vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L; vdev->entity.group_id = HWCAM_DEVICE_GROUP_ID; vdev->v4l2_dev = v4l2; vdev->release = video_device_release; vdev->fops = &s_fops_hwcam_dev; vdev->ioctl_ops = &s_iops_hwcam_dev; vdev->minor = -1; vdev->vfl_type = VFL_TYPE_GRABBER; rc = video_register_device(vdev, VFL_TYPE_GRABBER, -1); if (rc < 0) { goto video_register_fail; } cam_debug("video dev name %s %s",vdev->dev.kobj.name,vdev->name); mutex_init(&cam->lock); vdev->lock = &cam->lock; vdev->entity.name = video_device_node_name(vdev); video_set_drvdata(vdev, cam); cam->vdev = vdev; cam->mdev = mdev; cam->intf.vtbl = &s_vtbl_hwcam_dev; *dev_num = vdev->num; goto init_end; video_register_fail: v4l2_device_unregister(v4l2); v4l2_register_fail: media_entity_cleanup(&vdev->entity); entity_init_fail: media_device_unregister(mdev); media_register_fail: kzfree(mdev); media_alloc_fail: video_device_release(vdev); video_alloc_fail: kzfree(cam); init_end: return rc; }
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; }
/*! * 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 __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 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; }
/* * 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; }
int fimc_isp_video_device_register(struct fimc_isp *isp, struct v4l2_device *v4l2_dev, enum v4l2_buf_type type) { struct vb2_queue *q = &isp->video_capture.vb_queue; struct fimc_is_video *iv; struct video_device *vdev; int ret; if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) iv = &isp->video_capture; else return -ENOSYS; mutex_init(&isp->video_lock); INIT_LIST_HEAD(&iv->pending_buf_q); INIT_LIST_HEAD(&iv->active_buf_q); iv->format = fimc_isp_find_format(NULL, NULL, 0); iv->pixfmt.width = IS_DEFAULT_WIDTH; iv->pixfmt.height = IS_DEFAULT_HEIGHT; iv->pixfmt.pixelformat = iv->format->fourcc; iv->pixfmt.colorspace = V4L2_COLORSPACE_SRGB; iv->reqbufs_count = 0; memset(q, 0, sizeof(*q)); q->type = type; q->io_modes = VB2_MMAP | VB2_USERPTR; q->ops = &isp_video_capture_qops; q->mem_ops = &vb2_dma_contig_memops; q->buf_struct_size = sizeof(struct isp_video_buf); q->drv_priv = isp; q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; q->lock = &isp->video_lock; ret = vb2_queue_init(q); if (ret < 0) return ret; vdev = &iv->ve.vdev; memset(vdev, 0, sizeof(*vdev)); snprintf(vdev->name, sizeof(vdev->name), "fimc-is-isp.%s", type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ? "capture" : "output"); vdev->queue = q; vdev->fops = &isp_video_fops; vdev->ioctl_ops = &isp_video_ioctl_ops; vdev->v4l2_dev = v4l2_dev; vdev->minor = -1; vdev->release = video_device_release_empty; vdev->lock = &isp->video_lock; iv->pad.flags = MEDIA_PAD_FL_SINK; ret = media_entity_pads_init(&vdev->entity, 1, &iv->pad); if (ret < 0) return ret; video_set_drvdata(vdev, isp); ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1); if (ret < 0) { media_entity_cleanup(&vdev->entity); return ret; } v4l2_info(v4l2_dev, "Registered %s as /dev/%s\n", vdev->name, video_device_node_name(vdev)); return 0; }
/* * 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 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 fimc_is_probe(struct platform_device *pdev) { struct exynos4_platform_fimc_is *pdata; struct resource *mem_res; struct resource *regs_res; struct fimc_is_dev *dev; #if defined(CONFIG_VIDEO_EXYNOS_FIMC_IS_BAYER) struct v4l2_device *v4l2_dev; struct vb2_queue *isp_q; #endif int ret = -ENODEV; dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { dev_err(&pdev->dev, "Not enough memory for FIMC-IS device.\n"); return -ENOMEM; } mutex_init(&dev->lock); spin_lock_init(&dev->slock); init_waitqueue_head(&dev->irq_queue1); dev->pdev = pdev; if (!dev->pdev) { dev_err(&pdev->dev, "No platform data specified\n"); goto p_err_info; } pdata = pdev->dev.platform_data; if (!pdata) { dev_err(&pdev->dev, "Platform data not set\n"); goto p_err_info; } dev->pdata = pdata; /* * I/O remap */ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem_res) { dev_err(&pdev->dev, "Failed to get io memory region\n"); ret = -ENOENT; goto p_err_info; } regs_res = request_mem_region(mem_res->start, resource_size(mem_res), pdev->name); if (!regs_res) { dev_err(&pdev->dev, "Failed to request io memory region\n"); ret = -ENOENT; goto p_err_info; } dev->regs_res = regs_res; dev->regs = ioremap(mem_res->start, resource_size(mem_res)); if (!dev->regs) { dev_err(&pdev->dev, "Failed to remap io region\n"); ret = -ENXIO; goto p_err_req_region; } /* * initialize IRQ , FIMC-IS IRQ : ISP[0] -> SPI[90] , ISP[1] -> SPI[95] */ dev->irq1 = platform_get_irq(pdev, 0); if (dev->irq1 < 0) { ret = dev->irq1; dev_err(&pdev->dev, "Failed to get irq\n"); goto p_err_get_irq; } ret = request_irq(dev->irq1, fimc_is_irq_handler1, IRQF_DISABLED, dev_name(&pdev->dev), dev); if (ret) { dev_err(&pdev->dev, "failed to allocate irq (%d)\n", ret); goto p_err_req_irq; } #if defined(CONFIG_VIDEO_EXYNOS_FIMC_IS_BAYER) /* Init v4l2 device (ISP) */ #if defined(CONFIG_VIDEOBUF2_CMA_PHYS) dev->vb2 = &fimc_is_vb2_cma; #elif defined(CONFIG_VIDEOBUF2_ION) dev->vb2 = &fimc_is_vb2_ion; #endif /* Init and register V4L2 device */ v4l2_dev = &dev->video[FIMC_IS_VIDEO_NUM_BAYER].v4l2_dev; if (!v4l2_dev->name[0]) snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s.isp", dev_name(&dev->pdev->dev)); ret = v4l2_device_register(NULL, v4l2_dev); snprintf(dev->video[FIMC_IS_VIDEO_NUM_BAYER].vd.name, sizeof(dev->video[FIMC_IS_VIDEO_NUM_BAYER].vd.name), "%s", "exynos4-fimc-is-bayer"); dev->video[FIMC_IS_VIDEO_NUM_BAYER].vd.fops = &fimc_is_isp_video_fops; dev->video[FIMC_IS_VIDEO_NUM_BAYER].vd.ioctl_ops = &fimc_is_isp_video_ioctl_ops; dev->video[FIMC_IS_VIDEO_NUM_BAYER].vd.minor = -1; dev->video[FIMC_IS_VIDEO_NUM_BAYER].vd.release = video_device_release; dev->video[FIMC_IS_VIDEO_NUM_BAYER].vd.lock = &dev->lock; video_set_drvdata(&dev->video[FIMC_IS_VIDEO_NUM_BAYER].vd, dev); dev->video[FIMC_IS_VIDEO_NUM_BAYER].dev = dev; isp_q = &dev->video[FIMC_IS_VIDEO_NUM_BAYER].vbq; memset(isp_q, 0, sizeof(*isp_q)); isp_q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; isp_q->io_modes = VB2_MMAP | VB2_USERPTR; isp_q->drv_priv = &dev->video[FIMC_IS_VIDEO_NUM_BAYER]; isp_q->ops = &fimc_is_isp_qops; isp_q->mem_ops = dev->vb2->ops; vb2_queue_init(isp_q); ret = video_register_device(&dev->video[FIMC_IS_VIDEO_NUM_BAYER].vd, VFL_TYPE_GRABBER, 30); if (ret) { v4l2_err(v4l2_dev, "Failed to register video device\n"); goto err_vd_reg; } printk(KERN_INFO "FIMC-IS Video node :: ISP %d minor : %d\n", dev->video[FIMC_IS_VIDEO_NUM_BAYER].vd.num, dev->video[FIMC_IS_VIDEO_NUM_BAYER].vd.minor); #endif /* * initialize memory manager */ ret = fimc_is_init_mem_mgr(dev); if (ret) { dev_err(&pdev->dev, "failed to fimc_is_init_mem_mgr (%d)\n", ret); goto p_err_init_mem; } dbg("Parameter region = 0x%08x\n", (unsigned int)dev->is_p_region); /* * Get related clock for FIMC-IS */ if (dev->pdata->clk_get) { dev->pdata->clk_get(pdev); } else { err("#### failed to Get Clock####\n"); goto p_err_init_mem; } /* Init v4l2 sub device */ v4l2_subdev_init(&dev->sd, &fimc_is_subdev_ops); dev->sd.owner = THIS_MODULE; strcpy(dev->sd.name, MODULE_NAME); v4l2_set_subdevdata(&dev->sd, pdev); platform_set_drvdata(pdev, &dev->sd); pm_runtime_enable(&pdev->dev); #if defined(CONFIG_BUSFREQ_OPP) || defined(CONFIG_BUSFREQ_LOCK_WRAPPER) /* To lock bus frequency in OPP mode */ dev->bus_dev = dev_get("exynos-busfreq"); #endif dev->power = 0; dev->state = 0; dev->sensor_num = FIMC_IS_SENSOR_NUM; dev->sensor.id = 0; dev->p_region_index1 = 0; dev->p_region_index2 = 0; dev->sensor.offset_x = 16; dev->sensor.offset_y = 12; dev->sensor.framerate_update = false; atomic_set(&dev->p_region_num, 0); set_bit(IS_ST_IDLE, &dev->state); set_bit(IS_PWR_ST_POWEROFF, &dev->power); dev->af.af_state = FIMC_IS_AF_IDLE; dev->af.mode = IS_FOCUS_MODE_IDLE; dev->low_power_mode = false; dev->fw.state = 0; dev->setfile.state = 0; #if defined(M0) s5k6a3_dev = device_create(camera_class, NULL, 0, NULL, "front"); if (IS_ERR(s5k6a3_dev)) { printk(KERN_ERR "failed to create device!\n"); } else { if (device_create_file(s5k6a3_dev, &dev_attr_front_camtype) < 0) { printk(KERN_ERR "failed to create device file, %s\n", dev_attr_front_camtype.attr.name); } if (device_create_file(s5k6a3_dev, &dev_attr_front_camfw) < 0) { printk(KERN_ERR "failed to create device file, %s\n", dev_attr_front_camfw.attr.name); } } #endif printk(KERN_INFO "FIMC-IS probe completed\n"); return 0; p_err_init_mem: free_irq(dev->irq1, dev); #if defined(CONFIG_VIDEO_EXYNOS_FIMC_IS_BAYER) err_vd_reg: video_device_release(&dev->video[FIMC_IS_VIDEO_NUM_BAYER].vd); #endif p_err_req_irq: p_err_get_irq: iounmap(dev->regs); p_err_req_region: release_mem_region(regs_res->start, resource_size(regs_res)); p_err_info: dev_err(&dev->pdev->dev, "failed to install\n"); kfree(dev); return ret; }
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 cx18_reg_dev(struct cx18 *cx, int type) { struct cx18_stream *s = &cx->streams[type]; int vfl_type = cx18_stream_info[type].vfl_type; const char *name; int num, ret; if (type == CX18_ENC_STREAM_TYPE_TS && s->dvb != NULL) { ret = cx18_dvb_register(s); if (ret < 0) { CX18_ERR("DVB failed to register\n"); return ret; } } if (s->video_dev == NULL) return 0; num = s->video_dev->num; /* card number + user defined offset + device offset */ if (type != CX18_ENC_STREAM_TYPE_MPG) { struct cx18_stream *s_mpg = &cx->streams[CX18_ENC_STREAM_TYPE_MPG]; if (s_mpg->video_dev) num = s_mpg->video_dev->num + cx18_stream_info[type].num_offset; } video_set_drvdata(s->video_dev, s); /* Register device. First try the desired minor, then any free one. */ ret = video_register_device_no_warn(s->video_dev, vfl_type, num); if (ret < 0) { CX18_ERR("Couldn't register v4l2 device for %s (device node number %d)\n", s->name, num); video_device_release(s->video_dev); s->video_dev = NULL; return ret; } name = video_device_node_name(s->video_dev); switch (vfl_type) { case VFL_TYPE_GRABBER: CX18_INFO("Registered device %s for %s (%d x %d.%02d kB)\n", name, s->name, cx->stream_buffers[type], cx->stream_buf_size[type] / 1024, (cx->stream_buf_size[type] * 100 / 1024) % 100); break; case VFL_TYPE_RADIO: CX18_INFO("Registered device %s for %s\n", name, s->name); break; case VFL_TYPE_VBI: if (cx->stream_buffers[type]) CX18_INFO("Registered device %s for %s " "(%d x %d bytes)\n", name, s->name, cx->stream_buffers[type], cx->stream_buf_size[type]); else CX18_INFO("Registered device %s for %s\n", name, s->name); break; } return 0; }
static int __devinit fimc_probe(struct platform_device *pdev) { struct s3c_platform_fimc *pdata; struct fimc_control *ctrl; int ret; if (!fimc_dev) { fimc_dev = kzalloc(sizeof(*fimc_dev), GFP_KERNEL); if (!fimc_dev) { dev_err(&pdev->dev, "%s: not enough memory\n", __func__); goto err_fimc; } } ctrl = fimc_register_controller(pdev); if (!ctrl) { printk(KERN_ERR "%s: cannot register fimc\n", __func__); goto err_fimc; } pdata = to_fimc_plat(&pdev->dev); if (pdata->cfg_gpio) pdata->cfg_gpio(pdev); /* V4L2 device-subdev registration */ ret = v4l2_device_register(&pdev->dev, &ctrl->v4l2_dev); if (ret) { fimc_err("%s: v4l2 device register failed\n", __func__); goto err_v4l2; } /* things to initialize once */ if (!fimc_dev->initialized) { ret = fimc_init_global(pdev); if (ret) goto err_global; } /* v4l2 subdev configuration */ ret = fimc_configure_subdev(pdev, ctrl->id); if (ret) { fimc_err("%s: subdev[%d] registering failed\n", __func__, ctrl->id); } /* video device register */ ret = video_register_device(ctrl->vd, VFL_TYPE_GRABBER, ctrl->id); if (ret) { fimc_err("%s: cannot register video driver\n", __func__); goto err_global; } video_set_drvdata(ctrl->vd, ctrl); ret = device_create_file(&(pdev->dev), &dev_attr_log_level); if (ret < 0) fimc_err("failed to add sysfs entries\n"); fimc_info1("controller %d registered successfully\n", ctrl->id); return 0; err_global: clk_disable(ctrl->clk); clk_put(ctrl->clk); err_v4l2: fimc_unregister_controller(pdev); err_fimc: return -EINVAL; }
/* * 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; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; int i, int_end_size, 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->usb_buf = kmalloc(MAX_REPORT_SIZE, GFP_KERNEL); if (radio->usb_buf == NULL) { retval = -ENOMEM; goto err_radio; } radio->usbdev = interface_to_usbdev(intf); radio->intf = intf; radio->band = 1; /* Default to 76 - 108 MHz */ mutex_init(&radio->lock); init_completion(&radio->completion); iface_desc = intf->cur_altsetting; /* Set up interrupt endpoint information. */ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { endpoint = &iface_desc->endpoint[i].desc; if (usb_endpoint_is_int_in(endpoint)) radio->int_in_endpoint = endpoint; } if (!radio->int_in_endpoint) { dev_info(&intf->dev, "could not find interrupt in endpoint\n"); retval = -EIO; goto err_usbbuf; } int_end_size = le16_to_cpu(radio->int_in_endpoint->wMaxPacketSize); radio->int_in_buffer = kmalloc(int_end_size, GFP_KERNEL); if (!radio->int_in_buffer) { dev_info(&intf->dev, "could not allocate int_in_buffer"); retval = -ENOMEM; goto err_usbbuf; } radio->int_in_urb = usb_alloc_urb(0, GFP_KERNEL); if (!radio->int_in_urb) { retval = -ENOMEM; goto err_intbuffer; } radio->v4l2_dev.release = si470x_usb_release; /* * The si470x SiLabs reference design uses the same USB IDs as * 'Thanko's Raremono' si4734 based receiver. So check here which we * have: attempt to read the device ID from the si470x: the lower 12 * bits should be 0x0242 for the si470x. * * We use this check to determine which device we are dealing with. */ if (id->idVendor == 0x10c4 && id->idProduct == 0x818a) { retval = usb_control_msg(radio->usbdev, usb_rcvctrlpipe(radio->usbdev, 0), HID_REQ_GET_REPORT, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, 1, 2, radio->usb_buf, 3, 500); if (retval != 3 || (get_unaligned_be16(&radio->usb_buf[1]) & 0xfff) != 0x0242) { dev_info(&intf->dev, "this is not a si470x device.\n"); retval = -ENODEV; goto err_urb; } } retval = v4l2_device_register(&intf->dev, &radio->v4l2_dev); if (retval < 0) { dev_err(&intf->dev, "couldn't register v4l2_device\n"); goto err_urb; } v4l2_ctrl_handler_init(&radio->hdl, 2); v4l2_ctrl_new_std(&radio->hdl, &si470x_ctrl_ops, V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1); v4l2_ctrl_new_std(&radio->hdl, &si470x_ctrl_ops, V4L2_CID_AUDIO_VOLUME, 0, 15, 1, 15); if (radio->hdl.error) { retval = radio->hdl.error; dev_err(&intf->dev, "couldn't register control\n"); goto err_dev; } radio->videodev = si470x_viddev_template; radio->videodev.ctrl_handler = &radio->hdl; radio->videodev.lock = &radio->lock; radio->videodev.v4l2_dev = &radio->v4l2_dev; radio->videodev.release = video_device_release_empty; video_set_drvdata(&radio->videodev, radio); /* get device and chip versions */ if (si470x_get_all_registers(radio) < 0) { retval = -EIO; goto err_ctrl; } dev_info(&intf->dev, "DeviceID=0x%4.4hx ChipID=0x%4.4hx\n", radio->registers[DEVICEID], radio->registers[SI_CHIPID]); if ((radio->registers[SI_CHIPID] & SI_CHIPID_FIRMWARE) < RADIO_FW_VERSION) { dev_warn(&intf->dev, "This driver is known to work with firmware version %hu,\n", RADIO_FW_VERSION); dev_warn(&intf->dev, "but the device has firmware version %hu.\n", radio->registers[SI_CHIPID] & SI_CHIPID_FIRMWARE); version_warning = 1; } /* get software and hardware versions */ if (si470x_get_scratch_page_versions(radio) < 0) { retval = -EIO; goto err_ctrl; } dev_info(&intf->dev, "software version %d, hardware version %d\n", radio->software_version, radio->hardware_version); if (radio->hardware_version < RADIO_HW_VERSION) { dev_warn(&intf->dev, "This driver is known to work with hardware version %hu,\n", RADIO_HW_VERSION); dev_warn(&intf->dev, "but the device has hardware version %hu.\n", radio->hardware_version); version_warning = 1; } /* give out version warning */ if (version_warning == 1) { dev_warn(&intf->dev, "If you have some trouble using this driver,\n"); dev_warn(&intf->dev, "please report to V4L ML at [email protected]\n"); } /* 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_ctrl; } /* rds buffer configuration */ radio->wr_index = 0; radio->rd_index = 0; init_waitqueue_head(&radio->read_queue); usb_set_intfdata(intf, radio); /* start radio */ retval = si470x_start_usb(radio); if (retval < 0) goto err_all; /* set initial frequency */ si470x_set_freq(radio, 87.5 * FREQ_MUL); /* available in all regions */ /* register video device */ retval = video_register_device(&radio->videodev, VFL_TYPE_RADIO, radio_nr); if (retval) { dev_err(&intf->dev, "Could not register video device\n"); goto err_all; } return 0; err_all: kfree(radio->buffer); err_ctrl: v4l2_ctrl_handler_free(&radio->hdl); err_dev: v4l2_device_unregister(&radio->v4l2_dev); err_urb: usb_free_urb(radio->int_in_urb); err_intbuffer: kfree(radio->int_in_buffer); err_usbbuf: kfree(radio->usb_buf); err_radio: kfree(radio); err_initial: return retval; }
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; }