Exemplo n.º 1
0
/*
 * fd_probe - Fd device probe method.
 * @pdev: Pointer fd platform device.
 */
static int fd_probe(struct platform_device *pdev)
{
	struct msm_fd_device *fd;
	int ret;

	/* Face detection device struct */
	fd = kzalloc(sizeof(struct msm_fd_device), GFP_KERNEL);
	if (!fd)
		return -ENOMEM;

	mutex_init(&fd->lock);
	spin_lock_init(&fd->slock);
	fd->dev = &pdev->dev;

	/* Get resources */
	ret = msm_fd_hw_get_mem_resources(pdev, fd);
	if (ret < 0) {
		dev_err(&pdev->dev, "Fail get resources\n");
		ret = -ENODEV;
		goto error_mem_resources;
	}

	fd->vdd = regulator_get(&pdev->dev, "vdd");
	if (IS_ERR(fd->vdd)) {
		dev_err(&pdev->dev, "Fail to get vdd regulator\n");
		ret = -ENODEV;
		goto error_get_regulator;
	}

	ret = msm_fd_hw_get_clocks(fd);
	if (ret < 0) {
		dev_err(&pdev->dev, "Fail to get clocks\n");
		goto error_get_clocks;
	}

	ret = msm_fd_hw_get_iommu(fd);
	if (ret < 0) {
		dev_err(&pdev->dev, "Fail to get iommu\n");
		goto error_iommu_get;
	}

	fd->irq_num = platform_get_irq(pdev, 0);
	if (fd->irq_num < 0) {
		dev_err(&pdev->dev, "Can not get fd irq resource\n");
		ret = -ENODEV;
		goto error_irq_request;
	}

	ret = devm_request_irq(&pdev->dev, fd->irq_num, msm_fd_irq,
		IRQF_TRIGGER_RISING, dev_name(&pdev->dev), fd);
	if (ret) {
		dev_err(&pdev->dev, "Can not claim IRQ %d\n", fd->irq_num);
		goto error_irq_request;
	}

	fd->work_queue = alloc_workqueue(MSM_FD_DRV_NAME,
		WQ_HIGHPRI | WQ_NON_REENTRANT | WQ_UNBOUND, 0);
	if (!fd->work_queue) {
		dev_err(&pdev->dev, "Can not register workqueue\n");
		ret = -ENOMEM;
		goto error_alloc_workqueue;
	}
	INIT_WORK(&fd->work, msm_fd_wq_handler);
	INIT_LIST_HEAD(&fd->buf_queue);

	/* v4l2 device */
	ret = v4l2_device_register(&pdev->dev, &fd->v4l2_dev);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to register v4l2 device\n");
		ret = -ENOENT;
		goto error_v4l2_register;
	}

	fd->video.fops  = &fd_fops;
	fd->video.ioctl_ops = &fd_ioctl_ops;
	fd->video.minor = -1;
	fd->video.release  = video_device_release;
	fd->video.v4l2_dev = &fd->v4l2_dev;
	fd->video.vfl_dir = VFL_DIR_TX;
	fd->video.vfl_type = VFL_TYPE_GRABBER;
	strlcpy(fd->video.name, MSM_FD_DRV_NAME, sizeof(fd->video.name));

	ret = video_register_device(&fd->video, VFL_TYPE_GRABBER, -1);
	if (ret < 0) {
		v4l2_err(&fd->v4l2_dev, "Failed to register video device\n");
		goto error_video_register;
	}

	video_set_drvdata(&fd->video, fd);

	platform_set_drvdata(pdev, fd);

	return 0;

error_video_register:
	v4l2_device_unregister(&fd->v4l2_dev);
error_v4l2_register:
	destroy_workqueue(fd->work_queue);
error_alloc_workqueue:
	devm_free_irq(&pdev->dev, fd->irq_num, fd);
error_irq_request:
	msm_fd_hw_put_iommu(fd);
error_iommu_get:
	msm_fd_hw_put_clocks(fd);
error_get_clocks:
	regulator_put(fd->vdd);
error_get_regulator:
	msm_fd_hw_release_mem_resources(fd);
error_mem_resources:
	kfree(fd);
	return ret;
}
Exemplo n.º 2
0
Arquivo: dt3155.c Projeto: Lyude/linux
static int dt3155_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
	int err;
	struct dt3155_priv *pd;

	err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
	if (err)
		return -ENODEV;
	pd = devm_kzalloc(&pdev->dev, sizeof(*pd), GFP_KERNEL);
	if (!pd)
		return -ENOMEM;

	err = v4l2_device_register(&pdev->dev, &pd->v4l2_dev);
	if (err)
		return err;
	pd->vdev = dt3155_vdev;
	pd->vdev.v4l2_dev = &pd->v4l2_dev;
	video_set_drvdata(&pd->vdev, pd);  /* for use in video_fops */
	pd->pdev = pdev;
	pd->std = V4L2_STD_625_50;
	pd->csr2 = VT_50HZ;
	pd->width = 768;
	pd->height = 576;
	INIT_LIST_HEAD(&pd->dmaq);
	mutex_init(&pd->mux);
	pd->vdev.lock = &pd->mux; /* for locking v4l2_file_operations */
	pd->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	pd->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
	pd->vidq.io_modes = VB2_MMAP | VB2_DMABUF | VB2_READ;
	pd->vidq.ops = &q_ops;
	pd->vidq.mem_ops = &vb2_dma_contig_memops;
	pd->vidq.drv_priv = pd;
	pd->vidq.min_buffers_needed = 2;
	pd->vidq.gfp_flags = GFP_DMA32;
	pd->vidq.lock = &pd->mux; /* for locking v4l2_file_operations */
	pd->vidq.dev = &pdev->dev;
	pd->vdev.queue = &pd->vidq;
	err = vb2_queue_init(&pd->vidq);
	if (err < 0)
		goto err_v4l2_dev_unreg;
	spin_lock_init(&pd->lock);
	pd->config = ACQ_MODE_EVEN;
	err = pci_enable_device(pdev);
	if (err)
		goto err_v4l2_dev_unreg;
	err = pci_request_region(pdev, 0, pci_name(pdev));
	if (err)
		goto err_pci_disable;
	pd->regs = pci_iomap(pdev, 0, pci_resource_len(pd->pdev, 0));
	if (!pd->regs) {
		err = -ENOMEM;
		goto err_free_reg;
	}
	err = dt3155_init_board(pd);
	if (err)
		goto err_iounmap;
	err = request_irq(pd->pdev->irq, dt3155_irq_handler_even,
					IRQF_SHARED, DT3155_NAME, pd);
	if (err)
		goto err_iounmap;
	err = video_register_device(&pd->vdev, VFL_TYPE_GRABBER, -1);
	if (err)
		goto err_free_irq;
	dev_info(&pdev->dev, "/dev/video%i is ready\n", pd->vdev.minor);
	return 0;  /*   success   */

err_free_irq:
	free_irq(pd->pdev->irq, pd);
err_iounmap:
	pci_iounmap(pdev, pd->regs);
err_free_reg:
	pci_release_region(pdev, 0);
err_pci_disable:
	pci_disable_device(pdev);
err_v4l2_dev_unreg:
	v4l2_device_unregister(&pd->v4l2_dev);
	return err;
}
Exemplo n.º 3
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_TECHWELL_6800:	/* TW6800 */
		dev->vdecoder = TW6800;
		dev->board_virqmask = TW68_VID_INTS;
		break;
	case PCI_DEVICE_ID_TECHWELL_6801:	/* Video decoder for TW6802 */
		dev->vdecoder = TW6801;
		dev->board_virqmask = TW68_VID_INTS | TW68_VID_INTSX;
		break;
	case PCI_DEVICE_ID_TECHWELL_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;
}
Exemplo n.º 4
0
static int jpeg_probe(struct platform_device *pdev)
{
	struct jpeg_dev *dev;
	struct video_device *vfd;
	struct resource *res;
	int ret;

	/* global structure */
	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	if (!dev) {
		dev_err(&pdev->dev, "%s: not enough memory\n",
			__func__);
		ret = -ENOMEM;
		goto err_alloc;
	}

	dev->plat_dev = pdev;

	/* setup jpeg control */
	ret = jpeg_setup_controller(dev);
	if (ret) {
		jpeg_err("failed to setup controller\n");
		goto err_setup;
	}

	/* memory region */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		jpeg_err("failed to get jpeg memory region resource\n");
		ret = -ENOENT;
		goto err_res;
	}

	res = request_mem_region(res->start, resource_size(res),
				pdev->name);
	if (!res) {
		jpeg_err("failed to request jpeg io memory region\n");
		ret = -ENOMEM;
		goto err_region;
	}

	/* ioremap */
	dev->reg_base = ioremap(res->start, resource_size(res));
	if (!dev->reg_base) {
		jpeg_err("failed to remap jpeg io region\n");
		ret = -ENOENT;
		goto err_map;
	}

	/* irq */
	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		jpeg_err("failed to request jpeg irq resource\n");
		ret = -ENOENT;
		goto err_irq;
	}

	dev->irq_no = res->start;
	ret = request_irq(dev->irq_no, (void *)jpeg_irq,
			IRQF_DISABLED, pdev->name, dev);
	if (ret != 0) {
		jpeg_err("failed to jpeg request irq\n");
		ret = -ENOENT;
		goto err_irq;
	}

	/* clock */
	dev->clk = clk_get(&pdev->dev, "jpeg");
	if (IS_ERR(dev->clk)) {
		jpeg_err("failed to find jpeg clock source\n");
		ret = -ENOENT;
		goto err_clk;
	}

#ifdef CONFIG_PM_RUNTIME
#ifndef CONFIG_CPU_EXYNOS5250
	pm_runtime_enable(&pdev->dev);
#endif
#endif

	/* clock enable */
	clk_enable(dev->clk);

	ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
	if (ret) {
		v4l2_err(&dev->v4l2_dev, "Failed to register v4l2 device\n");
		goto err_v4l2;
	}

	/* encoder */
	vfd = video_device_alloc();
	if (!vfd) {
		v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n");
		ret = -ENOMEM;
		goto err_vd_alloc_enc;
	}

	*vfd = jpeg_enc_videodev;
	vfd->ioctl_ops = get_jpeg_enc_v4l2_ioctl_ops();
	ret = video_register_device(vfd, VFL_TYPE_GRABBER, 12);
	if (ret) {
		v4l2_err(&dev->v4l2_dev,
			 "%s(): failed to register video device\n", __func__);
		video_device_release(vfd);
		goto err_vd_alloc_enc;
	}
	v4l2_info(&dev->v4l2_dev,
		"JPEG driver is registered to /dev/video%d\n", vfd->num);

	dev->vfd_enc = vfd;
	dev->m2m_dev_enc = v4l2_m2m_init(&jpeg_m2m_enc_ops);
	if (IS_ERR(dev->m2m_dev_enc)) {
		v4l2_err(&dev->v4l2_dev,
			"failed to initialize v4l2-m2m device\n");
		ret = PTR_ERR(dev->m2m_dev_enc);
		goto err_m2m_init_enc;
	}
	video_set_drvdata(vfd, dev);

	/* decoder */
	vfd = video_device_alloc();
	if (!vfd) {
		v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n");
		ret = -ENOMEM;
		goto err_vd_alloc_dec;
	}

	*vfd = jpeg_dec_videodev;
	vfd->ioctl_ops = get_jpeg_dec_v4l2_ioctl_ops();
	ret = video_register_device(vfd, VFL_TYPE_GRABBER, 11);
	if (ret) {
		v4l2_err(&dev->v4l2_dev,
			 "%s(): failed to register video device\n", __func__);
		video_device_release(vfd);
		goto err_vd_alloc_dec;
	}
	v4l2_info(&dev->v4l2_dev,
		"JPEG driver is registered to /dev/video%d\n", vfd->num);

	dev->vfd_dec = vfd;
	dev->m2m_dev_dec = v4l2_m2m_init(&jpeg_m2m_dec_ops);
	if (IS_ERR(dev->m2m_dev_dec)) {
		v4l2_err(&dev->v4l2_dev,
			"failed to initialize v4l2-m2m device\n");
		ret = PTR_ERR(dev->m2m_dev_dec);
		goto err_m2m_init_dec;
	}
	video_set_drvdata(vfd, dev);

	platform_set_drvdata(pdev, dev);

