int usbtv_video_init(struct usbtv *usbtv) { int ret; (void)usbtv_configure_for_norm(usbtv, V4L2_STD_525_60); spin_lock_init(&usbtv->buflock); mutex_init(&usbtv->v4l2_lock); mutex_init(&usbtv->vb2q_lock); INIT_LIST_HEAD(&usbtv->bufs); /* videobuf2 structure */ usbtv->vb2q.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; usbtv->vb2q.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; usbtv->vb2q.drv_priv = usbtv; usbtv->vb2q.buf_struct_size = sizeof(struct usbtv_buf); usbtv->vb2q.ops = &usbtv_vb2_ops; usbtv->vb2q.mem_ops = &vb2_vmalloc_memops; usbtv->vb2q.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; usbtv->vb2q.lock = &usbtv->vb2q_lock; ret = vb2_queue_init(&usbtv->vb2q); if (ret < 0) { dev_warn(usbtv->dev, "Could not initialize videobuf2 queue\n"); return ret; } /* v4l2 structure */ usbtv->v4l2_dev.release = usbtv_release; ret = v4l2_device_register(usbtv->dev, &usbtv->v4l2_dev); if (ret < 0) { dev_warn(usbtv->dev, "Could not register v4l2 device\n"); goto v4l2_fail; } /* Video structure */ strlcpy(usbtv->vdev.name, "usbtv", sizeof(usbtv->vdev.name)); usbtv->vdev.v4l2_dev = &usbtv->v4l2_dev; usbtv->vdev.release = video_device_release_empty; usbtv->vdev.fops = &usbtv_fops; usbtv->vdev.ioctl_ops = &usbtv_ioctl_ops; usbtv->vdev.tvnorms = USBTV_TV_STD; usbtv->vdev.queue = &usbtv->vb2q; usbtv->vdev.lock = &usbtv->v4l2_lock; set_bit(V4L2_FL_USE_FH_PRIO, &usbtv->vdev.flags); video_set_drvdata(&usbtv->vdev, usbtv); ret = video_register_device(&usbtv->vdev, VFL_TYPE_GRABBER, -1); if (ret < 0) { dev_warn(usbtv->dev, "Could not register video device\n"); goto vdev_fail; } return 0; vdev_fail: v4l2_device_unregister(&usbtv->v4l2_dev); v4l2_fail: vb2_queue_release(&usbtv->vb2q); return ret; }
static int __init zoltrix_init(void) { struct zoltrix *zol = &zoltrix_card; struct v4l2_device *v4l2_dev = &zol->v4l2_dev; int res; strlcpy(v4l2_dev->name, "zoltrix", sizeof(v4l2_dev->name)); zol->io = io; if (zol->io == -1) { v4l2_err(v4l2_dev, "You must set an I/O address with io=0x20c or 0x30c\n"); return -EINVAL; } if (zol->io != 0x20c && zol->io != 0x30c) { v4l2_err(v4l2_dev, "invalid port, try 0x20c or 0x30c\n"); return -ENXIO; } if (!request_region(zol->io, 2, "zoltrix")) { v4l2_err(v4l2_dev, "port 0x%x already in use\n", zol->io); return -EBUSY; } res = v4l2_device_register(NULL, v4l2_dev); if (res < 0) { release_region(zol->io, 2); v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); return res; } <<<<<<< HEAD
/* * Media device */ static int camif_media_dev_init(struct camif_dev *camif) { struct media_device *md = &camif->media_dev; struct v4l2_device *v4l2_dev = &camif->v4l2_dev; unsigned int ip_rev = camif->variant->ip_revision; int ret; memset(md, 0, sizeof(*md)); snprintf(md->model, sizeof(md->model), "SAMSUNG S3C%s CAMIF", ip_rev == S3C6410_CAMIF_IP_REV ? "6410" : "244X"); strlcpy(md->bus_info, "platform", sizeof(md->bus_info)); md->hw_revision = ip_rev; md->driver_version = KERNEL_VERSION(1, 0, 0); md->dev = camif->dev; strlcpy(v4l2_dev->name, "s3c-camif", sizeof(v4l2_dev->name)); v4l2_dev->mdev = md; media_device_init(md); ret = v4l2_device_register(camif->dev, v4l2_dev); if (ret < 0) return ret; return ret; }
static int __init zoltrix_init(void) { struct zoltrix *zol = &zoltrix_card; struct v4l2_device *v4l2_dev = &zol->v4l2_dev; int res; strlcpy(v4l2_dev->name, "zoltrix", sizeof(v4l2_dev->name)); zol->io = io; if (zol->io == -1) { v4l2_err(v4l2_dev, "You must set an I/O address with io=0x20c or 0x30c\n"); return -EINVAL; } if (zol->io != 0x20c && zol->io != 0x30c) { v4l2_err(v4l2_dev, "invalid port, try 0x20c or 0x30c\n"); return -ENXIO; } if (!request_region(zol->io, 2, "zoltrix")) { v4l2_err(v4l2_dev, "port 0x%x already in use\n", zol->io); return -EBUSY; } res = v4l2_device_register(NULL, v4l2_dev); if (res < 0) { release_region(zol->io, 2); v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); return res; } strlcpy(zol->vdev.name, v4l2_dev->name, sizeof(zol->vdev.name)); zol->vdev.v4l2_dev = v4l2_dev; zol->vdev.fops = &zoltrix_fops; zol->vdev.ioctl_ops = &zoltrix_ioctl_ops; zol->vdev.release = video_device_release_empty; video_set_drvdata(&zol->vdev, zol); if (video_register_device(&zol->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { v4l2_device_unregister(v4l2_dev); release_region(zol->io, 2); return -EINVAL; } v4l2_info(v4l2_dev, "Zoltrix Radio Plus card driver.\n"); mutex_init(&zol->lock); /* mute card - prevents noisy bootups */ /* this ensures that the volume is all the way down */ outb(0, zol->io); outb(0, zol->io); msleep(20); inb(zol->io + 3); zol->curvol = 0; zol->stereo = 1; return 0; }
static int timbradio_probe(struct platform_device *pdev) #endif { struct timb_radio_platform_data *pdata = pdev->dev.platform_data; struct timbradio *tr; int err; if (!pdata) { dev_err(&pdev->dev, "Platform data missing\n"); err = -EINVAL; goto err; } tr = kzalloc(sizeof(*tr), GFP_KERNEL); if (!tr) { err = -ENOMEM; goto err; } tr->pdata = *pdata; mutex_init(&tr->lock); strlcpy(tr->video_dev.name, "Timberdale Radio", sizeof(tr->video_dev.name)); tr->video_dev.fops = &timbradio_fops; tr->video_dev.ioctl_ops = &timbradio_ioctl_ops; tr->video_dev.release = video_device_release_empty; tr->video_dev.minor = -1; tr->video_dev.lock = &tr->lock; strlcpy(tr->v4l2_dev.name, DRIVER_NAME, sizeof(tr->v4l2_dev.name)); err = v4l2_device_register(NULL, &tr->v4l2_dev); if (err) goto err_v4l2_dev; tr->video_dev.v4l2_dev = &tr->v4l2_dev; err = video_register_device(&tr->video_dev, VFL_TYPE_RADIO, -1); if (err) { dev_err(&pdev->dev, "Error reg video\n"); goto err_video_req; } video_set_drvdata(&tr->video_dev, tr); platform_set_drvdata(pdev, tr); return 0; err_video_req: video_device_release_empty(&tr->video_dev); v4l2_device_unregister(&tr->v4l2_dev); err_v4l2_dev: kfree(tr); err: dev_err(&pdev->dev, "Failed to register: %d\n", err); return err; }
static int __devinit __wfd_probe(struct platform_device *pdev) { int rc = 0; struct wfd_device *wfd_dev; WFD_MSG_DBG("__wfd_probe: E\n"); wfd_dev = kzalloc(sizeof(*wfd_dev), GFP_KERNEL); /*TODO: Free it*/ if (!wfd_dev) { WFD_MSG_ERR("Could not allocate memory for " "wfd device\n"); return -ENOMEM; } pdev->dev.platform_data = (void *) wfd_dev; rc = v4l2_device_register(&pdev->dev, &wfd_dev->v4l2_dev); if (rc) { WFD_MSG_ERR("Failed to register the video device\n"); goto err_v4l2_registration; } wfd_dev->pvdev = video_device_alloc(); if (!wfd_dev->pvdev) { WFD_MSG_ERR("Failed to allocate video device\n"); goto err_video_device_alloc; } wfd_dev->pvdev->release = release_video_device; wfd_dev->pvdev->fops = &g_wfd_fops; wfd_dev->pvdev->ioctl_ops = &g_wfd_ioctl_ops; rc = video_register_device(wfd_dev->pvdev, VFL_TYPE_GRABBER, -1); if (rc) { WFD_MSG_ERR("Failed to register the device\n"); goto err_video_register_device; } video_set_drvdata(wfd_dev->pvdev, wfd_dev); v4l2_subdev_init(&wfd_dev->mdp_sdev, &mdp_subdev_ops); strncpy(wfd_dev->mdp_sdev.name, "wfd-mdp", V4L2_SUBDEV_NAME_SIZE); rc = v4l2_device_register_subdev(&wfd_dev->v4l2_dev, &wfd_dev->mdp_sdev); if (rc) { WFD_MSG_ERR("Failed to register mdp subdevice: %d\n", rc); goto err_mdp_register_subdev; } WFD_MSG_DBG("__wfd_probe: X\n"); return rc; err_mdp_register_subdev: video_unregister_device(wfd_dev->pvdev); err_video_register_device: video_device_release(wfd_dev->pvdev); err_video_device_alloc: v4l2_device_unregister(&wfd_dev->v4l2_dev); err_v4l2_registration: kfree(wfd_dev); return rc; }
static int __init rtrack_init(void) { struct rtrack *rt = &rtrack_card; struct v4l2_device *v4l2_dev = &rt->v4l2_dev; int res; strlcpy(v4l2_dev->name, "rtrack", sizeof(v4l2_dev->name)); rt->io = io; if (rt->io == -1) { v4l2_err(v4l2_dev, "you must set an I/O address with io=0x20f or 0x30f\n"); return -EINVAL; } if (!request_region(rt->io, 2, "rtrack")) { v4l2_err(v4l2_dev, "port 0x%x already in use\n", rt->io); return -EBUSY; } res = v4l2_device_register(NULL, v4l2_dev); if (res < 0) { release_region(rt->io, 2); v4l2_err(v4l2_dev, "could not register v4l2_device\n"); return res; } strlcpy(rt->vdev.name, v4l2_dev->name, sizeof(rt->vdev.name)); rt->vdev.v4l2_dev = v4l2_dev; rt->vdev.fops = &rtrack_fops; rt->vdev.ioctl_ops = &rtrack_ioctl_ops; rt->vdev.release = video_device_release_empty; video_set_drvdata(&rt->vdev, rt); if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { v4l2_device_unregister(&rt->v4l2_dev); release_region(rt->io, 2); return -EINVAL; } v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n"); mutex_init(&rt->lock); outb(0x48, rt->io); sleep_delay(2000000); outb(0xc0, rt->io); return 0; }
static int __init rtrack_init(void) { struct rtrack *rt = &rtrack_card; struct v4l2_device *v4l2_dev = &rt->v4l2_dev; int res; strlcpy(v4l2_dev->name, "rtrack", sizeof(v4l2_dev->name)); rt->io = io; if (rt->io == -1) { v4l2_err(v4l2_dev, "you must set an I/O address with io=0x20f or 0x30f\n"); return -EINVAL; } if (!request_region(rt->io, 2, "rtrack")) { v4l2_err(v4l2_dev, "port 0x%x already in use\n", rt->io); return -EBUSY; } res = v4l2_device_register(NULL, v4l2_dev); if (res < 0) { release_region(rt->io, 2); v4l2_err(v4l2_dev, "could not register v4l2_device\n"); return res; } strlcpy(rt->vdev.name, v4l2_dev->name, sizeof(rt->vdev.name)); rt->vdev.v4l2_dev = v4l2_dev; rt->vdev.fops = &rtrack_fops; rt->vdev.ioctl_ops = &rtrack_ioctl_ops; rt->vdev.release = video_device_release_empty; video_set_drvdata(&rt->vdev, rt); /* Set up the I/O locking */ mutex_init(&rt->lock); /* mute card - prevents noisy bootups */ /* this ensures that the volume is all the way down */ outb(0x48, rt->io); /* volume down but still "on" */ msleep(2000); /* make sure it's totally down */ outb(0xc0, rt->io); /* steady volume, mute card */ if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { v4l2_device_unregister(&rt->v4l2_dev); release_region(rt->io, 2); return -EINVAL; } v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n"); return 0; }
static int __init rtrack2_init(void) { struct rtrack2 *dev = &rtrack2_card; struct v4l2_device *v4l2_dev = &dev->v4l2_dev; int res; strlcpy(v4l2_dev->name, "rtrack2", sizeof(v4l2_dev->name)); dev->io = io; if (dev->io == -1) { v4l2_err(v4l2_dev, "You must set an I/O address with io=0x20c or io=0x30c\n"); return -EINVAL; } if (!request_region(dev->io, 4, "rtrack2")) { v4l2_err(v4l2_dev, "port 0x%x already in use\n", dev->io); return -EBUSY; } res = v4l2_device_register(NULL, v4l2_dev); if (res < 0) { release_region(dev->io, 4); v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); return res; } strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name)); dev->vdev.v4l2_dev = v4l2_dev; dev->vdev.fops = &rtrack2_fops; dev->vdev.ioctl_ops = &rtrack2_ioctl_ops; dev->vdev.release = video_device_release_empty; video_set_drvdata(&dev->vdev, dev); mutex_init(&dev->lock); if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { v4l2_device_unregister(v4l2_dev); release_region(dev->io, 4); return -EINVAL; } v4l2_info(v4l2_dev, "AIMSlab Radiotrack II card driver.\n"); outb(1, dev->io); dev->muted = 1; return 0; }
static int __devinit mdev_probe(struct platform_device *pdev) { struct v4l2_device *v4l2_dev; struct exynos_md *mdev; int ret; mdev = kzalloc(sizeof(struct exynos_md), GFP_KERNEL); if (!mdev) return -ENOMEM; mdev->id = pdev->id; mdev->pdev = pdev; spin_lock_init(&mdev->slock); snprintf(mdev->media_dev.model, sizeof(mdev->media_dev.model), "%s%d", dev_name(&pdev->dev), mdev->id); mdev->media_dev.dev = &pdev->dev; v4l2_dev = &mdev->v4l2_dev; v4l2_dev->mdev = &mdev->media_dev; snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s", dev_name(&pdev->dev)); ret = v4l2_device_register(&pdev->dev, &mdev->v4l2_dev); if (ret < 0) { v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret); goto err_v4l2_reg; } ret = media_device_register(&mdev->media_dev); if (ret < 0) { v4l2_err(v4l2_dev, "Failed to register media device: %d\n", ret); goto err_mdev_reg; } platform_set_drvdata(pdev, mdev); v4l2_info(v4l2_dev, "Media%d[0x%08x] was registered successfully\n", mdev->id, (unsigned int)mdev); return 0; err_mdev_reg: v4l2_device_unregister(&mdev->v4l2_dev); err_v4l2_reg: kfree(mdev); return ret; }
static int fmr2_probe(struct fmr2 *fmr2, struct device *pdev, int io) { int err, i; char *card_name = fmr2->is_fmd2 ? "SF16-FMD2" : "SF16-FMR2"; /* avoid errors if a card was already registered at given port */ for (i = 0; i < num_fmr2_cards; i++) if (io == fmr2_cards[i]->io) return -EBUSY; strlcpy(fmr2->v4l2_dev.name, "radio-sf16fmr2", sizeof(fmr2->v4l2_dev.name)), fmr2->io = io; if (!request_region(fmr2->io, 2, fmr2->v4l2_dev.name)) { printk(KERN_ERR "radio-sf16fmr2: I/O port 0x%x already in use\n", fmr2->io); return -EBUSY; } dev_set_drvdata(pdev, fmr2); err = v4l2_device_register(pdev, &fmr2->v4l2_dev); if (err < 0) { v4l2_err(&fmr2->v4l2_dev, "Could not register v4l2_device\n"); release_region(fmr2->io, 2); return err; } fmr2->tea.v4l2_dev = &fmr2->v4l2_dev; fmr2->tea.private_data = fmr2; fmr2->tea.radio_nr = radio_nr[num_fmr2_cards]; fmr2->tea.ops = &fmr2_tea_ops; fmr2->tea.ext_init = fmr2_tea_ext_init; strlcpy(fmr2->tea.card, card_name, sizeof(fmr2->tea.card)); snprintf(fmr2->tea.bus_info, sizeof(fmr2->tea.bus_info), "%s:%s", fmr2->is_fmd2 ? "PnP" : "ISA", dev_name(pdev)); if (snd_tea575x_init(&fmr2->tea, THIS_MODULE)) { printk(KERN_ERR "radio-sf16fmr2: Unable to detect TEA575x tuner\n"); release_region(fmr2->io, 2); return -ENODEV; } printk(KERN_INFO "radio-sf16fmr2: %s radio card at 0x%x.\n", card_name, fmr2->io); return 0; }
static int au0828_usb_probe(struct usb_interface *interface, const struct usb_device_id *id) { int ifnum; int retval = 0; struct au0828_dev *dev; struct usb_device *usbdev = interface_to_usbdev(interface); ifnum = interface->altsetting->desc.bInterfaceNumber; if (ifnum != 0) return -ENODEV; dprintk(1, "%s() vendor id 0x%x device id 0x%x ifnum:%d\n", __func__, le16_to_cpu(usbdev->descriptor.idVendor), le16_to_cpu(usbdev->descriptor.idProduct), ifnum); /* * Make sure we have 480 Mbps of bandwidth, otherwise things like * video stream wouldn't likely work, since 12 Mbps is generally * not enough even for most Digital TV streams. */ if (usbdev->speed != USB_SPEED_HIGH && disable_usb_speed_check == 0) { pr_err("au0828: Device initialization failed.\n"); pr_err("au0828: Device must be connected to a high-speed USB 2.0 port.\n"); return -ENODEV; } dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (dev == NULL) { pr_err("%s() Unable to allocate memory\n", __func__); return -ENOMEM; } mutex_init(&dev->lock); mutex_lock(&dev->lock); mutex_init(&dev->mutex); mutex_init(&dev->dvb.lock); dev->usbdev = usbdev; dev->boardnr = id->driver_info; #ifdef CPTCFG_VIDEO_AU0828_V4L2 dev->v4l2_dev.release = au0828_usb_v4l2_release; /* Create the v4l2_device */ retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev); if (retval) { pr_err("%s() v4l2_device_register failed\n", __func__); mutex_unlock(&dev->lock); kfree(dev); return retval; } /* This control handler will inherit the controls from au8522 */ retval = v4l2_ctrl_handler_init(&dev->v4l2_ctrl_hdl, 4); if (retval) { pr_err("%s() v4l2_ctrl_handler_init failed\n", __func__); mutex_unlock(&dev->lock); kfree(dev); return retval; } dev->v4l2_dev.ctrl_handler = &dev->v4l2_ctrl_hdl; #endif /* Power Up the bridge */ au0828_write(dev, REG_600, 1 << 4); /* Bring up the GPIO's and supporting devices */ au0828_gpio_setup(dev); /* I2C */ au0828_i2c_register(dev); /* Setup */ au0828_card_setup(dev); #ifdef CPTCFG_VIDEO_AU0828_V4L2 /* Analog TV */ if (AUVI_INPUT(0).type != AU0828_VMUX_UNDEFINED) au0828_analog_register(dev, interface); #endif /* Digital TV */ retval = au0828_dvb_register(dev); if (retval) pr_err("%s() au0282_dev_register failed\n", __func__); /* Remote controller */ au0828_rc_register(dev); /* * Store the pointer to the au0828_dev so it can be accessed in * au0828_usb_disconnect */ usb_set_intfdata(interface, dev); pr_info("Registered device AU0828 [%s]\n", dev->board.name == NULL ? "Unset" : dev->board.name); mutex_unlock(&dev->lock); return retval; }
static int omap24xxcam_probe(struct platform_device *pdev) { struct omap24xxcam_device *cam; struct resource *mem; int irq; cam = kzalloc(sizeof(*cam), GFP_KERNEL); if (!cam) { dev_err(&pdev->dev, "could not allocate memory\n"); goto err; } platform_set_drvdata(pdev, cam); cam->dev = &pdev->dev; if (v4l2_device_register(&pdev->dev, &cam->v4l2_dev)) { dev_err(&pdev->dev, "v4l2_device_register failed\n"); goto err; } /* * Impose a lower limit on the amount of memory allocated for * capture. We require at least enough memory to double-buffer * QVGA (300KB). */ if (capture_mem < 320 * 240 * 2 * 2) capture_mem = 320 * 240 * 2 * 2; cam->capture_mem = capture_mem; /* request the mem region for the camera registers */ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) { dev_err(cam->dev, "no mem resource?\n"); goto err; } if (!request_mem_region(mem->start, resource_size(mem), pdev->name)) { dev_err(cam->dev, "cannot reserve camera register I/O region\n"); goto err; } cam->mmio_base_phys = mem->start; cam->mmio_size = resource_size(mem); /* map the region */ cam->mmio_base = ioremap_nocache(cam->mmio_base_phys, cam->mmio_size); if (!cam->mmio_base) { dev_err(cam->dev, "cannot map camera register I/O region\n"); goto err; } irq = platform_get_irq(pdev, 0); if (irq <= 0) { dev_err(cam->dev, "no irq for camera?\n"); goto err; } /* install the interrupt service routine */ if (request_irq(irq, omap24xxcam_isr, 0, CAM_NAME, cam)) { dev_err(cam->dev, "could not install interrupt service routine\n"); goto err; } cam->irq = irq; if (omap24xxcam_clock_get(cam)) goto err; INIT_WORK(&cam->sensor_reset_work, omap24xxcam_sensor_reset_work); mutex_init(&cam->mutex); spin_lock_init(&cam->core_enable_disable_lock); omap24xxcam_sgdma_init(&cam->sgdma, cam->mmio_base + CAMDMA_REG_OFFSET, omap24xxcam_stalled_dma_reset, (unsigned long)cam); omap24xxcam.priv = cam; if (v4l2_int_device_register(&omap24xxcam)) goto err; return 0; err: omap24xxcam_remove(pdev); return -ENODEV; }
/* 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; }
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; }
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; }
static int atomisp_register_entities(struct atomisp_device *isp) { int ret = 0; unsigned int i; isp->media_dev.dev = isp->dev; strlcpy(isp->media_dev.model, "Intel Atom ISP", sizeof(isp->media_dev.model)); ret = media_device_register(&isp->media_dev); if (ret < 0) { v4l2_err(&atomisp_dev, "%s: Media device registration " "failed (%d)\n", __func__, ret); return ret; } isp->v4l2_dev.mdev = &isp->media_dev; ret = v4l2_device_register(isp->dev, &isp->v4l2_dev); if (ret < 0) { v4l2_err(&atomisp_dev, "%s: V4L2 device registration failed (%d)\n", __func__, ret); goto v4l2_device_failed; } ret = atomisp_subdev_probe(isp); if (ret < 0) goto csi_and_subdev_probe_failed; /* Register internal entities */ for (i = 0; i < ATOMISP_CAMERA_NR_PORTS; i++) { ret = atomisp_mipi_csi2_register_entities(&isp->csi2_port[i], &isp->v4l2_dev); if (ret == 0) continue; /* error case */ v4l2_err(&atomisp_dev, "failed to register the CSI port: %d\n", i); /* deregister all registered CSI ports */ while (i--) atomisp_mipi_csi2_unregister_entities( &isp->csi2_port[i]); goto csi_and_subdev_probe_failed; } ret = atomisp_file_input_register_entities(&isp->file_dev, &isp->v4l2_dev); if (ret < 0) { v4l2_err(&atomisp_dev, "atomisp_file_input_register_entities\n"); goto file_input_register_failed; } ret = atomisp_tpg_register_entities(&isp->tpg, &isp->v4l2_dev); if (ret < 0) { v4l2_err(&atomisp_dev, "atomisp_tpg_register_entities\n"); goto tpg_register_failed; } for (i = 0; i < isp->num_of_streams; i++) { ret = atomisp_subdev_register_entities(&isp->isp_subdev[i], &isp->v4l2_dev); if (ret < 0) { v4l2_err(&atomisp_dev, "atomisp_subdev_register_entities fail\n"); goto subdev_register_failed; } } for (i = 0; i < isp->input_cnt; i++) { if (isp->inputs[i].port >= ATOMISP_CAMERA_NR_PORTS) { v4l2_err(&atomisp_dev, "isp->inputs port %d not supported\n", isp->inputs[i].port); ret = -EINVAL; goto link_failed; } ret = media_entity_create_link( &isp->inputs[i].camera->entity, 0, &isp->csi2_port[isp->inputs[i].port].subdev.entity, CSI2_PAD_SINK, MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE); if (ret < 0) { dev_err(isp->dev, "link create from sensor to csi-2 receiver failed\n"); goto link_failed; } } v4l2_dbg(1, dbg_level, &atomisp_dev, "FILE_INPUT enable, camera_cnt: %d\n", isp->input_cnt); isp->inputs[isp->input_cnt].type = FILE_INPUT; isp->inputs[isp->input_cnt].port = -1; isp->inputs[isp->input_cnt].shading_table = NULL; isp->inputs[isp->input_cnt].morph_table = NULL; isp->inputs[isp->input_cnt++].camera = &isp->file_dev.sd; if (isp->input_cnt < ATOM_ISP_MAX_INPUTS) { v4l2_dbg(1, dbg_level, &atomisp_dev, "TPG detected, camera_cnt: %d\n", isp->input_cnt); isp->inputs[isp->input_cnt].type = TEST_PATTERN; isp->inputs[isp->input_cnt].port = -1; isp->inputs[isp->input_cnt].shading_table = NULL; isp->inputs[isp->input_cnt].morph_table = NULL; isp->inputs[isp->input_cnt++].camera = &isp->tpg.sd; } else { v4l2_warn(&atomisp_dev, "too many atomisp inputs, TPG ignored.\n"); } ret = v4l2_device_register_subdev_nodes(&isp->v4l2_dev); if (ret < 0) goto link_failed; return ret; link_failed: for (i = 0; i < isp->num_of_streams; i++) atomisp_subdev_unregister_entities(&isp->isp_subdev[i]); subdev_register_failed: while (i--) atomisp_subdev_unregister_entities(&isp->isp_subdev[i]); atomisp_tpg_unregister_entities(&isp->tpg); tpg_register_failed: atomisp_file_input_unregister_entities(&isp->file_dev); file_input_register_failed: for (i = 0; i < ATOMISP_CAMERA_NR_PORTS; i++) atomisp_mipi_csi2_unregister_entities(&isp->csi2_port[i]); csi_and_subdev_probe_failed: v4l2_device_unregister(&isp->v4l2_dev); v4l2_device_failed: media_device_unregister(&isp->media_dev); return ret; }
static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(intf); struct pwc_device *pdev = NULL; int vendor_id, product_id, type_id; int rc; int features = 0; int compression = 0; int my_power_save = power_save; char serial_number[30], *name; vendor_id = le16_to_cpu(udev->descriptor.idVendor); product_id = le16_to_cpu(udev->descriptor.idProduct); /* Check if we can handle this device */ PWC_DEBUG_PROBE("probe() called [%04X %04X], if %d\n", vendor_id, product_id, intf->altsetting->desc.bInterfaceNumber); /* the interfaces are probed one by one. We are only interested in the video interface (0) now. Interface 1 is the Audio Control, and interface 2 Audio itself. */ if (intf->altsetting->desc.bInterfaceNumber > 0) return -ENODEV; if (vendor_id == 0x0471) { switch (product_id) { case 0x0302: PWC_INFO("Philips PCA645VC USB webcam detected.\n"); name = "Philips 645 webcam"; type_id = 645; break; case 0x0303: PWC_INFO("Philips PCA646VC USB webcam detected.\n"); name = "Philips 646 webcam"; type_id = 646; break; case 0x0304: PWC_INFO("Askey VC010 type 2 USB webcam detected.\n"); name = "Askey VC010 webcam"; type_id = 646; break; case 0x0307: PWC_INFO("Philips PCVC675K (Vesta) USB webcam detected.\n"); name = "Philips 675 webcam"; type_id = 675; break; case 0x0308: PWC_INFO("Philips PCVC680K (Vesta Pro) USB webcam detected.\n"); name = "Philips 680 webcam"; type_id = 680; break; case 0x030C: PWC_INFO("Philips PCVC690K (Vesta Pro Scan) USB webcam detected.\n"); name = "Philips 690 webcam"; type_id = 690; break; case 0x0310: PWC_INFO("Philips PCVC730K (ToUCam Fun)/PCVC830 (ToUCam II) USB webcam detected.\n"); name = "Philips 730 webcam"; type_id = 730; break; case 0x0311: PWC_INFO("Philips PCVC740K (ToUCam Pro)/PCVC840 (ToUCam II) USB webcam detected.\n"); name = "Philips 740 webcam"; type_id = 740; break; case 0x0312: PWC_INFO("Philips PCVC750K (ToUCam Pro Scan) USB webcam detected.\n"); name = "Philips 750 webcam"; type_id = 750; break; case 0x0313: PWC_INFO("Philips PCVC720K/40 (ToUCam XS) USB webcam detected.\n"); name = "Philips 720K/40 webcam"; type_id = 720; break; case 0x0329: PWC_INFO("Philips SPC 900NC USB webcam detected.\n"); name = "Philips SPC 900NC webcam"; type_id = 740; break; case 0x032C: PWC_INFO("Philips SPC 880NC USB webcam detected.\n"); name = "Philips SPC 880NC webcam"; type_id = 740; break; default: return -ENODEV; break; } } else if (vendor_id == 0x069A) { switch(product_id) { case 0x0001: PWC_INFO("Askey VC010 type 1 USB webcam detected.\n"); name = "Askey VC010 webcam"; type_id = 645; break; default: return -ENODEV; break; } } else if (vendor_id == 0x046d) { switch(product_id) { case 0x08b0: PWC_INFO("Logitech QuickCam Pro 3000 USB webcam detected.\n"); name = "Logitech QuickCam Pro 3000"; type_id = 740; /* CCD sensor */ break; case 0x08b1: PWC_INFO("Logitech QuickCam Notebook Pro USB webcam detected.\n"); name = "Logitech QuickCam Notebook Pro"; type_id = 740; /* CCD sensor */ break; case 0x08b2: PWC_INFO("Logitech QuickCam 4000 Pro USB webcam detected.\n"); name = "Logitech QuickCam Pro 4000"; type_id = 740; /* CCD sensor */ if (my_power_save == -1) my_power_save = 1; break; case 0x08b3: PWC_INFO("Logitech QuickCam Zoom USB webcam detected.\n"); name = "Logitech QuickCam Zoom"; type_id = 740; /* CCD sensor */ break; case 0x08B4: PWC_INFO("Logitech QuickCam Zoom (new model) USB webcam detected.\n"); name = "Logitech QuickCam Zoom"; type_id = 740; /* CCD sensor */ if (my_power_save == -1) my_power_save = 1; break; case 0x08b5: PWC_INFO("Logitech QuickCam Orbit/Sphere USB webcam detected.\n"); name = "Logitech QuickCam Orbit"; type_id = 740; /* CCD sensor */ if (my_power_save == -1) my_power_save = 1; features |= FEATURE_MOTOR_PANTILT; break; case 0x08b6: PWC_INFO("Logitech/Cisco VT Camera webcam detected.\n"); name = "Cisco VT Camera"; type_id = 740; /* CCD sensor */ break; case 0x08b7: PWC_INFO("Logitech ViewPort AV 100 webcam detected.\n"); name = "Logitech ViewPort AV 100"; type_id = 740; /* CCD sensor */ break; case 0x08b8: /* Where this released? */ PWC_INFO("Logitech QuickCam detected (reserved ID).\n"); name = "Logitech QuickCam (res.)"; type_id = 730; /* Assuming CMOS */ break; default: return -ENODEV; break; } } else if (vendor_id == 0x055d) { /* I don't know the difference between the C10 and the C30; I suppose the difference is the sensor, but both cameras work equally well with a type_id of 675 */ switch(product_id) { case 0x9000: PWC_INFO("Samsung MPC-C10 USB webcam detected.\n"); name = "Samsung MPC-C10"; type_id = 675; break; case 0x9001: PWC_INFO("Samsung MPC-C30 USB webcam detected.\n"); name = "Samsung MPC-C30"; type_id = 675; break; case 0x9002: PWC_INFO("Samsung SNC-35E (v3.0) USB webcam detected.\n"); name = "Samsung MPC-C30"; type_id = 740; break; default: return -ENODEV; break; } } else if (vendor_id == 0x041e) { switch(product_id) { case 0x400c: PWC_INFO("Creative Labs Webcam 5 detected.\n"); name = "Creative Labs Webcam 5"; type_id = 730; if (my_power_save == -1) my_power_save = 1; break; case 0x4011: PWC_INFO("Creative Labs Webcam Pro Ex detected.\n"); name = "Creative Labs Webcam Pro Ex"; type_id = 740; break; default: return -ENODEV; break; } } else if (vendor_id == 0x04cc) { switch(product_id) { case 0x8116: PWC_INFO("Sotec Afina Eye USB webcam detected.\n"); name = "Sotec Afina Eye"; type_id = 730; break; default: return -ENODEV; break; } } else if (vendor_id == 0x06be) { switch(product_id) { case 0x8116: /* This is essentially the same cam as the Sotec Afina Eye */ PWC_INFO("AME Co. Afina Eye USB webcam detected.\n"); name = "AME Co. Afina Eye"; type_id = 750; break; default: return -ENODEV; break; } } else if (vendor_id == 0x0d81) { switch(product_id) { case 0x1900: PWC_INFO("Visionite VCS-UC300 USB webcam detected.\n"); name = "Visionite VCS-UC300"; type_id = 740; /* CCD sensor */ break; case 0x1910: PWC_INFO("Visionite VCS-UM100 USB webcam detected.\n"); name = "Visionite VCS-UM100"; type_id = 730; /* CMOS sensor */ break; default: return -ENODEV; break; } } else return -ENODEV; /* Not any of the know types; but the list keeps growing. */ if (my_power_save == -1) my_power_save = 0; memset(serial_number, 0, 30); usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 29); PWC_DEBUG_PROBE("Device serial number is %s\n", serial_number); if (udev->descriptor.bNumConfigurations > 1) PWC_WARNING("Warning: more than 1 configuration available.\n"); /* Allocate structure, initialize pointers, mutexes, etc. and link it to the usb_device */ pdev = kzalloc(sizeof(struct pwc_device), GFP_KERNEL); if (pdev == NULL) { PWC_ERROR("Oops, could not allocate memory for pwc_device.\n"); return -ENOMEM; } pdev->type = type_id; pdev->features = features; pwc_construct(pdev); /* set min/max sizes correct */ mutex_init(&pdev->v4l2_lock); mutex_init(&pdev->vb_queue_lock); spin_lock_init(&pdev->queued_bufs_lock); INIT_LIST_HEAD(&pdev->queued_bufs); pdev->udev = udev; pdev->power_save = my_power_save; /* Init videobuf2 queue structure */ pdev->vb_queue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; pdev->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; pdev->vb_queue.drv_priv = pdev; pdev->vb_queue.buf_struct_size = sizeof(struct pwc_frame_buf); pdev->vb_queue.ops = &pwc_vb_queue_ops; pdev->vb_queue.mem_ops = &vb2_vmalloc_memops; pdev->vb_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; rc = vb2_queue_init(&pdev->vb_queue); if (rc < 0) { PWC_ERROR("Oops, could not initialize vb2 queue.\n"); goto err_free_mem; } /* Init video_device structure */ pdev->vdev = pwc_template; strcpy(pdev->vdev.name, name); pdev->vdev.queue = &pdev->vb_queue; pdev->vdev.queue->lock = &pdev->vb_queue_lock; video_set_drvdata(&pdev->vdev, pdev); pdev->release = le16_to_cpu(udev->descriptor.bcdDevice); PWC_DEBUG_PROBE("Release: %04x\n", pdev->release); /* Allocate USB command buffers */ pdev->ctrl_buf = kmalloc(sizeof(pdev->cmd_buf), GFP_KERNEL); if (!pdev->ctrl_buf) { PWC_ERROR("Oops, could not allocate memory for pwc_device.\n"); rc = -ENOMEM; goto err_free_mem; } #ifdef CONFIG_USB_PWC_DEBUG /* Query sensor type */ if (pwc_get_cmos_sensor(pdev, &rc) >= 0) { PWC_DEBUG_OPEN("This %s camera is equipped with a %s (%d).\n", pdev->vdev.name, pwc_sensor_type_to_string(rc), rc); } #endif /* Set the leds off */ pwc_set_leds(pdev, 0, 0); /* Setup initial videomode */ rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT, V4L2_PIX_FMT_YUV420, 30, &compression, 1); if (rc) goto err_free_mem; /* Register controls (and read default values from camera */ rc = pwc_init_controls(pdev); if (rc) { PWC_ERROR("Failed to register v4l2 controls (%d).\n", rc); goto err_free_mem; } /* And powerdown the camera until streaming starts */ pwc_camera_power(pdev, 0); /* Register the v4l2_device structure */ pdev->v4l2_dev.release = pwc_video_release; rc = v4l2_device_register(&intf->dev, &pdev->v4l2_dev); if (rc) { PWC_ERROR("Failed to register v4l2-device (%d).\n", rc); goto err_free_controls; } pdev->v4l2_dev.ctrl_handler = &pdev->ctrl_handler; pdev->vdev.v4l2_dev = &pdev->v4l2_dev; pdev->vdev.lock = &pdev->v4l2_lock; rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, -1); if (rc < 0) { PWC_ERROR("Failed to register as video device (%d).\n", rc); goto err_unregister_v4l2_dev; } PWC_INFO("Registered as %s.\n", video_device_node_name(&pdev->vdev)); #ifdef CONFIG_USB_PWC_INPUT_EVDEV /* register webcam snapshot button input device */ pdev->button_dev = input_allocate_device(); if (!pdev->button_dev) { rc = -ENOMEM; goto err_video_unreg; } usb_make_path(udev, pdev->button_phys, sizeof(pdev->button_phys)); strlcat(pdev->button_phys, "/input0", sizeof(pdev->button_phys)); pdev->button_dev->name = "PWC snapshot button"; pdev->button_dev->phys = pdev->button_phys; usb_to_input_id(pdev->udev, &pdev->button_dev->id); pdev->button_dev->dev.parent = &pdev->udev->dev; pdev->button_dev->evbit[0] = BIT_MASK(EV_KEY); pdev->button_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA); rc = input_register_device(pdev->button_dev); if (rc) { input_free_device(pdev->button_dev); pdev->button_dev = NULL; goto err_video_unreg; } #endif return 0; #ifdef CONFIG_USB_PWC_INPUT_EVDEV err_video_unreg: video_unregister_device(&pdev->vdev); #endif err_unregister_v4l2_dev: v4l2_device_unregister(&pdev->v4l2_dev); err_free_controls: v4l2_ctrl_handler_free(&pdev->ctrl_handler); err_free_mem: kfree(pdev->ctrl_buf); kfree(pdev); return rc; }
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; }
int xylonfb_adv7511_register(struct fb_info *fbi) { struct v4l2_subdev *sd; struct i2c_client *client; struct xylonfb_layer_data *ld = fbi->par; struct xylonfb_common_data *cd = ld->xylonfb_cd; struct xylonfb_misc_data *misc_data = cd->xylonfb_misc; int ret; driver_devel("%s\n", __func__); if (xfb_adv7511) return 0; xfb_adv7511 = kzalloc(sizeof(struct xylonfb_adv7511), GFP_KERNEL); if (!xfb_adv7511) { pr_err("xylonfb ADV7511 error allocating data\n"); return -ENOMEM; } strlcpy(xfb_adv7511->v4l2_dev.name, DRIVER_NAME, sizeof(xfb_adv7511->v4l2_dev.name)); ret = v4l2_device_register(NULL, &xfb_adv7511->v4l2_dev); if (ret) { pr_err("xylonfb ADV7511 registering V4L2 device error\n"); return ret; } xfb_adv7511->flags |= ADV7511_FLAG_INIT; xfb_adv7511->v4l2_dev.notify = xylonfb_adv7511_notify; init_completion(&xfb_adv7511->edid_done); xfb_adv7511->var_screeninfo = kzalloc(sizeof(struct fb_var_screeninfo), GFP_KERNEL); xfb_adv7511->monspecs = kzalloc(sizeof(struct fb_monspecs), GFP_KERNEL); xfb_adv7511->xfb_flags = &cd->xylonfb_flags; xfb_adv7511->fbi = fbi; misc_data->var_screeninfo = xfb_adv7511->var_screeninfo; misc_data->monspecs = xfb_adv7511->monspecs; sd = adv7511_subdev(NULL); if (!sd) { pr_err("xylonfb ADV7511 getting V4L2 subdevice error %s\n", ADV7511_NAME); ret = -ENODEV; goto error_subdev; } sd->v4l2_dev = &xfb_adv7511->v4l2_dev; xfb_adv7511->sd = sd; client = v4l2_get_subdevdata(sd); if (!client) { pr_err("xylonfb ADV7511 getting V4L2 subdevice client error\n"); ret = -ENODEV; goto error_subdev; } xfb_adv7511->irq_work_queue = create_singlethread_workqueue(ADV7511_NAME); if (xfb_adv7511->irq_work_queue == NULL) { pr_err("xylonfb ADV7511 workqueue error\n"); goto error_subdev; } INIT_WORK(&xfb_adv7511->irq_work, xylonfb_adv7511_handler); if (client->irq > 0) { ret = request_irq(client->irq, xylonfb_adv7511_isr, IRQF_TRIGGER_RISING, ADV7511_NAME, xfb_adv7511); if (ret) { pr_err("xylonfb ADV7511 registering interrupt error %d at %d\n", ret, client->irq); goto error_irq; } } else { pr_err("xylonfb ADV7511 error no IRQ registered\n"); } sd->ops->core->interrupt_service_routine(sd, 0, NULL); if (xfb_adv7511->timeout) { ret = wait_for_completion_timeout(&xfb_adv7511->edid_done, xfb_adv7511->timeout); } else { ret = 0; } xfb_adv7511->flags &= ~ADV7511_FLAG_INIT; if (ret == 0) { if (xfb_adv7511->timeout) { pr_err("xylonfb ADV7511 EDID error\n"); return -ETIMEDOUT; } else { return -ENODEV; } } return 0; error_irq: flush_work(&xfb_adv7511->irq_work); flush_workqueue(xfb_adv7511->irq_work_queue); destroy_workqueue(xfb_adv7511->irq_work_queue); error_subdev: v4l2_device_unregister(&xfb_adv7511->v4l2_dev); kfree(xfb_adv7511); 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 __devinit fimc_md_probe(struct platform_device *pdev) { struct v4l2_device *v4l2_dev; struct fimc_md *fmd; int ret; fmd = devm_kzalloc(&pdev->dev, sizeof(*fmd), GFP_KERNEL); if (!fmd) return -ENOMEM; spin_lock_init(&fmd->slock); fmd->pdev = pdev; strlcpy(fmd->media_dev.model, "SAMSUNG S5P FIMC", sizeof(fmd->media_dev.model)); fmd->media_dev.link_notify = fimc_md_link_notify; fmd->media_dev.dev = &pdev->dev; v4l2_dev = &fmd->v4l2_dev; v4l2_dev->mdev = &fmd->media_dev; v4l2_dev->notify = fimc_sensor_notify; snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s", dev_name(&pdev->dev)); ret = v4l2_device_register(&pdev->dev, &fmd->v4l2_dev); if (ret < 0) { v4l2_err(v4l2_dev, "Failed to register v4l2_device: %d\n", ret); return ret; } ret = media_device_register(&fmd->media_dev); if (ret < 0) { v4l2_err(v4l2_dev, "Failed to register media device: %d\n", ret); goto err2; } ret = fimc_md_get_clocks(fmd); if (ret) goto err3; fmd->user_subdev_api = false; ret = fimc_md_register_platform_entities(fmd); if (ret) goto err3; if (pdev->dev.platform_data) { ret = fimc_md_register_sensor_entities(fmd); if (ret) goto err3; } ret = fimc_md_create_links(fmd); if (ret) goto err3; ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev); if (ret) goto err3; ret = fimc_md_register_video_nodes(fmd); if (ret) goto err3; ret = device_create_file(&pdev->dev, &dev_attr_subdev_conf_mode); if (!ret) { platform_set_drvdata(pdev, fmd); return 0; } err3: media_device_unregister(&fmd->media_dev); fimc_md_put_clocks(fmd); fimc_md_unregister_entities(fmd); err2: v4l2_device_unregister(&fmd->v4l2_dev); return ret; }
static int unicam_register_entities(struct unicam_device *unicam) { struct unicam_platform_data *pdata = unicam->pdata; struct unicam_v4l2_subdevs_groups *subdevs; int ret, i; /* media device registration */ unicam->media_dev.dev = unicam->dev; strlcpy(unicam->media_dev.model, "Broadcom Kona Unicam", sizeof(unicam->media_dev.model)); unicam->media_dev.hw_revision = unicam->revision; unicam->media_dev.link_notify = unicam_pipeline_link_notify; ret = media_device_register(&unicam->media_dev); if (ret < 0) { dev_err(unicam->dev, "media device registration failed (%d)\n", ret); return ret; } /* v4l2 device registration */ unicam->v4l2_dev.mdev = &unicam->media_dev; ret = v4l2_device_register(unicam->dev, &unicam->v4l2_dev); if (ret < 0) { dev_err(unicam->dev, "V4L2 device registration failed (%d)\n", ret); goto done; } /* now register all enitites */ ret = kona_unicam_csi2_register_entities(&unicam->csi2a, &unicam->v4l2_dev); if (ret < 0) { dev_err(unicam->dev, "failed to register csi2a entities (%d)\n", ret); goto done; } /* now register external entities */ for (i = 0; i < pdata->num_subdevs; i++) { struct v4l2_subdev *sensor; struct media_entity *input; unsigned int pad; subdevs = &pdata->subdevs[i]; sensor = unicam_register_subdev_group(unicam, subdevs->i2c_info); if (sensor == NULL) continue; sensor->host_priv = subdevs; /* * connect the sensor to the correct interface module. * we only have one receiver here */ switch (subdevs->interface) { case UNICAM_INTERFACE_CSI2_PHY1: input = &unicam->csi2a.subdev.entity; pad = CSI2_PAD_SINK; break; default: dev_err(unicam->dev, "invalid interface type %u\n", subdevs->interface); goto done; } ret = media_entity_create_link(&sensor->entity, 0, input, pad, 0); if (ret < 0) goto done; }; ret = v4l2_device_register_subdev_nodes(&unicam->v4l2_dev); done: if (ret < 0) unicam_unregister_entities(unicam); return ret; }
static int bdisp_probe(struct platform_device *pdev) { struct bdisp_dev *bdisp; struct resource *res; struct device *dev = &pdev->dev; int ret; dev_dbg(dev, "%s\n", __func__); bdisp = devm_kzalloc(dev, sizeof(struct bdisp_dev), GFP_KERNEL); if (!bdisp) return -ENOMEM; bdisp->pdev = pdev; bdisp->dev = dev; platform_set_drvdata(pdev, bdisp); if (dev->of_node) bdisp->id = of_alias_get_id(pdev->dev.of_node, BDISP_NAME); else bdisp->id = pdev->id; init_waitqueue_head(&bdisp->irq_queue); INIT_DELAYED_WORK(&bdisp->timeout_work, bdisp_irq_timeout); bdisp->work_queue = create_workqueue(BDISP_NAME); spin_lock_init(&bdisp->slock); mutex_init(&bdisp->lock); /* get resources */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); bdisp->regs = devm_ioremap_resource(dev, res); if (IS_ERR(bdisp->regs)) { dev_err(dev, "failed to get regs\n"); return PTR_ERR(bdisp->regs); } bdisp->clock = devm_clk_get(dev, BDISP_NAME); if (IS_ERR(bdisp->clock)) { dev_err(dev, "failed to get clock\n"); return PTR_ERR(bdisp->clock); } ret = clk_prepare(bdisp->clock); if (ret < 0) { dev_err(dev, "clock prepare failed\n"); bdisp->clock = ERR_PTR(-EINVAL); return ret; } res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { dev_err(dev, "failed to get IRQ resource\n"); goto err_clk; } ret = devm_request_threaded_irq(dev, res->start, bdisp_irq_handler, bdisp_irq_thread, IRQF_ONESHOT, pdev->name, bdisp); if (ret) { dev_err(dev, "failed to install irq\n"); goto err_clk; } /* v4l2 register */ ret = v4l2_device_register(dev, &bdisp->v4l2_dev); if (ret) { dev_err(dev, "failed to register\n"); goto err_clk; } /* Debug */ ret = bdisp_debugfs_create(bdisp); if (ret) { dev_err(dev, "failed to create debugfs\n"); goto err_v4l2; } /* Power management */ pm_runtime_enable(dev); ret = pm_runtime_get_sync(dev); if (ret < 0) { dev_err(dev, "failed to set PM\n"); goto err_dbg; } /* Filters */ if (bdisp_hw_alloc_filters(bdisp->dev)) { dev_err(bdisp->dev, "no memory for filters\n"); ret = -ENOMEM; goto err_pm; } /* Register */ ret = bdisp_register_device(bdisp); if (ret) { dev_err(dev, "failed to register\n"); goto err_filter; } dev_info(dev, "%s%d registered as /dev/video%d\n", BDISP_NAME, bdisp->id, bdisp->vdev.num); pm_runtime_put(dev); return 0; err_filter: bdisp_hw_free_filters(bdisp->dev); err_pm: pm_runtime_put(dev); err_dbg: bdisp_debugfs_remove(bdisp); err_v4l2: v4l2_device_unregister(&bdisp->v4l2_dev); err_clk: if (!IS_ERR(bdisp->clock)) clk_unprepare(bdisp->clock); 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; }
static int __devinit cx18_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id) { int retval = 0; int i; u32 devtype; struct cx18 *cx; /* FIXME - module parameter arrays constrain max instances */ i = atomic_inc_return(&cx18_instance) - 1; if (i >= CX18_MAX_CARDS) { printk(KERN_ERR "cx18: cannot manage card %d, driver has a " "limit of 0 - %d\n", i, CX18_MAX_CARDS - 1); return -ENOMEM; } cx = kzalloc(sizeof(struct cx18), GFP_ATOMIC); if (cx == NULL) { printk(KERN_ERR "cx18: cannot manage card %d, out of memory\n", i); return -ENOMEM; } cx->pci_dev = pci_dev; cx->instance = i; retval = v4l2_device_register(&pci_dev->dev, &cx->v4l2_dev); if (retval) { printk(KERN_ERR "cx18: v4l2_device_register of card %d failed" "\n", cx->instance); kfree(cx); return retval; } snprintf(cx->v4l2_dev.name, sizeof(cx->v4l2_dev.name), "cx18-%d", cx->instance); CX18_INFO("Initializing card %d\n", cx->instance); cx18_process_options(cx); if (cx->options.cardtype == -1) { retval = -ENODEV; goto err; } retval = cx18_init_struct1(cx); if (retval) goto err; CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr); /* PCI Device Setup */ retval = cx18_setup_pci(cx, pci_dev, pci_id); if (retval != 0) goto free_workqueues; /* map io memory */ CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE); cx->enc_mem = ioremap_nocache(cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE); if (!cx->enc_mem) { CX18_ERR("ioremap failed. Can't get a window into CX23418 " "memory and register space\n"); CX18_ERR("Each capture card with a CX23418 needs 64 MB of " "vmalloc address space for the window\n"); CX18_ERR("Check the output of 'grep Vmalloc /proc/meminfo'\n"); CX18_ERR("Use the vmalloc= kernel command line option to set " "VmallocTotal to a larger value\n"); retval = -ENOMEM; goto free_mem; } cx->reg_mem = cx->enc_mem + CX18_REG_OFFSET; devtype = cx18_read_reg(cx, 0xC72028); switch (devtype & 0xff000000) { case 0xff000000: CX18_INFO("cx23418 revision %08x (A)\n", devtype); break; case 0x01000000: CX18_INFO("cx23418 revision %08x (B)\n", devtype); break; default: CX18_INFO("cx23418 revision %08x (Unknown)\n", devtype); break; } cx18_init_power(cx, 1); cx18_init_memory(cx); cx->scb = (struct cx18_scb __iomem *)(cx->enc_mem + SCB_OFFSET); cx18_init_scb(cx); cx18_gpio_init(cx); /* Initialize integrated A/V decoder early to set PLLs, just in case */ retval = cx18_av_probe(cx); if (retval) { CX18_ERR("Could not register A/V decoder subdevice\n"); goto free_map; } /* Initialize GPIO Reset Controller to do chip resets during i2c init */ if (cx->card->hw_all & CX18_HW_GPIO_RESET_CTRL) { if (cx18_gpio_register(cx, CX18_HW_GPIO_RESET_CTRL) != 0) CX18_WARN("Could not register GPIO reset controller" "subdevice; proceeding anyway.\n"); else cx->hw_flags |= CX18_HW_GPIO_RESET_CTRL; } /* active i2c */ CX18_DEBUG_INFO("activating i2c...\n"); retval = init_cx18_i2c(cx); if (retval) { CX18_ERR("Could not initialize i2c\n"); goto free_map; } if (cx->card->hw_all & CX18_HW_TVEEPROM) { /* Based on the model number the cardtype may be changed. The PCI IDs are not always reliable. */ const struct cx18_card *orig_card = cx->card; cx18_process_eeprom(cx); if (cx->card != orig_card) { /* Changed the cardtype; re-reset the I2C chips */ cx18_gpio_init(cx); cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL, core, reset, (u32) CX18_GPIO_RESET_I2C); } } if (cx->card->comment) CX18_INFO("%s", cx->card->comment); if (cx->card->v4l2_capabilities == 0) { retval = -ENODEV; goto free_i2c; } cx18_init_memory(cx); cx18_init_scb(cx); /* Register IRQ */ retval = request_irq(cx->pci_dev->irq, cx18_irq_handler, IRQF_SHARED | IRQF_DISABLED, cx->v4l2_dev.name, (void *)cx); if (retval) { CX18_ERR("Failed to register irq %d\n", retval); goto free_i2c; } if (cx->std == 0) cx->std = V4L2_STD_NTSC_M; if (cx->options.tuner == -1) { for (i = 0; i < CX18_CARD_MAX_TUNERS; i++) { if ((cx->std & cx->card->tuners[i].std) == 0) continue; cx->options.tuner = cx->card->tuners[i].tuner; break; } } /* if no tuner was found, then pick the first tuner in the card list */ if (cx->options.tuner == -1 && cx->card->tuners[0].std) { cx->std = cx->card->tuners[0].std; if (cx->std & V4L2_STD_PAL) cx->std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H; else if (cx->std & V4L2_STD_NTSC) cx->std = V4L2_STD_NTSC_M; else if (cx->std & V4L2_STD_SECAM) cx->std = V4L2_STD_SECAM_L; cx->options.tuner = cx->card->tuners[0].tuner; } if (cx->options.radio == -1) cx->options.radio = (cx->card->radio_input.audio_type != 0); /* The card is now fully identified, continue with card-specific initialization. */ cx18_init_struct2(cx); cx18_init_subdevs(cx); if (cx->std & V4L2_STD_525_60) cx->is_60hz = 1; else cx->is_50hz = 1; cx2341x_handler_set_50hz(&cx->cxhdl, !cx->is_60hz); if (cx->options.radio > 0) cx->v4l2_cap |= V4L2_CAP_RADIO; if (cx->options.tuner > -1) { struct tuner_setup setup; setup.addr = ADDR_UNSET; setup.type = cx->options.tuner; setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */ setup.tuner_callback = (setup.type == TUNER_XC2028) ? cx18_reset_tuner_gpio : NULL; cx18_call_all(cx, tuner, s_type_addr, &setup); if (setup.type == TUNER_XC2028) { static struct xc2028_ctrl ctrl = { .fname = XC2028_DEFAULT_FIRMWARE, .max_len = 64, }; struct v4l2_priv_tun_config cfg = { .tuner = cx->options.tuner, .priv = &ctrl, }; cx18_call_all(cx, tuner, s_config, &cfg); } } /* The tuner is fixed to the standard. The other inputs (e.g. S-Video) are not. */ cx->tuner_std = cx->std; if (cx->std == V4L2_STD_ALL) cx->std = V4L2_STD_NTSC_M; retval = cx18_streams_setup(cx); if (retval) { CX18_ERR("Error %d setting up streams\n", retval); goto free_irq; } retval = cx18_streams_register(cx); if (retval) { CX18_ERR("Error %d registering devices\n", retval); goto free_streams; } CX18_INFO("Initialized card: %s\n", cx->card_name); /* Load cx18 submodules (cx18-alsa) */ request_modules(cx); return 0; free_streams: cx18_streams_cleanup(cx, 1); free_irq: free_irq(cx->pci_dev->irq, (void *)cx); free_i2c: exit_cx18_i2c(cx); free_map: cx18_iounmap(cx); free_mem: release_mem_region(cx->base_addr, CX18_MEM_SIZE); free_workqueues: destroy_workqueue(cx->in_work_queue); err: if (retval == 0) retval = -ENODEV; CX18_ERR("Error %d on initialization\n", retval); v4l2_device_unregister(&cx->v4l2_dev); kfree(cx); return retval; } int cx18_init_on_first_open(struct cx18 *cx) { int video_input; int fw_retry_count = 3; struct v4l2_frequency vf; struct cx18_open_id fh; v4l2_std_id std; fh.cx = cx; if (test_bit(CX18_F_I_FAILED, &cx->i_flags)) return -ENXIO; if (test_and_set_bit(CX18_F_I_INITED, &cx->i_flags)) return 0; while (--fw_retry_count > 0) { /* load firmware */ if (cx18_firmware_init(cx) == 0) break; if (fw_retry_count > 1) CX18_WARN("Retry loading firmware\n"); } if (fw_retry_count == 0) { set_bit(CX18_F_I_FAILED, &cx->i_flags); return -ENXIO; } set_bit(CX18_F_I_LOADED_FW, &cx->i_flags); /* * Init the firmware twice to work around a silicon bug * with the digital TS. * * The second firmware load requires us to normalize the APU state, * or the audio for the first analog capture will be badly incorrect. * * I can't seem to call APU_RESETAI and have it succeed without the * APU capturing audio, so we start and stop it here to do the reset */ /* MPEG Encoding, 224 kbps, MPEG Layer II, 48 ksps */ cx18_vapi(cx, CX18_APU_START, 2, CX18_APU_ENCODING_METHOD_MPEG|0xb9, 0); cx18_vapi(cx, CX18_APU_RESETAI, 0); cx18_vapi(cx, CX18_APU_STOP, 1, CX18_APU_ENCODING_METHOD_MPEG); fw_retry_count = 3; while (--fw_retry_count > 0) { /* load firmware */ if (cx18_firmware_init(cx) == 0) break; if (fw_retry_count > 1) CX18_WARN("Retry loading firmware\n"); } if (fw_retry_count == 0) { set_bit(CX18_F_I_FAILED, &cx->i_flags); return -ENXIO; } /* * The second firmware load requires us to normalize the APU state, * or the audio for the first analog capture will be badly incorrect. * * I can't seem to call APU_RESETAI and have it succeed without the * APU capturing audio, so we start and stop it here to do the reset */ /* MPEG Encoding, 224 kbps, MPEG Layer II, 48 ksps */ cx18_vapi(cx, CX18_APU_START, 2, CX18_APU_ENCODING_METHOD_MPEG|0xb9, 0); cx18_vapi(cx, CX18_APU_RESETAI, 0); cx18_vapi(cx, CX18_APU_STOP, 1, CX18_APU_ENCODING_METHOD_MPEG); /* Init the A/V decoder, if it hasn't been already */ v4l2_subdev_call(cx->sd_av, core, load_fw); vf.tuner = 0; vf.type = V4L2_TUNER_ANALOG_TV; vf.frequency = 6400; /* the tuner 'baseline' frequency */ /* Set initial frequency. For PAL/SECAM broadcasts no 'default' channel exists AFAIK. */ if (cx->std == V4L2_STD_NTSC_M_JP) vf.frequency = 1460; /* ch. 1 91250*16/1000 */ else if (cx->std & V4L2_STD_NTSC_M) vf.frequency = 1076; /* ch. 4 67250*16/1000 */ video_input = cx->active_input; cx->active_input++; /* Force update of input */ cx18_s_input(NULL, &fh, video_input); /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code in one place. */ cx->std++; /* Force full standard initialization */ std = (cx->tuner_std == V4L2_STD_ALL) ? V4L2_STD_NTSC_M : cx->tuner_std; cx18_s_std(NULL, &fh, &std); cx18_s_frequency(NULL, &fh, &vf); return 0; } static void cx18_cancel_in_work_orders(struct cx18 *cx) { int i; for (i = 0; i < CX18_MAX_IN_WORK_ORDERS; i++) cancel_work_sync(&cx->in_work_order[i].work); }
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 atomisp_register_entities(struct atomisp_device *isp) { int ret = 0; int i = 0; struct v4l2_subdev *subdev = NULL; struct media_entity *input = NULL; unsigned int flags; unsigned int pad; isp->media_dev.dev = isp->dev; strlcpy(isp->media_dev.model, "Intel Atom ISP", sizeof(isp->media_dev.model)); ret = media_device_register(&isp->media_dev); if (ret < 0) { v4l2_err(&atomisp_dev, "%s: Media device registration " "failed (%d)\n", __func__, ret); return ret; } isp->v4l2_dev.mdev = &isp->media_dev; ret = v4l2_device_register(isp->dev, &isp->v4l2_dev); if (ret < 0) { v4l2_err(&atomisp_dev, "%s: V4L2 device registration failed (%d)\n", __func__, ret); goto v4l2_device_failed; } /* * fixing me! * not sub device exists on * mrfld vp */ if (!IS_MRFLD) { ret = atomisp_subdev_probe(isp); if (ret < 0) goto lane4_and_subdev_probe_failed; } /* Register internal entities */ ret = atomisp_mipi_csi2_register_entities(&isp->csi2_4p, &isp->v4l2_dev); if (ret < 0) { v4l2_err(&atomisp_dev, "atomisp_mipi_csi2_register_entities 4p\n"); goto lane4_and_subdev_probe_failed; } ret = atomisp_mipi_csi2_register_entities(&isp->csi2_1p, &isp->v4l2_dev); if (ret < 0) { v4l2_err(&atomisp_dev, "atomisp_mipi_csi2_register_entities 1p\n"); goto lane1_failed; } ret = atomisp_file_input_register_entities(&isp->file_dev, &isp->v4l2_dev); if (ret < 0) { v4l2_err(&atomisp_dev, "atomisp_file_input_register_entities\n"); goto file_input_register_failed; } ret = atomisp_tpg_register_entities(&isp->tpg, &isp->v4l2_dev); if (ret < 0) { v4l2_err(&atomisp_dev, "atomisp_tpg_register_entities\n"); goto tpg_register_failed; } ret = atomisp_subdev_register_entities(&isp->isp_subdev, &isp->v4l2_dev); if (ret < 0) { v4l2_err(&atomisp_dev, "atomisp_subdev_register_entities fail\n"); goto subdev_register_failed; } for (i = 0; i < isp->input_cnt; i++) { subdev = isp->inputs[i].camera; switch (isp->inputs[i].port) { case ATOMISP_CAMERA_PORT_PRIMARY: input = &isp->csi2_4p.subdev.entity; pad = CSI2_PAD_SINK; flags = 0; break; case ATOMISP_CAMERA_PORT_SECONDARY: input = &isp->csi2_1p.subdev.entity; pad = CSI2_PAD_SINK; flags = 0; break; default: v4l2_dbg(1, dbg_level, &atomisp_dev, "isp->inputs type not supported\n"); break; } ret = media_entity_create_link(&subdev->entity, 0, input, pad, flags); if (ret < 0) { v4l2_err(&atomisp_dev, "snr to mipi csi link failed\n"); goto link_failed; } } v4l2_dbg(1, dbg_level, &atomisp_dev, "FILE_INPUT enable, camera_cnt: %d\n", isp->input_cnt); isp->inputs[isp->input_cnt].type = FILE_INPUT; isp->inputs[isp->input_cnt].port = -1; isp->inputs[isp->input_cnt].shading_table = NULL; isp->inputs[isp->input_cnt].morph_table = NULL; isp->inputs[isp->input_cnt++].camera = &isp->file_dev.sd; if (isp->input_cnt < ATOM_ISP_MAX_INPUTS) { v4l2_dbg(1, dbg_level, &atomisp_dev, "TPG detected, camera_cnt: %d\n", isp->input_cnt); isp->inputs[isp->input_cnt].type = TEST_PATTERN; isp->inputs[isp->input_cnt].port = -1; isp->inputs[isp->input_cnt].shading_table = NULL; isp->inputs[isp->input_cnt].morph_table = NULL; isp->inputs[isp->input_cnt++].camera = &isp->tpg.sd; } else { v4l2_warn(&atomisp_dev, "too many atomisp inputs, TPG ignored.\n"); } ret = v4l2_device_register_subdev_nodes(&isp->v4l2_dev); if (ret < 0) goto link_failed; return ret; link_failed: atomisp_subdev_unregister_entities(&isp->isp_subdev); subdev_register_failed: atomisp_tpg_unregister_entities(&isp->tpg); tpg_register_failed: atomisp_file_input_unregister_entities(&isp->file_dev); file_input_register_failed: atomisp_mipi_csi2_unregister_entities(&isp->csi2_1p); lane1_failed: atomisp_mipi_csi2_unregister_entities(&isp->csi2_4p); lane4_and_subdev_probe_failed: v4l2_device_unregister(&isp->v4l2_dev); v4l2_device_failed: media_device_unregister(&isp->media_dev); return ret; }
static int tw68_initdev(struct pci_dev *pci_dev, const struct pci_device_id *pci_id) { struct tw68_dev *dev; int vidnr = -1; int err; dev = devm_kzalloc(&pci_dev->dev, sizeof(*dev), GFP_KERNEL); if (NULL == dev) return -ENOMEM; dev->instance = v4l2_device_set_name(&dev->v4l2_dev, "tw68", &tw68_instance); err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev); if (err) return err; /* pci init */ dev->pci = pci_dev; if (pci_enable_device(pci_dev)) { err = -EIO; goto fail1; } dev->name = dev->v4l2_dev.name; if (UNSET != latency) { pr_info("%s: setting pci latency timer to %d\n", dev->name, latency); pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, latency); } /* print pci info */ pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); pr_info("%s: found at %s, rev: %d, irq: %d, latency: %d, mmio: 0x%llx\n", dev->name, pci_name(pci_dev), dev->pci_rev, pci_dev->irq, dev->pci_lat, (u64)pci_resource_start(pci_dev, 0)); pci_set_master(pci_dev); if (!pci_dma_supported(pci_dev, DMA_BIT_MASK(32))) { pr_info("%s: Oops: no 32bit PCI DMA ???\n", dev->name); err = -EIO; goto fail1; } switch (pci_id->device) { case PCI_DEVICE_ID_6800: /* TW6800 */ dev->vdecoder = TW6800; dev->board_virqmask = TW68_VID_INTS; break; case PCI_DEVICE_ID_6801: /* Video decoder for TW6802 */ dev->vdecoder = TW6801; dev->board_virqmask = TW68_VID_INTS | TW68_VID_INTSX; break; case PCI_DEVICE_ID_6804: /* Video decoder for TW6804 */ dev->vdecoder = TW6804; dev->board_virqmask = TW68_VID_INTS | TW68_VID_INTSX; break; default: dev->vdecoder = TWXXXX; /* To be announced */ dev->board_virqmask = TW68_VID_INTS | TW68_VID_INTSX; break; } /* get mmio */ if (!request_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0), dev->name)) { err = -EBUSY; pr_err("%s: can't get MMIO memory @ 0x%llx\n", dev->name, (unsigned long long)pci_resource_start(pci_dev, 0)); goto fail1; } dev->lmmio = ioremap(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0)); dev->bmmio = (__u8 __iomem *)dev->lmmio; if (NULL == dev->lmmio) { err = -EIO; pr_err("%s: can't ioremap() MMIO memory\n", dev->name); goto fail2; } /* initialize hardware #1 */ /* Then do any initialisation wanted before interrupts are on */ tw68_hw_init1(dev); dev->alloc_ctx = vb2_dma_sg_init_ctx(&pci_dev->dev); if (IS_ERR(dev->alloc_ctx)) { err = PTR_ERR(dev->alloc_ctx); goto fail3; } /* get irq */ err = devm_request_irq(&pci_dev->dev, pci_dev->irq, tw68_irq, IRQF_SHARED, dev->name, dev); if (err < 0) { pr_err("%s: can't get IRQ %d\n", dev->name, pci_dev->irq); goto fail4; } /* * Now do remainder of initialisation, first for * things unique for this card, then for general board */ if (dev->instance < TW68_MAXBOARDS) vidnr = video_nr[dev->instance]; /* initialise video function first */ err = tw68_video_init2(dev, vidnr); if (err < 0) { pr_err("%s: can't register video device\n", dev->name); goto fail5; } tw_setl(TW68_INTMASK, dev->pci_irqmask); pr_info("%s: registered device %s\n", dev->name, video_device_node_name(&dev->vdev)); return 0; fail5: video_unregister_device(&dev->vdev); fail4: vb2_dma_sg_cleanup_ctx(dev->alloc_ctx); fail3: iounmap(dev->lmmio); fail2: release_mem_region(pci_resource_start(pci_dev, 0), pci_resource_len(pci_dev, 0)); fail1: v4l2_device_unregister(&dev->v4l2_dev); return err; }
/* * 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; }