示例#1
0
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
示例#3
0
/*
 * 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;
}
示例#4
0
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;
}
示例#5
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;
}
示例#6
0
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;
}
示例#8
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;
}
示例#10
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;
}
示例#11
0
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;
}
示例#12
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;
}
示例#13
0
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;
}
示例#14
0
/* 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;
}
示例#15
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;
}
示例#17
0
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;
}
示例#18
0
文件: pwc-if.c 项目: AK101111/linux
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;
}
示例#19
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;
}
示例#20
0
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;
}
示例#23
0
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;
}
示例#24
0
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;
}
示例#26
0
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);
}
示例#27
0
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;
}
示例#29
0
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;
}
示例#30
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;
	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;
}