#ifdef CONFIG_VIDEOBUF2_CMA_PHYS
	dev->vb2 = &jpeg_vb2_cma;
#elif defined(CONFIG_VIDEOBUF2_ION)
	dev->vb2 = &jpeg_vb2_ion;
#endif
	dev->alloc_ctx = dev->vb2->init(dev);

	if (IS_ERR(dev->alloc_ctx)) {
		ret = PTR_ERR(dev->alloc_ctx);
		goto err_video_reg;
	}

#ifdef CONFIG_BUSFREQ_OPP
	/* To lock bus frequency in OPP mode */
	dev->bus_dev = dev_get("exynos-busfreq");
#endif

	dev->watchdog_workqueue = create_singlethread_workqueue(JPEG_NAME);
	INIT_WORK(&dev->watchdog_work, jpeg_watchdog_worker);
	atomic_set(&dev->watchdog_cnt, 0);
	init_timer(&dev->watchdog_timer);
	dev->watchdog_timer.data = (unsigned long)dev;
	dev->watchdog_timer.function = jpeg_watchdog;

	/* clock disable */
	clk_disable(dev->clk);

	return 0;

err_video_reg:
	v4l2_m2m_release(dev->m2m_dev_dec);
err_m2m_init_dec:
	video_unregister_device(dev->vfd_dec);
	video_device_release(dev->vfd_dec);
err_vd_alloc_dec:
	v4l2_m2m_release(dev->m2m_dev_enc);
err_m2m_init_enc:
	video_unregister_device(dev->vfd_enc);
	video_device_release(dev->vfd_enc);
err_vd_alloc_enc:
	v4l2_device_unregister(&dev->v4l2_dev);
err_v4l2:
	clk_disable(dev->clk);
	clk_put(dev->clk);
err_clk:
	free_irq(dev->irq_no, NULL);
err_irq:
	iounmap(dev->reg_base);
err_map:
err_region:
	kfree(res);
err_res:
	mutex_destroy(&dev->lock);
err_setup:
	kfree(dev);
err_alloc:
	return ret;

}
Exemplo n.º 5
0
static int s3c_camif_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct s3c_camif_plat_data *pdata = dev->platform_data;
	struct s3c_camif_drvdata *drvdata;
	struct camif_dev *camif;
	struct resource *mres;
	int ret = 0;

	camif = devm_kzalloc(dev, sizeof(*camif), GFP_KERNEL);
	if (!camif)
		return -ENOMEM;

	spin_lock_init(&camif->slock);
	mutex_init(&camif->lock);

	camif->dev = dev;

	if (!pdata || !pdata->gpio_get || !pdata->gpio_put) {
		dev_err(dev, "wrong platform data\n");
		return -EINVAL;
	}

	camif->pdata = *pdata;
	drvdata = (void *)platform_get_device_id(pdev)->driver_data;
	camif->variant = drvdata->variant;

	mres = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	camif->io_base = devm_ioremap_resource(dev, mres);
	if (IS_ERR(camif->io_base))
		return PTR_ERR(camif->io_base);

	ret = camif_request_irqs(pdev, camif);
	if (ret < 0)
		return ret;

	ret = pdata->gpio_get();
	if (ret < 0)
		return ret;

	ret = s3c_camif_create_subdev(camif);
	if (ret < 0)
		goto err_sd;

	ret = camif_clk_get(camif);
	if (ret < 0)
		goto err_clk;

	platform_set_drvdata(pdev, camif);
	clk_set_rate(camif->clock[CLK_CAM],
			camif->pdata.sensor.clock_frequency);

	dev_info(dev, "sensor clock frequency: %lu\n",
		 clk_get_rate(camif->clock[CLK_CAM]));
	/*
	 * Set initial pixel format, resolution and crop rectangle.
	 * Must be done before a sensor subdev is registered as some
	 * settings are overrode with values from sensor subdev.
	 */
	s3c_camif_set_defaults(camif);

	pm_runtime_enable(dev);

	ret = pm_runtime_get_sync(dev);
	if (ret < 0)
		goto err_pm;

	ret = camif_media_dev_init(camif);
	if (ret < 0)
		goto err_alloc;

	ret = camif_register_sensor(camif);
	if (ret < 0)
		goto err_sens;

	ret = v4l2_device_register_subdev(&camif->v4l2_dev, &camif->subdev);
	if (ret < 0)
		goto err_sens;

	ret = v4l2_device_register_subdev_nodes(&camif->v4l2_dev);
	if (ret < 0)
		goto err_sens;

	ret = camif_register_video_nodes(camif);
	if (ret < 0)
		goto err_sens;

	ret = camif_create_media_links(camif);
	if (ret < 0)
		goto err_sens;

	ret = media_device_register(&camif->media_dev);
	if (ret < 0)
		goto err_sens;

	pm_runtime_put(dev);
	return 0;

err_sens:
	v4l2_device_unregister(&camif->v4l2_dev);
	media_device_unregister(&camif->media_dev);
	media_device_cleanup(&camif->media_dev);
	camif_unregister_media_entities(camif);
err_alloc:
	pm_runtime_put(dev);
	pm_runtime_disable(dev);
err_pm:
	camif_clk_put(camif);
err_clk:
	s3c_camif_unregister_subdev(camif);
err_sd:
	pdata->gpio_put();
	return ret;
}
Exemplo n.º 6
0
static int __init fmi_init(void)
{
	struct fmi *fmi = &fmi_card;
	struct v4l2_device *v4l2_dev = &fmi->v4l2_dev;
	struct v4l2_ctrl_handler *hdl = &fmi->hdl;
	int res, i;
	int probe_ports[] = { 0, 0x284, 0x384 };

	if (io < 0) {
		for (i = 0; i < ARRAY_SIZE(probe_ports); i++) {
			io = probe_ports[i];
			if (io == 0) {
				io = isapnp_fmi_probe();
				if (io < 0)
					continue;
				pnp_attached = true;
			}
			if (!request_region(io, 2, "radio-sf16fmi")) {
				if (pnp_attached)
					pnp_device_detach(dev);
				io = -1;
				continue;
			}
			if (pnp_attached ||
			    ((inb(io) & 0xf9) == 0xf9 && (inb(io) & 0x4) == 0))
				break;
			release_region(io, 2);
			io = -1;
		}
	} else {
		if (!request_region(io, 2, "radio-sf16fmi")) {
			printk(KERN_ERR "radio-sf16fmi: port %#x already in use\n", io);
			return -EBUSY;
		}
		if (inb(io) == 0xff) {
			printk(KERN_ERR "radio-sf16fmi: card not present at %#x\n", io);
			release_region(io, 2);
			return -ENODEV;
		}
	}
	if (io < 0) {
		printk(KERN_ERR "radio-sf16fmi: no cards found\n");
		return -ENODEV;
	}

	strlcpy(v4l2_dev->name, "sf16fmi", sizeof(v4l2_dev->name));
	fmi->io = io;

	res = v4l2_device_register(NULL, v4l2_dev);
	if (res < 0) {
		release_region(fmi->io, 2);
		if (pnp_attached)
			pnp_device_detach(dev);
		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
		return res;
	}

	v4l2_ctrl_handler_init(hdl, 1);
	v4l2_ctrl_new_std(hdl, &fmi_ctrl_ops,
			V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
	v4l2_dev->ctrl_handler = hdl;
	if (hdl->error) {
		res = hdl->error;
		v4l2_err(v4l2_dev, "Could not register controls\n");
		v4l2_ctrl_handler_free(hdl);
		v4l2_device_unregister(v4l2_dev);
		return res;
	}

	strlcpy(fmi->vdev.name, v4l2_dev->name, sizeof(fmi->vdev.name));
	fmi->vdev.v4l2_dev = v4l2_dev;
	fmi->vdev.fops = &fmi_fops;
	fmi->vdev.ioctl_ops = &fmi_ioctl_ops;
	fmi->vdev.release = video_device_release_empty;
	video_set_drvdata(&fmi->vdev, fmi);

	mutex_init(&fmi->lock);

	/* mute card and set default frequency */
	fmi->mute = true;
	fmi->curfreq = RSF16_MINFREQ;
	fmi_set_freq(fmi);

	if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
		v4l2_ctrl_handler_free(hdl);
		v4l2_device_unregister(v4l2_dev);
		release_region(fmi->io, 2);
		if (pnp_attached)
			pnp_device_detach(dev);
		return -EINVAL;
	}

	v4l2_info(v4l2_dev, "card driver at 0x%x\n", fmi->io);
	return 0;
}
Exemplo n.º 7
0
static int rockchip_vpu_probe(struct platform_device *pdev)
{
	const struct of_device_id *match;
	struct rockchip_vpu_dev *vpu;
	struct resource *res;
	int i, ret;

	vpu = devm_kzalloc(&pdev->dev, sizeof(*vpu), GFP_KERNEL);
	if (!vpu)
		return -ENOMEM;

	vpu->dev = &pdev->dev;
	vpu->pdev = pdev;
	mutex_init(&vpu->vpu_mutex);
	spin_lock_init(&vpu->irqlock);

	match = of_match_node(of_rockchip_vpu_match, pdev->dev.of_node);
	vpu->variant = match->data;

	INIT_DELAYED_WORK(&vpu->watchdog_work, rockchip_vpu_watchdog);

	for (i = 0; i < vpu->variant->num_clocks; i++)
		vpu->clocks[i].id = vpu->variant->clk_names[i];
	ret = devm_clk_bulk_get(&pdev->dev, vpu->variant->num_clocks,
				vpu->clocks);
	if (ret)
		return ret;

	res = platform_get_resource(vpu->pdev, IORESOURCE_MEM, 0);
	vpu->base = devm_ioremap_resource(vpu->dev, res);
	if (IS_ERR(vpu->base))
		return PTR_ERR(vpu->base);
	vpu->enc_base = vpu->base + vpu->variant->enc_offset;

	ret = dma_set_coherent_mask(vpu->dev, DMA_BIT_MASK(32));
	if (ret) {
		dev_err(vpu->dev, "Could not set DMA coherent mask.\n");
		return ret;
	}

	if (vpu->variant->vepu_irq) {
		int irq;

		irq = platform_get_irq_byname(vpu->pdev, "vepu");
		if (irq <= 0) {
			dev_err(vpu->dev, "Could not get vepu IRQ.\n");
			return -ENXIO;
		}

		ret = devm_request_irq(vpu->dev, irq, vpu->variant->vepu_irq,
				       0, dev_name(vpu->dev), vpu);
		if (ret) {
			dev_err(vpu->dev, "Could not request vepu IRQ.\n");
			return ret;
		}
	}

	ret = vpu->variant->init(vpu);
	if (ret) {
		dev_err(&pdev->dev, "Failed to init VPU hardware\n");
		return ret;
	}

	pm_runtime_set_autosuspend_delay(vpu->dev, 100);
	pm_runtime_use_autosuspend(vpu->dev);
	pm_runtime_enable(vpu->dev);

	ret = clk_bulk_prepare(vpu->variant->num_clocks, vpu->clocks);
	if (ret) {
		dev_err(&pdev->dev, "Failed to prepare clocks\n");
		return ret;
	}

	ret = v4l2_device_register(&pdev->dev, &vpu->v4l2_dev);
	if (ret) {
		dev_err(&pdev->dev, "Failed to register v4l2 device\n");
		goto err_clk_unprepare;
	}
	platform_set_drvdata(pdev, vpu);

	vpu->m2m_dev = v4l2_m2m_init(&vpu_m2m_ops);
	if (IS_ERR(vpu->m2m_dev)) {
		v4l2_err(&vpu->v4l2_dev, "Failed to init mem2mem device\n");
		ret = PTR_ERR(vpu->m2m_dev);
		goto err_v4l2_unreg;
	}

	vpu->mdev.dev = vpu->dev;
	strlcpy(vpu->mdev.model, DRIVER_NAME, sizeof(vpu->mdev.model));
	media_device_init(&vpu->mdev);
	vpu->v4l2_dev.mdev = &vpu->mdev;

	ret = rockchip_vpu_video_device_register(vpu);
	if (ret) {
		dev_err(&pdev->dev, "Failed to register encoder\n");
		goto err_m2m_rel;
	}

	ret = media_device_register(&vpu->mdev);
	if (ret) {
		v4l2_err(&vpu->v4l2_dev, "Failed to register mem2mem media device\n");
		goto err_video_dev_unreg;
	}
	return 0;
err_video_dev_unreg:
	if (vpu->vfd_enc) {
		video_unregister_device(vpu->vfd_enc);
		video_device_release(vpu->vfd_enc);
	}
err_m2m_rel:
	v4l2_m2m_release(vpu->m2m_dev);
err_v4l2_unreg:
	v4l2_device_unregister(&vpu->v4l2_dev);
err_clk_unprepare:
	clk_bulk_unprepare(vpu->variant->num_clocks, vpu->clocks);
	pm_runtime_disable(vpu->dev);
	return ret;
}
Exemplo n.º 8
0
static int __devinit hdmi_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct resource *res;
	struct i2c_adapter *phy_adapter;
	struct hdmi_device *hdmi_dev = NULL;
	struct hdmi_driver_data *drv_data;
	int ret;
	unsigned int irq_type;

	dev_dbg(dev, "probe start\n");

	hdmi_dev = kzalloc(sizeof(*hdmi_dev), GFP_KERNEL);
	if (!hdmi_dev) {
		dev_err(dev, "out of memory\n");
		ret = -ENOMEM;
		goto fail;
	}

	hdmi_dev->dev = dev;

	ret = hdmi_resources_init(hdmi_dev);
	if (ret)
		goto fail_hdev;

	/* mapping HDMI registers */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		dev_err(dev, "get memory resource failed.\n");
		ret = -ENXIO;
		goto fail_init;
	}

	hdmi_dev->regs = ioremap(res->start, resource_size(res));
	if (hdmi_dev->regs == NULL) {
		dev_err(dev, "register mapping failed.\n");
		ret = -ENXIO;
		goto fail_hdev;
	}

	/* External hpd */
	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (res == NULL) {
		dev_err(dev, "get external interrupt resource failed.\n");
		ret = -ENXIO;
		goto fail_regs;
	}
	hdmi_dev->ext_irq = res->start;

	/* Internal hpd */
	res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
	if (res == NULL) {
		dev_err(dev, "get internal interrupt resource failed.\n");
		ret = -ENXIO;
		goto fail_regs;
	}
	hdmi_dev->int_irq = res->start;

	/* workqueue for HPD */
	hdmi_dev->hpd_wq = create_workqueue("hdmi-hpd");
	if (hdmi_dev->hpd_wq == NULL)
		ret = -ENXIO;
	INIT_WORK(&hdmi_dev->hpd_work, s5p_hpd_kobject_uevent);

	/* setting v4l2 name to prevent WARN_ON in v4l2_device_register */
	strlcpy(hdmi_dev->v4l2_dev.name, dev_name(dev),
		sizeof(hdmi_dev->v4l2_dev.name));
	/* passing NULL owner prevents driver from erasing drvdata */
	ret = v4l2_device_register(NULL, &hdmi_dev->v4l2_dev);
	if (ret) {
		dev_err(dev, "could not register v4l2 device.\n");
		goto fail_regs;
	}

	drv_data = (struct hdmi_driver_data *)
		platform_get_device_id(pdev)->driver_data;
	dev_info(dev, "hdmiphy i2c bus number = %d\n", drv_data->hdmiphy_bus);

	phy_adapter = i2c_get_adapter(drv_data->hdmiphy_bus);
	if (phy_adapter == NULL) {
		dev_err(dev, "adapter request failed\n");
		ret = -ENXIO;
		goto fail_vdev;
	}

	hdmi_dev->phy_sd = v4l2_i2c_new_subdev_board(&hdmi_dev->v4l2_dev,
		phy_adapter, &hdmiphy_info, NULL);
	/* on failure or not adapter is no longer useful */
	i2c_put_adapter(phy_adapter);
	if (hdmi_dev->phy_sd == NULL) {
		dev_err(dev, "missing subdev for hdmiphy\n");
		ret = -ENODEV;
		goto fail_vdev;
	}

	/* HDMI PHY power off
	 * HDMI PHY is on as default configuration
	 * So, HDMI PHY must be turned off if it's not used */
	clk_enable(hdmi_dev->res.hdmiphy);
	v4l2_subdev_call(hdmi_dev->phy_sd, core, s_power, 0);
	clk_disable(hdmi_dev->res.hdmiphy);

	pm_runtime_enable(dev);

	/* irq setting by TV power on/off status */
	if (!pm_runtime_suspended(hdmi_dev->dev)) {
		hdmi_dev->curr_irq = hdmi_dev->int_irq;
		irq_type = 0;
		s5p_v4l2_int_src_hdmi_hpd();
	} else {
		if (s5p_v4l2_hpd_read_gpio())
			atomic_set(&hdmi_dev->hpd_state, HPD_HIGH);
		else
			atomic_set(&hdmi_dev->hpd_state, HPD_LOW);
		hdmi_dev->curr_irq = hdmi_dev->ext_irq;
		irq_type = IRQ_TYPE_EDGE_BOTH;
		s5p_v4l2_int_src_ext_hpd();
	}

	hdmi_dev->hpd_user_checked = false;

	ret = request_irq(hdmi_dev->curr_irq, hdmi_irq_handler,
			irq_type, "hdmi", hdmi_dev);

	if (ret) {
		dev_err(dev, "request interrupt failed.\n");
		goto fail_vdev;
	}

	hdmi_dev->cur_preset = HDMI_DEFAULT_PRESET;
	/* FIXME: missing fail preset is not supported */
	hdmi_dev->cur_conf = hdmi_preset2conf(hdmi_dev->cur_preset);

	/* default audio configuration : enable audio */
	hdmi_dev->audio_enable = 1;
	hdmi_dev->sample_rate = DEFAULT_SAMPLE_RATE;
	hdmi_dev->bits_per_sample = DEFAULT_BITS_PER_SAMPLE;
	hdmi_dev->audio_codec = DEFAULT_AUDIO_CODEC;

	/* register hdmi subdev as entity */
	ret = hdmi_register_entity(hdmi_dev);
	if (ret)
		goto fail_irq;

	hdmi_entity_info_print(hdmi_dev);

	/* initialize hdcp resource */
	ret = hdcp_prepare(hdmi_dev);
	if (ret)
		goto fail_irq;

	dev_info(dev, "probe sucessful\n");

	return 0;

fail_vdev:
	v4l2_device_unregister(&hdmi_dev->v4l2_dev);

fail_irq:
	free_irq(hdmi_dev->curr_irq, hdmi_dev);

fail_regs:
	iounmap(hdmi_dev->regs);

fail_init:
	hdmi_resources_cleanup(hdmi_dev);

fail_hdev:
	kfree(hdmi_dev);

fail:
	dev_err(dev, "probe failed\n");
	return ret;
}
static int hdmi_probe(struct platform_device *pdev)
{
	struct s5p_hdmi_platdata *pdata = NULL;
	struct device *dev = &pdev->dev;
	struct resource *res;
	struct i2c_adapter *phy_adapter;
	struct hdmi_device *hdmi_dev = NULL;
	struct hdmi_driver_data *drv_data;
	int ret;

	dev_info(dev, "probe start\n");

	hdmi_dev = devm_kzalloc(&pdev->dev, sizeof(struct hdmi_device), GFP_KERNEL);
	if (!hdmi_dev) {
		dev_err(&pdev->dev, "no memory for hdmi device\n");
		return -ENOMEM;
	}
	hdmi_dev->dev = dev;

	hdmi_dev->pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
	if (!hdmi_dev->pdata) {
		dev_err(&pdev->dev, "no memory for state\n");
		return -ENOMEM;
	}

	/* store platform data ptr to mixer context */
	if (dev->of_node) {
		of_property_read_u32(dev->of_node, "ip_ver", &hdmi_dev->pdata->ip_ver);
		pdata = hdmi_dev->pdata;
	} else {
		hdmi_dev->pdata = dev->platform_data;
		pdata = hdmi_dev->pdata;
	}
	dev_info(dev, "HDMI ip version %d\n", pdata->ip_ver);

	/* mapping HDMI registers */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(dev, "get hdmi memory resource failed.\n");
		return -ENXIO;
	}
	hdmi_dev->regs = devm_request_and_ioremap(&pdev->dev, res);
	if (hdmi_dev->regs == NULL) {
		dev_err(dev, "failed to claim register region for hdmi\n");
		return -ENOENT;
	}

	/* mapping HDMIPHY_APB registers */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (!res) {
		dev_err(dev, "get hdmiphy memory resource failed.\n");
		return -ENXIO;
	}
	hdmi_dev->phy_regs = devm_request_and_ioremap(&pdev->dev, res);
	if (hdmi_dev->phy_regs == NULL) {
		dev_err(dev, "failed to claim register region for hdmiphy\n");
		return -ENOENT;
	}

	/* Internal hpd */
	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		dev_err(dev, "get internal interrupt resource failed.\n");
		return -ENXIO;
	}
	ret = devm_request_irq(dev, res->start, hdmi_irq_handler,
			0, "hdmi-int", hdmi_dev);
	if (ret) {
		dev_err(dev, "request int interrupt failed.\n");
		return ret;
	} else {
		hdmi_dev->int_irq = res->start;
		disable_irq(hdmi_dev->int_irq);
		dev_info(dev, "success request hdmi-int irq\n");
	}

	/* setting v4l2 name to prevent WARN_ON in v4l2_device_register */
	strlcpy(hdmi_dev->v4l2_dev.name, dev_name(dev),
		sizeof(hdmi_dev->v4l2_dev.name));
	/* passing NULL owner prevents driver from erasing drvdata */
	ret = v4l2_device_register(NULL, &hdmi_dev->v4l2_dev);
	if (ret) {
		dev_err(dev, "could not register v4l2 device.\n");
		goto fail;
	}

	INIT_WORK(&hdmi_dev->hpd_work, hdmi_hpd_work);
	INIT_DELAYED_WORK(&hdmi_dev->hpd_work_ext, hdmi_hpd_work_ext);

	/* setting the clocks */
	ret = hdmi_resources_init(hdmi_dev);
	if (ret)
		goto fail_vdev;

	/* setting the GPIO */
	ret = hdmi_set_gpio(hdmi_dev);
	if (ret) {
		dev_err(dev, "failed to get GPIO\n");
		goto fail_clk;
	}

	/* External hpd */
	hdmi_dev->ext_irq = gpio_to_irq(hdmi_dev->res.gpio_hpd);
	ret = devm_request_irq(dev, hdmi_dev->ext_irq, hdmi_irq_handler_ext,
			IRQ_TYPE_EDGE_BOTH, "hdmi-ext", hdmi_dev);
	if (ret) {
		dev_err(dev, "request ext interrupt failed.\n");
		goto fail_gpio;
	} else {
		dev_info(dev, "success request hdmi-ext irq\n");
	}

	hdmi_dev->hpd_switch.name = "hdmi";
	ret = switch_dev_register(&hdmi_dev->hpd_switch);
	if (ret) {
		dev_err(dev, "request switch class failed.\n");
		goto fail_gpio;
	}

	mutex_init(&hdmi_dev->mutex);

	if (soc_is_exynos5250()) {
		drv_data = (struct hdmi_driver_data *)
			platform_get_device_id(pdev)->driver_data;
		dev_info(dev, "hdmiphy i2c bus number = %d\n", drv_data->hdmiphy_bus);

		phy_adapter = i2c_get_adapter(drv_data->hdmiphy_bus);
		if (phy_adapter == NULL) {
			dev_err(dev, "adapter request failed\n");
			ret = -ENXIO;
			goto fail_switch;
		}

		hdmi_dev->phy_sd = v4l2_i2c_new_subdev_board(&hdmi_dev->v4l2_dev,
				phy_adapter, &hdmiphy_info, NULL);
		/* on failure or not adapter is no longer useful */
		i2c_put_adapter(phy_adapter);
		if (hdmi_dev->phy_sd == NULL) {
			dev_err(dev, "missing subdev for hdmiphy\n");
			ret = -ENODEV;
			goto fail_switch;
		}
	}

	hdmi_dev->cur_timings =
		hdmi_conf[HDMI_DEFAULT_TIMINGS_IDX].dv_timings;
	/* FIXME: missing fail preset is not supported */
	hdmi_dev->cur_conf = hdmi_conf[HDMI_DEFAULT_TIMINGS_IDX].conf;

	/* default audio configuration : enable audio */
	hdmi_dev->audio_enable = 1;
	hdmi_dev->audio_channel_count = 2;
	hdmi_dev->sample_rate = DEFAULT_SAMPLE_RATE;
	hdmi_dev->color_range = HDMI_RGB709_0_255;
	hdmi_dev->bits_per_sample = DEFAULT_BITS_PER_SAMPLE;
	hdmi_dev->audio_codec = DEFAULT_AUDIO_CODEC;

	/* default aspect ratio is 16:9 */
	hdmi_dev->aspect = HDMI_ASPECT_RATIO_16_9;

	/* default HDMI streaming is stoped */
	hdmi_dev->streaming = HDMI_STOP;

	/* register hdmi subdev as entity */
	ret = hdmi_register_entity(hdmi_dev);
	if (ret)
		goto fail_switch;

	hdmi_entity_info_print(hdmi_dev);

	pm_runtime_enable(dev);

	/* initialize hdcp resource */
	ret = hdcp_prepare(hdmi_dev);
	if (ret)
		goto fail_switch;

	/* work after booting */
	queue_delayed_work(system_nrt_wq, &hdmi_dev->hpd_work_ext,
					msecs_to_jiffies(1500));
	/* TODO : Check the PHY power off is implemented at pm_domains
	 * If not, PHY power off should be applied at here */

	dev_info(dev, "probe sucessful\n");

	hdmi_debugfs_init(hdmi_dev);

	return 0;

fail_switch:
	switch_dev_unregister(&hdmi_dev->hpd_switch);
	mutex_destroy(&hdmi_dev->mutex);

fail_gpio:
	gpio_free(hdmi_dev->res.gpio_hpd);
	gpio_free(hdmi_dev->res.gpio_ls);
	gpio_free(hdmi_dev->res.gpio_dcdc);

fail_clk:
	hdmi_resources_cleanup(hdmi_dev);

fail_vdev:
	v4l2_device_unregister(&hdmi_dev->v4l2_dev);

fail:
	dev_err(dev, "probe failed\n");
	return ret;
}
Exemplo n.º 10
0
static int __init fmi_init(void)
{
	struct fmi *fmi = &fmi_card;
	struct v4l2_device *v4l2_dev = &fmi->v4l2_dev;
	int res, i;
	int probe_ports[] = { 0, 0x284, 0x384 };

	if (io < 0) {
		for (i = 0; i < ARRAY_SIZE(probe_ports); i++) {
			io = probe_ports[i];
			if (io == 0) {
				io = isapnp_fmi_probe();
				if (io < 0)
					continue;
				pnp_attached = 1;
			}
			if (!request_region(io, 2, "radio-sf16fmi")) {
				if (pnp_attached)
					pnp_device_detach(dev);
				io = -1;
				continue;
			}
			if (pnp_attached ||
			    ((inb(io) & 0xf9) == 0xf9 && (inb(io) & 0x4) == 0))
				break;
			release_region(io, 2);
			io = -1;
		}
	} else {
		if (!request_region(io, 2, "radio-sf16fmi")) {
			printk(KERN_ERR "radio-sf16fmi: port %#x already in use\n", io);
			return -EBUSY;
		}
		if (inb(io) == 0xff) {
			printk(KERN_ERR "radio-sf16fmi: card not present at %#x\n", io);
			release_region(io, 2);
			return -ENODEV;
		}
	}
	if (io < 0) {
		printk(KERN_ERR "radio-sf16fmi: no cards found\n");
		return -ENODEV;
	}

	strlcpy(v4l2_dev->name, "sf16fmi", sizeof(v4l2_dev->name));
	fmi->io = io;

	res = v4l2_device_register(NULL, v4l2_dev);
	if (res < 0) {
		release_region(fmi->io, 2);
		if (pnp_attached)
			pnp_device_detach(dev);
		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
		return res;
	}

	strlcpy(fmi->vdev.name, v4l2_dev->name, sizeof(fmi->vdev.name));
	fmi->vdev.v4l2_dev = v4l2_dev;
	fmi->vdev.fops = &fmi_fops;
	fmi->vdev.ioctl_ops = &fmi_ioctl_ops;
	fmi->vdev.release = video_device_release_empty;
	video_set_drvdata(&fmi->vdev, fmi);

	mutex_init(&fmi->lock);

	/* mute card - prevents noisy bootups */
	fmi_mute(fmi);

	if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
		v4l2_device_unregister(v4l2_dev);
		release_region(fmi->io, 2);
		if (pnp_attached)
			pnp_device_detach(dev);
		return -EINVAL;
	}

	v4l2_info(v4l2_dev, "card driver at 0x%x\n", fmi->io);
	return 0;
}
static int __devinit msm_vidc_probe(struct platform_device *pdev)
{
	int rc = 0;
	struct msm_vidc_core *core;
	struct device *dev;
	int nr = BASE_DEVICE_NUMBER;

	core = kzalloc(sizeof(*core), GFP_KERNEL);
	if (!core || !vidc_driver) {
		dprintk(VIDC_ERR,
			"Failed to allocate memory for device core\n");
		rc = -ENOMEM;
		goto err_no_mem;
	}
	rc = msm_vidc_initialize_core(pdev, core);
	if (rc) {
		dprintk(VIDC_ERR, "Failed to init core\n");
		goto err_core_init;
	}
	rc = device_create_file(&pdev->dev, &dev_attr_pwr_collapse_delay);
	if (rc) {
		dprintk(VIDC_ERR,
				"Failed to create pwr_collapse_delay sysfs node");
		goto err_core_init;
	}
	if (core->hfi_type == VIDC_HFI_Q6) {
		dprintk(VIDC_ERR, "Q6 hfi device probe called\n");
		nr += MSM_VIDC_MAX_DEVICES;
		core->id = MSM_VIDC_CORE_Q6;
	} else {
		core->id = MSM_VIDC_CORE_VENUS;
	}

	rc = v4l2_device_register(&pdev->dev, &core->v4l2_dev);
	if (rc) {
		dprintk(VIDC_ERR, "Failed to register v4l2 device\n");
		goto err_v4l2_register;
	}
	core->vdev[MSM_VIDC_DECODER].vdev.release =
		msm_vidc_release_video_device;
	core->vdev[MSM_VIDC_DECODER].vdev.fops = &msm_v4l2_vidc_fops;
	core->vdev[MSM_VIDC_DECODER].vdev.ioctl_ops = &msm_v4l2_ioctl_ops;
	core->vdev[MSM_VIDC_DECODER].type = MSM_VIDC_DECODER;
	rc = video_register_device(&core->vdev[MSM_VIDC_DECODER].vdev,
					VFL_TYPE_GRABBER, nr);
	if (rc) {
		dprintk(VIDC_ERR, "Failed to register video decoder device");
		goto err_dec_register;
	}
	video_set_drvdata(&core->vdev[MSM_VIDC_DECODER].vdev, core);
	dev = &core->vdev[MSM_VIDC_DECODER].vdev.dev;
	rc = device_create_file(dev, &dev_attr_link_name);
	if (rc) {
		dprintk(VIDC_ERR,
				"Failed to create link name sysfs for decoder");
		goto err_dec_attr_link_name;
	}

	core->vdev[MSM_VIDC_ENCODER].vdev.release =
		msm_vidc_release_video_device;
	core->vdev[MSM_VIDC_ENCODER].vdev.fops = &msm_v4l2_vidc_fops;
	core->vdev[MSM_VIDC_ENCODER].vdev.ioctl_ops = &msm_v4l2_ioctl_ops;
	core->vdev[MSM_VIDC_ENCODER].type = MSM_VIDC_ENCODER;
	rc = video_register_device(&core->vdev[MSM_VIDC_ENCODER].vdev,
				VFL_TYPE_GRABBER, nr + 1);
	if (rc) {
		dprintk(VIDC_ERR, "Failed to register video encoder device");
		goto err_enc_register;
	}
	video_set_drvdata(&core->vdev[MSM_VIDC_ENCODER].vdev, core);
	dev = &core->vdev[MSM_VIDC_ENCODER].vdev.dev;
	rc = device_create_file(dev, &dev_attr_link_name);
	if (rc) {
		dprintk(VIDC_ERR,
				"Failed to create link name sysfs for encoder");
		goto err_enc_attr_link_name;
	}

	mutex_lock(&vidc_driver->lock);
	if (vidc_driver->num_cores  + 1 > MSM_VIDC_CORES_MAX) {
		mutex_unlock(&vidc_driver->lock);
		dprintk(VIDC_ERR, "Maximum cores already exist, core_no = %d\n",
				vidc_driver->num_cores);
		goto err_cores_exceeded;
	}
	vidc_driver->num_cores++;
	mutex_unlock(&vidc_driver->lock);

	core->device = vidc_hfi_initialize(core->hfi_type, core->id,
				&core->resources, &handle_cmd_response);
	if (IS_ERR_OR_NULL(core->device)) {
		mutex_lock(&vidc_driver->lock);
		vidc_driver->num_cores--;
		mutex_unlock(&vidc_driver->lock);
		rc = PTR_ERR(core->device);
		if (rc != -EPROBE_DEFER)
			dprintk(VIDC_ERR, "Failed to create HFI device\n");
		else
			dprintk(VIDC_DBG, "msm_vidc: request probe defer\n");
		goto err_cores_exceeded;
	}

	mutex_lock(&vidc_driver->lock);
	list_add_tail(&core->list, &vidc_driver->cores);
	mutex_unlock(&vidc_driver->lock);
	core->debugfs_root = msm_vidc_debugfs_init_core(
		core, vidc_driver->debugfs_root);
	pdev->dev.platform_data = core;
	return rc;

err_cores_exceeded:
	device_remove_file(&core->vdev[MSM_VIDC_ENCODER].vdev.dev,
			&dev_attr_link_name);
err_enc_attr_link_name:
	video_unregister_device(&core->vdev[MSM_VIDC_ENCODER].vdev);
err_enc_register:
	device_remove_file(&core->vdev[MSM_VIDC_DECODER].vdev.dev,
			&dev_attr_link_name);
err_dec_attr_link_name:
	video_unregister_device(&core->vdev[MSM_VIDC_DECODER].vdev);
err_dec_register:
	v4l2_device_unregister(&core->v4l2_dev);
err_v4l2_register:
	device_remove_file(&pdev->dev, &dev_attr_pwr_collapse_delay);
err_core_init:
	kfree(core);
err_no_mem:
	return rc;
}
Exemplo n.º 12
0
int fimc_register_capture_device(struct fimc_dev *fimc)
{
	struct v4l2_device *v4l2_dev = &fimc->vid_cap.v4l2_dev;
	struct video_device *vfd;
	struct fimc_vid_cap *vid_cap;
	struct fimc_ctx *ctx;
	struct v4l2_format f;
	int ret;

	ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;

	ctx->fimc_dev	 = fimc;
	ctx->in_path	 = FIMC_CAMERA;
	ctx->out_path	 = FIMC_DMA;
	ctx->state	 = FIMC_CTX_CAP;

	f.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24;
	ctx->d_frame.fmt = find_format(&f, FMT_FLAGS_M2M);

	if (!v4l2_dev->name[0])
		snprintf(v4l2_dev->name, sizeof(v4l2_dev->name),
			 "%s.capture", dev_name(&fimc->pdev->dev));

	ret = v4l2_device_register(NULL, v4l2_dev);
	if (ret)
		goto err_info;

	vfd = video_device_alloc();
	if (!vfd) {
		v4l2_err(v4l2_dev, "Failed to allocate video device\n");
		goto err_v4l2_reg;
	}

	snprintf(vfd->name, sizeof(vfd->name), "%s:cap",
		 dev_name(&fimc->pdev->dev));

	vfd->fops	= &fimc_capture_fops;
	vfd->ioctl_ops	= &fimc_capture_ioctl_ops;
	vfd->minor	= -1;
	vfd->release	= video_device_release;
	video_set_drvdata(vfd, fimc);

	vid_cap = &fimc->vid_cap;
	vid_cap->vfd = vfd;
	vid_cap->active_buf_cnt = 0;
	vid_cap->reqbufs_count  = 0;
	vid_cap->refcnt = 0;
	/* The default color format for image sensor. */
	vid_cap->fmt.code = V4L2_MBUS_FMT_YUYV8_2X8;

	INIT_LIST_HEAD(&vid_cap->pending_buf_q);
	INIT_LIST_HEAD(&vid_cap->active_buf_q);
	spin_lock_init(&ctx->slock);
	vid_cap->ctx = ctx;

	videobuf_queue_dma_contig_init(&vid_cap->vbq, &fimc_qops,
		vid_cap->v4l2_dev.dev, &fimc->irqlock,
		V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE,
		sizeof(struct fimc_vid_buffer), (void *)ctx);

	ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
	if (ret) {
		v4l2_err(v4l2_dev, "Failed to register video device\n");
		goto err_vd_reg;
	}

	v4l2_info(v4l2_dev,
		  "FIMC capture driver registered as /dev/video%d\n",
		  vfd->num);

	return 0;

err_vd_reg:
	video_device_release(vfd);
err_v4l2_reg:
	v4l2_device_unregister(v4l2_dev);
err_info:
	dev_err(&fimc->pdev->dev, "failed to install\n");
	return ret;
}
Exemplo n.º 13
0
static int __devinit nxp_v4l2_probe(struct platform_device *pdev)
{
    struct v4l2_device *v4l2_dev;
    struct nxp_v4l2 *nxp_v4l2;
    struct nxp_v4l2_platformdata *pdata;
#ifdef CONFIG_VIDEO_NXP_CAPTURE
    struct nxp_capture_platformdata *capture_pdata;
    struct nxp_capture *capture;
    int i;
#endif
#ifdef CONFIG_NXP_M2M_SCALER
    struct nxp_scaler *scaler;
#endif

#ifdef CONFIG_LOOPBACK_SENSOR_DRIVER
		struct nxp_loopback_sensor *loopback_sensor = NULL;
#endif

    int ret;

    pr_debug("%s entered\n", __func__);

    pdata = pdev->dev.platform_data;
    if (!pdata) {
        dev_err(&pdev->dev, "can't get platformdata\n");
        return -EINVAL;
    }

    nxp_v4l2 = kzalloc(sizeof(*nxp_v4l2), GFP_KERNEL);
    if (!nxp_v4l2) {
        pr_err("%s error: fail to kzalloc(size %d)\n", __func__, sizeof(struct nxp_v4l2));
        return -ENOMEM;
    }

    nxp_v4l2->pdev = pdev;
    nxp_v4l2->pdata = pdata;

    snprintf(nxp_v4l2->media_dev.model, sizeof(nxp_v4l2->media_dev.model), "%s",
            dev_name(&pdev->dev));

    nxp_v4l2->media_dev.dev = &pdev->dev;

    v4l2_dev       = &nxp_v4l2->v4l2_dev;
    v4l2_dev->mdev = &nxp_v4l2->media_dev;
    snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s",
            dev_name(&pdev->dev));

    /* alloc context : use uncached area */
    nxp_v4l2->alloc_ctx =
        vb2_ion_create_context(&pdev->dev, SZ_4K, VB2ION_CTX_UNCACHED);
    if (!nxp_v4l2->alloc_ctx) {
        pr_err("%s: failed to ion alloc context\n", __func__);
        ret = -ENOMEM;
        goto err_alloc_ctx;
    }

    ret = v4l2_device_register(&pdev->dev, &nxp_v4l2->v4l2_dev);
    if (ret < 0) {
        pr_err("%s: failed to register v4l2_device: %d\n", __func__, ret);
        goto err_v4l2_reg;
    }

    ret = media_device_register(&nxp_v4l2->media_dev);
    if (ret < 0) {
        pr_err("%s: failed to register media_device: %d\n", __func__, ret);
        goto err_media_reg;
    }

    __me = nxp_v4l2;

#ifdef CONFIG_LOOPBACK_SENSOR_DRIVER
		loopback_sensor =	create_nxp_loopback_sensor(pdata->captures);
		if (!loopback_sensor) {
				pr_err("%s: failed to create_nxp_loopback_sensor()\n", __func__);
				ret = -EINVAL;
				goto err_loopback_sensor_create;
		}

		ret = register_nxp_loopback_sensor(loopback_sensor);
		if (ret < 0) {
				pr_err("%s: failed to register_nxp_loopback_sensor()\n", __func__);
				goto err_loopback_sensor_create;
		}

    nxp_v4l2->loopback_sensor = loopback_sensor;
#endif

#ifdef CONFIG_VIDEO_NXP_CAPTURE
    /* capture */
    for (capture_pdata = pdata->captures, i = 0;
            capture_pdata->sensor;
            capture_pdata++, i++) {
        /* TODO : psw0523 test for module index problem !!! */
        /* capture = create_nxp_capture(i, capture_pdata); */
        capture = create_nxp_capture(i, capture_pdata->module, capture_pdata);
        if (!capture) {
            pr_err("%s: failed to %dth create_nxp_capture()\n", __func__, i);
            ret = -EINVAL;
            goto err_capture_create;
        }

        ret = register_nxp_capture(capture);
        if (ret < 0) {
            pr_err("%s: failed to %dth register_nxp_capture()\n", __func__, i);
            goto err_capture_create;
        }

        nxp_v4l2->capture[i] = capture;
    }
#endif

#ifdef CONFIG_NXP_M2M_SCALER
    /* m2m */
    scaler = create_nxp_scaler();
    if (!scaler) {
        pr_err("%s: failed to create_nxp_scaler()\n", __func__);
        ret = -ENOMEM;
#ifdef CONFIG_VIDEO_NXP_CAPTURE
        goto err_capture_create;
#else
        goto err_media_reg;
#endif
    }

    ret = register_nxp_scaler(scaler);
    if (ret < 0) {
        pr_err("%s: failed to nxp_scaler_register()\n", __func__);
        goto err_register_scaler;
    }
    nxp_v4l2->scaler = scaler;
#endif

#ifdef CONFIG_VIDEO_NXP_OUT
    /* out */
    nxp_v4l2->out = create_nxp_out(pdata->out);
    if (!nxp_v4l2->out) {
        pr_err("%s: failed to create_nxp_out()\n", __func__);
        goto err_create_out;
    }

    ret = register_nxp_out(nxp_v4l2->out);
    if (ret < 0) {
        pr_err("%s: failed to register_nxp_out()\n", __func__);
        goto err_register_out;
    }
#endif

    ret = v4l2_device_register_subdev_nodes(&nxp_v4l2->v4l2_dev);
    if (ret < 0) {
        pr_err("%s: failed to v4l2_device_register_subdev_nodes()\n", __func__);
        goto err_register_out_subdev;
    }

    platform_set_drvdata(pdev, nxp_v4l2);
   // printk("%s success!!!\n", __func__);

    return 0;

err_register_out_subdev:
#ifdef CONFIG_VIDEO_NXP_OUT
    unregister_nxp_out(nxp_v4l2->out);
err_register_out:
    release_nxp_out(nxp_v4l2->out);
err_create_out:
#endif
#ifdef CONFIG_NXP_M2M_SCALER
    unregister_nxp_scaler(scaler);
err_register_scaler:
    release_nxp_scaler(scaler);
#endif
#ifdef CONFIG_VIDEO_NXP_CAPTURE
err_capture_create:
    for (i = 0; i < NXP_MAX_CAPTURE_NUM; ++i) {
        capture = nxp_v4l2->capture[i];
        if (capture) {
            unregister_nxp_capture(capture);
            release_nxp_capture(capture);
        }
    }
    media_device_unregister(&nxp_v4l2->media_dev);
#endif
#ifdef CONFIG_LOOPBACK_SENSOR_DRIVER
err_loopback_sensor_create:
		if( loopback_sensor )
		{
			unregister_nxp_loopback_sensor(loopback_sensor);
    	release_nxp_loopback_sensor(loopback_sensor);
		}
#endif

err_media_reg:
    v4l2_device_unregister(&nxp_v4l2->v4l2_dev);
err_v4l2_reg:
    vb2_ion_destroy_context(nxp_v4l2->alloc_ctx);
err_alloc_ctx:
    kfree(nxp_v4l2);
    __me = NULL;
    return ret;
}
Exemplo n.º 14
0
/*
 * jpegdma_probe - Dma device probe method.
 * @pdev: Pointer Dma platform device.
 */
static int jpegdma_probe(struct platform_device *pdev)
{
	struct msm_jpegdma_device *jpegdma;
	int ret;

	dev_dbg(&pdev->dev, "jpeg v4l2 DMA probed\n");
	/* Jpeg dma device struct */
	jpegdma = kzalloc(sizeof(struct msm_jpegdma_device), GFP_KERNEL);
	if (!jpegdma)
		return -ENOMEM;

	mutex_init(&jpegdma->lock);

	init_completion(&jpegdma->hw_reset_completion);
	init_completion(&jpegdma->hw_halt_completion);
	jpegdma->dev = &pdev->dev;

	/* Get resources */
	ret = msm_jpegdma_hw_get_mem_resources(pdev, jpegdma);
	if (ret < 0)
		goto error_mem_resources;

	ret = msm_jpegdma_hw_get_regulators(jpegdma);
	if (ret < 0)
		goto error_get_regulators;

	ret = msm_jpegdma_hw_get_clocks(jpegdma);
	if (ret < 0)
		goto error_get_clocks;

	ret = msm_jpegdma_hw_get_qos(jpegdma);
	if (ret < 0)
		goto error_qos_get;

	ret = msm_jpegdma_hw_get_vbif(jpegdma);
	if (ret < 0)
		goto error_vbif_get;

	ret = msm_jpegdma_hw_get_prefetch(jpegdma);
	if (ret < 0)
		goto error_prefetch_get;

	ret = msm_jpegdma_hw_request_irq(pdev, jpegdma);
	if (ret < 0)
		goto error_hw_get_request_irq;

	ret = msm_jpegdma_hw_get_capabilities(jpegdma);
	if (ret < 0)
		goto error_hw_get_request_irq;

	/* mem2mem device */
	jpegdma->m2m_dev = v4l2_m2m_init(&msm_jpegdma_m2m_ops);
	if (IS_ERR(jpegdma->m2m_dev)) {
		dev_err(&pdev->dev, "Failed to init mem2mem device\n");
		ret = PTR_ERR(jpegdma->m2m_dev);
		goto error_m2m_init;
	}

	/* v4l2 device */
	ret = v4l2_device_register(&pdev->dev, &jpegdma->v4l2_dev);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to register v4l2 device\n");
		goto error_v4l2_register;
	}

	jpegdma->video.fops = &fd_fops;
	jpegdma->video.ioctl_ops = &fd_ioctl_ops;
	jpegdma->video.minor = -1;
	jpegdma->video.release = video_device_release;
	jpegdma->video.v4l2_dev = &jpegdma->v4l2_dev;
	jpegdma->video.vfl_dir = VFL_DIR_M2M;
	jpegdma->video.vfl_type = VFL_TYPE_GRABBER;
	strlcpy(jpegdma->video.name, MSM_JPEGDMA_DRV_NAME,
		sizeof(jpegdma->video.name));

	ret = video_register_device(&jpegdma->video, VFL_TYPE_GRABBER, -1);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to register video device\n");
		goto error_video_register;
	}

	video_set_drvdata(&jpegdma->video, jpegdma);

	platform_set_drvdata(pdev, jpegdma);

	dev_dbg(&pdev->dev, "jpeg v4l2 DMA probe success\n");
	return 0;

error_video_register:
	v4l2_device_unregister(&jpegdma->v4l2_dev);
error_v4l2_register:
	v4l2_m2m_release(jpegdma->m2m_dev);
error_m2m_init:
	msm_jpegdma_hw_release_irq(jpegdma);
error_hw_get_request_irq:
	msm_jpegdma_hw_put_prefetch(jpegdma);
error_prefetch_get:
	msm_jpegdma_hw_put_vbif(jpegdma);
error_vbif_get:
	msm_jpegdma_hw_put_qos(jpegdma);
error_qos_get:
	msm_jpegdma_hw_put_clocks(jpegdma);
error_get_clocks:
	msm_jpegdma_hw_put_regulators(jpegdma);
error_get_regulators:
	msm_jpegdma_hw_release_mem_resources(jpegdma);
error_mem_resources:
	kfree(jpegdma);
	return ret;
}
Exemplo n.º 15
0
static int __devinit hdmi_probe(struct platform_device *pdev)
{
	struct s5p_hdmi_platdata *pdata;
	struct device *dev = &pdev->dev;
	struct resource *res;
	struct i2c_adapter *phy_adapter;
	struct hdmi_device *hdmi_dev = NULL;
	struct hdmi_driver_data *drv_data;
	struct generic_pm_domain *genpd;
	int ret;

	dev_dbg(dev, "probe start\n");

	hdmi_dev = kzalloc(sizeof(*hdmi_dev), GFP_KERNEL);
	if (!hdmi_dev) {
		dev_err(dev, "out of memory\n");
		ret = -ENOMEM;
		goto fail;
	}

	hdmi_dev->dev = dev;

	ret = hdmi_resources_init(hdmi_dev);
	if (ret)
		goto fail_hdev;

	/* mapping HDMI registers */
	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (res == NULL) {
		dev_err(dev, "get memory resource failed.\n");
		ret = -ENXIO;
		goto fail_init;
	}

	hdmi_dev->regs = ioremap(res->start, resource_size(res));
	if (hdmi_dev->regs == NULL) {
		dev_err(dev, "register mapping failed.\n");
		ret = -ENXIO;
		goto fail_hdev;
	}

	/* External hpd */
	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (res == NULL) {
		dev_err(dev, "get external interrupt resource failed.\n");
		ret = -ENXIO;
		goto fail_regs;
	}
	hdmi_dev->ext_irq = res->start;

	/* Internal hpd */
	res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
	if (res == NULL) {
		dev_err(dev, "get internal interrupt resource failed.\n");
		ret = -ENXIO;
		goto fail_regs;
	}
	hdmi_dev->int_irq = res->start;

	INIT_WORK(&hdmi_dev->hpd_work, hdmi_hpd_work);
	INIT_DELAYED_WORK(&hdmi_dev->hpd_work_ext, hdmi_hpd_work_ext);
	mutex_init(&hdmi_dev->mutex);

	/* setting v4l2 name to prevent WARN_ON in v4l2_device_register */
	strlcpy(hdmi_dev->v4l2_dev.name, dev_name(dev),
		sizeof(hdmi_dev->v4l2_dev.name));
	/* passing NULL owner prevents driver from erasing drvdata */
	ret = v4l2_device_register(NULL, &hdmi_dev->v4l2_dev);
	if (ret) {
		dev_err(dev, "could not register v4l2 device.\n");
		goto fail_regs;
	}

	drv_data = (struct hdmi_driver_data *)
		platform_get_device_id(pdev)->driver_data;
	dev_info(dev, "hdmiphy i2c bus number = %d\n", drv_data->hdmiphy_bus);

	phy_adapter = i2c_get_adapter(drv_data->hdmiphy_bus);
	if (phy_adapter == NULL) {
		dev_err(dev, "adapter request failed\n");
		ret = -ENXIO;
		goto fail_vdev;
	}

	hdmi_dev->phy_sd = v4l2_i2c_new_subdev_board(&hdmi_dev->v4l2_dev,
		phy_adapter, &hdmiphy_info, NULL);
	/* on failure or not adapter is no longer useful */
	i2c_put_adapter(phy_adapter);
	if (hdmi_dev->phy_sd == NULL) {
		dev_err(dev, "missing subdev for hdmiphy\n");
		ret = -ENODEV;
		goto fail_vdev;
	}

	pdata = pdev->dev.platform_data;

	/* HDMI PHY power off
	 * HDMI PHY is on as default configuration
	 * So, HDMI PHY must be turned off if it's not used */
	if (pdata->hdmiphy_enable)
		pdata->hdmiphy_enable(pdev, 1);
	v4l2_subdev_call(hdmi_dev->phy_sd, core, s_power, 0);
	if (pdata->hdmiphy_enable)
		pdata->hdmiphy_enable(pdev, 0);

#ifdef CONFIG_PM_GENERIC_DOMAINS
	genpd = dev_to_genpd(hdmi_dev->dev);
	if (IS_ERR(genpd)) {
		dev_err(dev, "failed get genpd\n");
		goto fail_vdev;
	}
	genpd->domain.ops.suspend = hdmi_suspend;
	genpd->domain.ops.resume = hdmi_resume;
#endif

	pm_runtime_enable(dev);

	hdmi_dev->hpd_switch.name = "hdmi";
	switch_dev_register(&hdmi_dev->hpd_switch);
	hdmi_dev->hpd_audio_switch.name = "hdmi_audio";
	switch_dev_register(&hdmi_dev->hpd_audio_switch);

	ret = request_irq(hdmi_dev->int_irq, hdmi_irq_handler,
			0, "hdmi-int", hdmi_dev);
	if (ret) {
		dev_err(dev, "request int interrupt failed.\n");
		goto fail_vdev;
	}
	disable_irq(hdmi_dev->int_irq);

	s5p_v4l2_int_src_ext_hpd();
	ret = request_irq(hdmi_dev->ext_irq, hdmi_irq_handler_ext,
			IRQ_TYPE_EDGE_BOTH, "hdmi-ext", hdmi_dev);
	if (ret) {
		dev_err(dev, "request ext interrupt failed.\n");
		goto fail_ext;
	}

	hdmi_dev->cur_preset = HDMI_DEFAULT_PRESET;
	/* FIXME: missing fail preset is not supported */
	hdmi_dev->cur_conf = hdmi_preset2conf(hdmi_dev->cur_preset);

	/* default audio configuration : disable audio */
	hdmi_dev->audio_enable = 0;
	hdmi_dev->audio_channel_count = 2;
	hdmi_dev->sample_rate = DEFAULT_SAMPLE_RATE;
	hdmi_dev->color_range = 3;
	hdmi_dev->bits_per_sample = DEFAULT_BITS_PER_SAMPLE;
	hdmi_dev->audio_codec = DEFAULT_AUDIO_CODEC;

	/* default aspect ratio is 16:9 */
	hdmi_dev->aspect = HDMI_ASPECT_RATIO_16_9;

	/* register hdmi subdev as entity */
	ret = hdmi_register_entity(hdmi_dev);
	if (ret)
		goto fail_irq;

	hdmi_entity_info_print(hdmi_dev);

	/* initialize hdcp resource */
	ret = hdcp_prepare(hdmi_dev);
	if (ret)
		goto fail_irq;

	queue_delayed_work(system_nrt_wq, &hdmi_dev->hpd_work_ext,
					  msecs_to_jiffies(1000));

	dev_info(dev, "probe sucessful\n");

	hdmi_debugfs_init(hdmi_dev);

	return 0;

fail_irq:
	free_irq(hdmi_dev->ext_irq, hdmi_dev);

fail_ext:
	free_irq(hdmi_dev->int_irq, hdmi_dev);

fail_vdev:
	v4l2_device_unregister(&hdmi_dev->v4l2_dev);

fail_regs:
	iounmap(hdmi_dev->regs);

fail_init:
	hdmi_resources_cleanup(hdmi_dev);

fail_hdev:
	kfree(hdmi_dev);

fail:
	dev_err(dev, "probe failed\n");
	return ret;
}
Exemplo n.º 16
0
static int __devinit fimc_md_probe(struct platform_device *pdev)
{
	struct v4l2_device *v4l2_dev;
	struct fimc_md *fmd;
	int ret;

	fmd = kzalloc(sizeof(struct fimc_md), 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);
		goto err1;
	}
	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);
err1:
	kfree(fmd);
	return ret;
}
Exemplo n.º 17
0
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);
	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;
}
Exemplo n.º 18
0
static int 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 err_md;
	}
	ret = fimc_md_get_clocks(fmd);
	if (ret)
		goto err_clk;

	fmd->user_subdev_api = false;

	/* Protect the media graph while we're registering entities */
	mutex_lock(&fmd->media_dev.graph_mutex);

	ret = fimc_md_register_platform_entities(fmd);
	if (ret)
		goto err_unlock;

	if (pdev->dev.platform_data) {
		ret = fimc_md_register_sensor_entities(fmd);
		if (ret)
			goto err_unlock;
	}
	ret = fimc_md_create_links(fmd);
	if (ret)
		goto err_unlock;
	ret = v4l2_device_register_subdev_nodes(&fmd->v4l2_dev);
	if (ret)
		goto err_unlock;

	ret = device_create_file(&pdev->dev, &dev_attr_subdev_conf_mode);
	if (ret)
		goto err_unlock;

	platform_set_drvdata(pdev, fmd);
	mutex_unlock(&fmd->media_dev.graph_mutex);
	return 0;

err_unlock:
	mutex_unlock(&fmd->media_dev.graph_mutex);
err_clk:
	media_device_unregister(&fmd->media_dev);
	fimc_md_put_clocks(fmd);
	fimc_md_unregister_entities(fmd);
err_md:
	v4l2_device_unregister(&fmd->v4l2_dev);
	return ret;
}
Exemplo n.º 19
0
static int hva_probe(struct platform_device *pdev)
{
	struct hva_dev *hva;
	struct device *dev = &pdev->dev;
	int ret;

	hva = devm_kzalloc(dev, sizeof(*hva), GFP_KERNEL);
	if (!hva) {
		ret = -ENOMEM;
		goto err;
	}

	hva->dev = dev;
	hva->pdev = pdev;
	platform_set_drvdata(pdev, hva);

	mutex_init(&hva->lock);

	/* probe hardware */
	ret = hva_hw_probe(pdev, hva);
	if (ret)
		goto err;

	/* register all available encoders */
	register_encoders(hva);

	/* register all supported formats */
	register_formats(hva);

	/* register on V4L2 */
	ret = v4l2_device_register(dev, &hva->v4l2_dev);
	if (ret) {
		dev_err(dev, "%s %s failed to register V4L2 device\n",
			HVA_PREFIX, HVA_NAME);
		goto err_hw;
	}

	hva->work_queue = create_workqueue(HVA_NAME);
	if (!hva->work_queue) {
		dev_err(dev, "%s %s failed to allocate work queue\n",
			HVA_PREFIX, HVA_NAME);
		ret = -ENOMEM;
		goto err_v4l2;
	}

	/* register device */
	ret = hva_register_device(hva);
	if (ret)
		goto err_work_queue;

	dev_info(dev, "%s %s registered as /dev/video%d\n", HVA_PREFIX,
		 HVA_NAME, hva->vdev->num);

	return 0;

err_work_queue:
	destroy_workqueue(hva->work_queue);
err_v4l2:
	v4l2_device_unregister(&hva->v4l2_dev);
err_hw:
	hva_hw_remove(hva);
err:
	return ret;
}
Exemplo n.º 20
0
/*
 * vpif_probe: This function creates device entries by register itself to the
 * V4L2 driver and initializes fields of each channel objects
 */
static __init int vpif_probe(struct platform_device *pdev)
{
	struct vpif_subdev_info *subdevdata;
	struct vpif_display_config *config;
	int i, j = 0, k, q, m, err = 0;
	struct i2c_adapter *i2c_adap;
	struct common_obj *common;
	struct channel_obj *ch;
	struct video_device *vfd;
	struct resource *res;
	int subdev_count;

	vpif_dev = &pdev->dev;

	err = initialize_vpif();

	if (err) {
		v4l2_err(vpif_dev->driver, "Error initializing vpif\n");
		return err;
	}

	err = v4l2_device_register(vpif_dev, &vpif_obj.v4l2_dev);
	if (err) {
		v4l2_err(vpif_dev->driver, "Error registering v4l2 device\n");
		return err;
	}

	k = 0;
	while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, k))) {
		for (i = res->start; i <= res->end; i++) {
			if (request_irq(i, vpif_channel_isr, IRQF_DISABLED,
					"DM646x_Display",
				(void *)(&vpif_obj.dev[k]->channel_id))) {
				err = -EBUSY;
				goto vpif_int_err;
			}
		}
		k++;
	}

	for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {

		/* Get the pointer to the channel object */
		ch = vpif_obj.dev[i];

		/* Allocate memory for video device */
		vfd = video_device_alloc();
		if (vfd == NULL) {
			for (j = 0; j < i; j++) {
				ch = vpif_obj.dev[j];
				video_device_release(ch->video_dev);
			}
			err = -ENOMEM;
			goto vpif_int_err;
		}

		/* Initialize field of video device */
		*vfd = vpif_video_template;
		vfd->v4l2_dev = &vpif_obj.v4l2_dev;
		vfd->release = video_device_release;
		snprintf(vfd->name, sizeof(vfd->name),
			 "DM646x_VPIFDisplay_DRIVER_V%d.%d.%d",
			 (VPIF_DISPLAY_VERSION_CODE >> 16) & 0xff,
			 (VPIF_DISPLAY_VERSION_CODE >> 8) & 0xff,
			 (VPIF_DISPLAY_VERSION_CODE) & 0xff);

		/* Set video_dev to the video device */
		ch->video_dev = vfd;
	}

	for (j = 0; j < VPIF_DISPLAY_MAX_DEVICES; j++) {
		ch = vpif_obj.dev[j];
		/* Initialize field of the channel objects */
		atomic_set(&ch->usrs, 0);
		for (k = 0; k < VPIF_NUMOBJECTS; k++) {
			ch->common[k].numbuffers = 0;
			common = &ch->common[k];
			common->io_usrs = 0;
			common->started = 0;
			spin_lock_init(&common->irqlock);
			mutex_init(&common->lock);
			common->numbuffers = 0;
			common->set_addr = NULL;
			common->ytop_off = common->ybtm_off = 0;
			common->ctop_off = common->cbtm_off = 0;
			common->cur_frm = common->next_frm = NULL;
			memset(&common->fmt, 0, sizeof(common->fmt));
			common->numbuffers = config_params.numbuffers[k];

		}
		ch->initialized = 0;
		ch->channel_id = j;
		if (j < 2)
			ch->common[VPIF_VIDEO_INDEX].numbuffers =
			    config_params.numbuffers[ch->channel_id];
		else
			ch->common[VPIF_VIDEO_INDEX].numbuffers = 0;

		memset(&ch->vpifparams, 0, sizeof(ch->vpifparams));

		/* Initialize prio member of channel object */
		v4l2_prio_init(&ch->prio);
		ch->common[VPIF_VIDEO_INDEX].fmt.type =
						V4L2_BUF_TYPE_VIDEO_OUTPUT;

		/* register video device */
		vpif_dbg(1, debug, "channel=%x,channel->video_dev=%x\n",
				(int)ch, (int)&ch->video_dev);

		err = video_register_device(ch->video_dev,
					  VFL_TYPE_GRABBER, (j ? 3 : 2));
		if (err < 0)
			goto probe_out;

		video_set_drvdata(ch->video_dev, ch);
	}

	i2c_adap = i2c_get_adapter(1);
	config = pdev->dev.platform_data;
	subdev_count = config->subdev_count;
	subdevdata = config->subdevinfo;
	vpif_obj.sd = 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;
	}

	for (i = 0; i < subdev_count; i++) {
		vpif_obj.sd[i] = v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
						i2c_adap, subdevdata[i].name,
						&subdevdata[i].board_info,
						NULL);
		if (!vpif_obj.sd[i]) {
			vpif_err("Error registering v4l2 subdevice\n");
			goto probe_subdev_out;
		}

		if (vpif_obj.sd[i])
			vpif_obj.sd[i]->grp_id = 1 << i;
	}

	return 0;

probe_subdev_out:
	kfree(vpif_obj.sd);
probe_out:
	for (k = 0; k < j; k++) {
		ch = vpif_obj.dev[k];
		video_unregister_device(ch->video_dev);
		video_device_release(ch->video_dev);
		ch->video_dev = NULL;
	}
vpif_int_err:
	v4l2_device_unregister(&vpif_obj.v4l2_dev);
	vpif_err("VPIF IRQ request failed\n");
	for (q = k; k >= 0; k--) {
		for (m = i; m >= res->start; m--)
			free_irq(m, (void *)(&vpif_obj.dev[k]->channel_id));
		res = platform_get_resource(pdev, IORESOURCE_IRQ, k-1);
		m = res->end;
	}

	return err;
}
Exemplo n.º 21
0
static int g2d_probe(struct platform_device *pdev)
{
	struct g2d_dev *dev;
	struct video_device *vfd;
	struct resource *res;
	const struct of_device_id *of_id;
	int ret = 0;

	dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
	if (!dev)
		return -ENOMEM;

	spin_lock_init(&dev->ctrl_lock);
	mutex_init(&dev->mutex);
	atomic_set(&dev->num_inst, 0);
	init_waitqueue_head(&dev->irq_queue);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	dev->regs = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(dev->regs))
		return PTR_ERR(dev->regs);

	dev->clk = clk_get(&pdev->dev, "sclk_fimg2d");
	if (IS_ERR(dev->clk)) {
		dev_err(&pdev->dev, "failed to get g2d clock\n");
		return -ENXIO;
	}

	ret = clk_prepare(dev->clk);
	if (ret) {
		dev_err(&pdev->dev, "failed to prepare g2d clock\n");
		goto put_clk;
	}

	dev->gate = clk_get(&pdev->dev, "fimg2d");
	if (IS_ERR(dev->gate)) {
		dev_err(&pdev->dev, "failed to get g2d clock gate\n");
		ret = -ENXIO;
		goto unprep_clk;
	}

	ret = clk_prepare(dev->gate);
	if (ret) {
		dev_err(&pdev->dev, "failed to prepare g2d clock gate\n");
		goto put_clk_gate;
	}

	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (!res) {
		dev_err(&pdev->dev, "failed to find IRQ\n");
		ret = -ENXIO;
		goto unprep_clk_gate;
	}

	dev->irq = res->start;

	ret = devm_request_irq(&pdev->dev, dev->irq, g2d_isr,
						0, pdev->name, dev);
	if (ret) {
		dev_err(&pdev->dev, "failed to install IRQ\n");
		goto put_clk_gate;
	}

	dev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
	if (IS_ERR(dev->alloc_ctx)) {
		ret = PTR_ERR(dev->alloc_ctx);
		goto unprep_clk_gate;
	}

	ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
	if (ret)
		goto alloc_ctx_cleanup;
	vfd = video_device_alloc();
	if (!vfd) {
		v4l2_err(&dev->v4l2_dev, "Failed to allocate video device\n");
		ret = -ENOMEM;
		goto unreg_v4l2_dev;
	}
	*vfd = g2d_videodev;
	vfd->lock = &dev->mutex;
	ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
	if (ret) {
		v4l2_err(&dev->v4l2_dev, "Failed to register video device\n");
		goto rel_vdev;
	}
	video_set_drvdata(vfd, dev);
	snprintf(vfd->name, sizeof(vfd->name), "%s", g2d_videodev.name);
	dev->vfd = vfd;
	v4l2_info(&dev->v4l2_dev, "device registered as /dev/video%d\n",
								vfd->num);
	platform_set_drvdata(pdev, dev);
	dev->m2m_dev = v4l2_m2m_init(&g2d_m2m_ops);
	if (IS_ERR(dev->m2m_dev)) {
		v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem device\n");
		ret = PTR_ERR(dev->m2m_dev);
		goto unreg_video_dev;
	}

	def_frame.stride = (def_frame.width * def_frame.fmt->depth) >> 3;

	if (!pdev->dev.of_node) {
		dev->variant = g2d_get_drv_data(pdev);
	} else {
		of_id = of_match_node(exynos_g2d_match, pdev->dev.of_node);
		if (!of_id) {
			ret = -ENODEV;
			goto unreg_video_dev;
		}
		dev->variant = (struct g2d_variant *)of_id->data;
	}

	return 0;

unreg_video_dev:
	video_unregister_device(dev->vfd);
rel_vdev:
	video_device_release(vfd);
unreg_v4l2_dev:
	v4l2_device_unregister(&dev->v4l2_dev);
alloc_ctx_cleanup:
	vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
unprep_clk_gate:
	clk_unprepare(dev->gate);
put_clk_gate:
	clk_put(dev->gate);
unprep_clk:
	clk_unprepare(dev->clk);
put_clk:
	clk_put(dev->clk);

	return ret;
}
static int32_t cam_dummy_platform_probe(struct platform_device *pdev)
{
	int32_t rc = 0;
	const struct of_device_id *match;
	struct msm_video_device *pvdev;

	/* init_waitqueue_head(&cam_dummy_queue.state_wait);*/
	pr_err("%s:%d\n", __func__, __LINE__);
	match = of_match_device(cam_dummy_dt_match, &pdev->dev);

	msm_v4l2_dev = kzalloc(sizeof(*msm_v4l2_dev),
		GFP_KERNEL);
	if (WARN_ON(!msm_v4l2_dev)) {
		rc = -ENOMEM;
		goto probe_end;
	}

	pvdev = kzalloc(sizeof(struct msm_video_device),
		GFP_KERNEL);
	if (WARN_ON(!pvdev)) {
		rc = -ENOMEM;
		goto pvdev_fail;
	}

	pvdev->vdev = video_device_alloc();
	if (WARN_ON(!pvdev->vdev)) {
		rc = -ENOMEM;
		goto video_fail;
	}

#if defined(CONFIG_MEDIA_CONTROLLER)
	msm_v4l2_dev->mdev = kzalloc(sizeof(struct media_device),
		GFP_KERNEL);
	if (!msm_v4l2_dev->mdev) {
		rc = -ENOMEM;
		goto mdev_fail;
	}
	strlcpy(msm_v4l2_dev->mdev->model, MSM_CAMERA_DUMMY_NAME,
			sizeof(msm_v4l2_dev->mdev->model));
	msm_v4l2_dev->mdev->dev = &(pdev->dev);

	rc = media_device_register(msm_v4l2_dev->mdev);
	if (WARN_ON(rc < 0))
		goto media_fail;

	if (WARN_ON((rc == media_entity_init(&pvdev->vdev->entity,
			0, NULL, 0)) < 0))
		goto entity_fail;

	pvdev->vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
	pvdev->vdev->entity.group_id = QCAMERA_VNODE_GROUP_ID;
#endif

	pvdev->vdev->v4l2_dev = msm_v4l2_dev;

	rc = v4l2_device_register(&(pdev->dev), pvdev->vdev->v4l2_dev);
	if (WARN_ON(rc < 0))
		goto register_fail;

	strlcpy(pvdev->vdev->name, "msm-camdummy", sizeof(pvdev->vdev->name));
	pvdev->vdev->release  = video_device_release;
	pvdev->vdev->fops     = &msm_fops_config;
#if defined CONFIG_SEC_CAMERA_TUNING
	pvdev->vdev->ioctl_ops = &msm_v4l2_ioctl_ops;
#endif
	pvdev->vdev->minor     = -1;
	pvdev->vdev->vfl_type  = VFL_TYPE_GRABBER;
	rc = video_register_device(pvdev->vdev,
		VFL_TYPE_GRABBER, -1);
	if (WARN_ON(rc < 0))
		goto v4l2_fail;

#if defined(CONFIG_MEDIA_CONTROLLER)
	/* FIXME: How to get rid of this messy? */
	pvdev->vdev->entity.name = video_device_node_name(pvdev->vdev);
#endif

	atomic_set(&pvdev->opened, 0);
	video_set_drvdata(pvdev->vdev, pvdev);

	goto probe_end;

v4l2_fail:
	v4l2_device_unregister(pvdev->vdev->v4l2_dev);
register_fail:
#if defined(CONFIG_MEDIA_CONTROLLER)
	media_entity_cleanup(&pvdev->vdev->entity);
entity_fail:
	media_device_unregister(msm_v4l2_dev->mdev);
media_fail:
	kzfree(msm_v4l2_dev->mdev);
mdev_fail:
#endif
	video_device_release(pvdev->vdev);
video_fail:
	kzfree(pvdev);
pvdev_fail:
	kzfree(msm_v4l2_dev);
probe_end:
	return rc;
}
Exemplo n.º 23
0
/**
 * vpbe_initialize() - Initialize the vpbe display controller
 * @vpbe_dev - vpbe device ptr
 *
 * Master frame buffer device drivers calls this to initialize vpbe
 * display controller. This will then registers v4l2 device and the sub
 * devices and sets a current encoder sub device for display. v4l2 display
 * device driver is the master and frame buffer display device driver is
 * the slave. Frame buffer display driver checks the initialized during
 * probe and exit if not initialized. Returns status.
 */
static int vpbe_initialize(struct device *dev, struct vpbe_device *vpbe_dev)
{
	struct encoder_config_info *enc_info;
	struct amp_config_info *amp_info;
	struct v4l2_subdev **enc_subdev;
	struct osd_state *osd_device;
	struct i2c_adapter *i2c_adap;
	int num_encoders;
	int ret = 0;
	int err;
	int i;

	/*
	 * v4l2 abd FBDev frame buffer devices will get the vpbe_dev pointer
	 * from the platform device by iteration of platform drivers and
	 * matching with device name
	 */
	if (NULL == vpbe_dev || NULL == dev) {
		printk(KERN_ERR "Null device pointers.\n");
		return -ENODEV;
	}

	if (vpbe_dev->initialized)
		return 0;

	mutex_lock(&vpbe_dev->lock);

	if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) {
		/* We have dac clock available for platform */
		vpbe_dev->dac_clk = clk_get(vpbe_dev->pdev, "vpss_dac");
		if (IS_ERR(vpbe_dev->dac_clk)) {
			ret =  PTR_ERR(vpbe_dev->dac_clk);
			goto fail_mutex_unlock;
		}
		if (clk_prepare_enable(vpbe_dev->dac_clk)) {
			ret =  -ENODEV;
			goto fail_mutex_unlock;
		}
	}

	/* first enable vpss clocks */
	vpss_enable_clock(VPSS_VPBE_CLOCK, 1);

	/* First register a v4l2 device */
	ret = v4l2_device_register(dev, &vpbe_dev->v4l2_dev);
	if (ret) {
		v4l2_err(dev->driver,
			"Unable to register v4l2 device.\n");
		goto fail_clk_put;
	}
	v4l2_info(&vpbe_dev->v4l2_dev, "vpbe v4l2 device registered\n");

	err = bus_for_each_dev(&platform_bus_type, NULL, vpbe_dev,
			       platform_device_get);
	if (err < 0) {
		ret = err;
		goto fail_dev_unregister;
	}

	vpbe_dev->venc = venc_sub_dev_init(&vpbe_dev->v4l2_dev,
					   vpbe_dev->cfg->venc.module_name);
	/* register venc sub device */
	if (vpbe_dev->venc == NULL) {
		v4l2_err(&vpbe_dev->v4l2_dev,
			"vpbe unable to init venc sub device\n");
		ret = -ENODEV;
		goto fail_dev_unregister;
	}
	/* initialize osd device */
	osd_device = vpbe_dev->osd_device;

	if (NULL != osd_device->ops.initialize) {
		err = osd_device->ops.initialize(osd_device);
		if (err) {
			v4l2_err(&vpbe_dev->v4l2_dev,
				 "unable to initialize the OSD device");
			err = -ENOMEM;
			goto fail_dev_unregister;
		}
	}

	/*
	 * Register any external encoders that are configured. At index 0 we
	 * store venc sd index.
	 */
	num_encoders = vpbe_dev->cfg->num_ext_encoders + 1;
	vpbe_dev->encoders = kmalloc(
				sizeof(struct v4l2_subdev *)*num_encoders,
				GFP_KERNEL);
	if (NULL == vpbe_dev->encoders) {
		v4l2_err(&vpbe_dev->v4l2_dev,
			"unable to allocate memory for encoders sub devices");
		ret = -ENOMEM;
		goto fail_dev_unregister;
	}

	i2c_adap = i2c_get_adapter(vpbe_dev->cfg->i2c_adapter_id);
	for (i = 0; i < (vpbe_dev->cfg->num_ext_encoders + 1); i++) {
		if (i == 0) {
			/* venc is at index 0 */
			enc_subdev = &vpbe_dev->encoders[i];
			*enc_subdev = vpbe_dev->venc;
			continue;
		}
		enc_info = &vpbe_dev->cfg->ext_encoders[i];
		if (enc_info->is_i2c) {
			enc_subdev = &vpbe_dev->encoders[i];
			*enc_subdev = v4l2_i2c_new_subdev_board(
						&vpbe_dev->v4l2_dev, i2c_adap,
						&enc_info->board_info, NULL);
			if (*enc_subdev)
				v4l2_info(&vpbe_dev->v4l2_dev,
					  "v4l2 sub device %s registered\n",
					  enc_info->module_name);
			else {
				v4l2_err(&vpbe_dev->v4l2_dev, "encoder %s"
					 " failed to register",
					 enc_info->module_name);
				ret = -ENODEV;
				goto fail_kfree_encoders;
			}
		} else
			v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c encoders"
				 " currently not supported");
	}
	/* Add amplifier subdevice for dm365 */
	if ((strcmp(vpbe_dev->cfg->module_name, "dm365-vpbe-display") == 0) &&
			vpbe_dev->cfg->amp != NULL) {
		amp_info = vpbe_dev->cfg->amp;
		if (amp_info->is_i2c) {
			vpbe_dev->amp = v4l2_i2c_new_subdev_board(
			&vpbe_dev->v4l2_dev, i2c_adap,
			&amp_info->board_info, NULL);
			if (!vpbe_dev->amp) {
				v4l2_err(&vpbe_dev->v4l2_dev,
					 "amplifier %s failed to register",
					 amp_info->module_name);
				ret = -ENODEV;
				goto fail_kfree_encoders;
			}
			v4l2_info(&vpbe_dev->v4l2_dev,
					  "v4l2 sub device %s registered\n",
					  amp_info->module_name);
		} else {
			    vpbe_dev->amp = NULL;
			    v4l2_warn(&vpbe_dev->v4l2_dev, "non-i2c amplifiers"
			    " currently not supported");
		}
	} else {
	    vpbe_dev->amp = NULL;
	}

	/* set the current encoder and output to that of venc by default */
	vpbe_dev->current_sd_index = 0;
	vpbe_dev->current_out_index = 0;

	mutex_unlock(&vpbe_dev->lock);

	printk(KERN_NOTICE "Setting default output to %s\n", def_output);
	ret = vpbe_set_default_output(vpbe_dev);
	if (ret) {
		v4l2_err(&vpbe_dev->v4l2_dev, "Failed to set default output %s",
			 def_output);
		return ret;
	}

	printk(KERN_NOTICE "Setting default mode to %s\n", def_mode);
	ret = vpbe_set_default_mode(vpbe_dev);
	if (ret) {
		v4l2_err(&vpbe_dev->v4l2_dev, "Failed to set default mode %s",
			 def_mode);
		return ret;
	}
	vpbe_dev->initialized = 1;
	/* TBD handling of bootargs for default output and mode */
	return 0;

fail_kfree_encoders:
	kfree(vpbe_dev->encoders);
fail_dev_unregister:
	v4l2_device_unregister(&vpbe_dev->v4l2_dev);
fail_clk_put:
	if (strcmp(vpbe_dev->cfg->module_name, "dm644x-vpbe-display") != 0) {
		clk_disable_unprepare(vpbe_dev->dac_clk);
		clk_put(vpbe_dev->dac_clk);
	}
fail_mutex_unlock:
	mutex_unlock(&vpbe_dev->lock);
	return ret;
}
Exemplo n.º 24
0
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;
		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_type = 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;
	set_bit(V4L2_FL_USE_FH_PRIO, &pdev->vdev.flags);
	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 CPTCFG_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 CPTCFG_USB_PWC_INPUT_EVDEV
	/* register webcam snapshot button input device */
	pdev->button_dev = input_allocate_device();
	if (!pdev->button_dev) {
		PWC_ERROR("Err, insufficient memory for webcam snapshot button device.");
		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;

err_video_unreg:
	video_unregister_device(&pdev->vdev);
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;
}
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. */
		cx18_process_eeprom(cx);
	}
	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;

	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;

	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 */
	cx18_s_std(NULL, &fh, &cx->tuner_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);
}
Exemplo n.º 26
0
static void unicam_unregister_entities(struct unicam_device *unicam)
{
	kona_unicam_csi2_unregister_entities(&unicam->csi2a);
	v4l2_device_unregister(&unicam->v4l2_dev);
	media_device_unregister(&unicam->media_dev);
}