static int tegra_camera_release(struct inode *inode, struct file *file)
{
	int ret = 0;
	struct tegra_camera_dev *dev = file->private_data;

	dev_info(dev->dev, "%s\n", __func__);


	mutex_lock(&dev->tegra_camera_lock);
	/* disable HW clock */
	ret = tegra_camera_disable_clk(dev);
	if (ret)
		goto release_exit;
	/* nullify EMC request */
	ret = tegra_camera_disable_emc(dev);
	if (ret)
		goto release_exit;
	/* turn off CSI regulator */
	tegra_camera_power_off(dev);
	if (ret)
		goto release_exit;

release_exit:
	mutex_unlock(&dev->tegra_camera_lock);
	WARN_ON(!atomic_xchg(&dev->in_use, 0));
	return 0;
}
static int tegra_camera_open(struct inode *inode, struct file *file)
{
	int ret;
	struct miscdevice *miscdev = file->private_data;
	struct tegra_camera *camera = container_of(miscdev,
						struct tegra_camera,
						misc_dev);

	dev_info(camera->dev, "%s: ++\n", __func__);

	if (atomic_xchg(&camera->in_use, 1))
		return -EBUSY;

	file->private_data = camera;
	mutex_lock(&camera->tegra_camera_lock);
	/* turn on CSI regulator */
	ret = tegra_camera_power_on(camera);
	if (ret)
		goto power_on_fail;
	/* set EMC request */
	ret = tegra_camera_enable_emc(camera);
	if (ret)
		goto enable_emc_fail;
	/* read initial clock info */
	tegra_camera_init_clk(camera, clock_init);
	/* enable camera HW clock */
	ret = tegra_camera_enable_clk(camera);
	if (ret)
		goto enable_clk_fail;
	mutex_unlock(&camera->tegra_camera_lock);
	return 0;

enable_clk_fail:
	tegra_camera_disable_emc(camera);
enable_emc_fail:
	tegra_camera_power_off(camera);
power_on_fail:
	mutex_unlock(&camera->tegra_camera_lock);
	return ret;
}
Exemple #3
0
static int tegra_camera_release(struct inode *inode, struct file *file)
{
	int i;
	struct tegra_camera_dev *dev = file->private_data;

	dev_info(dev->dev, "%s\n", __func__);
	for (i = 0; i < ARRAY_SIZE(tegra_camera_block); i++)
		if (tegra_camera_block[i].is_enabled) {
			tegra_camera_block[i].disable(dev);
			tegra_camera_block[i].is_enabled = false;
		}

	/* If camera blocks are not powergated yet, do it now */
	if (dev->power_refcnt > 0) {
		mutex_lock(&dev->tegra_camera_lock);
		dev->power_refcnt = 1;
		tegra_camera_power_off(dev);
		mutex_unlock(&dev->tegra_camera_lock);
	}
	tegra_camera_disable_avp(dev);
	tegra_camera_disable_emc(dev);
	return 0;
}
Exemple #4
0
static long tegra_camera_ioctl(struct file *file,
			       unsigned int cmd, unsigned long arg)
{
	uint id;
	struct tegra_camera_dev *dev = file->private_data;

	/* first element of arg must be u32 with id of module to talk to */
	if (copy_from_user(&id, (const void __user *)arg, sizeof(uint))) {
		dev_err(dev->dev,
				"%s: Failed to copy arg from user", __func__);
		return -EFAULT;
	}

	if (id >= ARRAY_SIZE(tegra_camera_block)) {
		dev_err(dev->dev,
				"%s: Invalid id to tegra isp ioctl%d\n",
				__func__, id);
		return -EINVAL;
	}

	switch (cmd) {
	case TEGRA_CAMERA_IOCTL_ENABLE:
	{
		int ret = 0;

		mutex_lock(&dev->tegra_camera_lock);
		/* Unpowergate camera blocks (vi, csi and isp)
		   before enabling clocks */
		ret = tegra_camera_power_on(dev);
		if (ret) {
			dev->power_refcnt = 0;
			mutex_unlock(&dev->tegra_camera_lock);
			return ret;
		}

		if (!tegra_camera_block[id].is_enabled) {
			ret = tegra_camera_block[id].enable(dev);
			tegra_camera_block[id].is_enabled = true;
		}
		mutex_unlock(&dev->tegra_camera_lock);
		return ret;
	}
	case TEGRA_CAMERA_IOCTL_DISABLE:
	{
		int ret = 0;

		mutex_lock(&dev->tegra_camera_lock);
		if (tegra_camera_block[id].is_enabled) {
			ret = tegra_camera_block[id].disable(dev);
			tegra_camera_block[id].is_enabled = false;
		}
		/* Powergate camera blocks (vi, csi and isp)
		   after disabling all the clocks */
		if (!ret) {
			ret = tegra_camera_power_off(dev);
		}
		mutex_unlock(&dev->tegra_camera_lock);
		return ret;
	}
	case TEGRA_CAMERA_IOCTL_CLK_SET_RATE:
	{
		int ret;

		if (copy_from_user(&dev->info, (const void __user *)arg,
				   sizeof(struct tegra_camera_clk_info))) {
			dev_err(dev->dev,
				"%s: Failed to copy arg from user\n", __func__);
			return -EFAULT;
		}
		ret = tegra_camera_clk_set_rate(dev);
		if (ret)
			return ret;
		if (copy_to_user((void __user *)arg, &dev->info,
				 sizeof(struct tegra_camera_clk_info))) {
			dev_err(dev->dev,
				"%s: Failed to copy arg to user\n", __func__);
			return -EFAULT;
		}
		return 0;
	}
	case TEGRA_CAMERA_IOCTL_RESET:
		return tegra_camera_reset(dev, id);
	default:
		dev_err(dev->dev,
				"%s: Unknown tegra_camera ioctl.\n", __func__);
		return -EINVAL;
	}
	return 0;
}
Exemple #5
0
static long tegra_camera_ioctl(struct file *file,
                               unsigned int cmd, unsigned long arg)
{
    uint id;
    struct tegra_camera_dev *dev = file->private_data;

    /* first element of arg must be u32 with id of module to talk to */
    if (copy_from_user(&id, (const void __user *)arg, sizeof(uint))) {
        dev_err(dev->dev,
                "%s: Failed to copy arg from user", __func__);
        return -EFAULT;
    }

    if (id >= ARRAY_SIZE(tegra_camera_block)) {
        dev_err(dev->dev,
                "%s: Invalid id to tegra isp ioctl%d\n",
                __func__, id);
        return -EINVAL;
    }

    switch (cmd) {
    case TEGRA_CAMERA_IOCTL_ENABLE:
    {
        int ret = 0;

        mutex_lock(&dev->tegra_camera_lock);
        /* Unpowergate camera blocks (vi, csi and isp)
           before enabling clocks */
        ret = tegra_camera_power_on(dev);
        if (ret) {
            dev->power_refcnt = 0;
            mutex_unlock(&dev->tegra_camera_lock);
            return ret;
        }

        if (!tegra_camera_block[id].is_enabled) {
            ret = tegra_camera_block[id].enable(dev);
            tegra_camera_block[id].is_enabled = true;
        }
        mutex_unlock(&dev->tegra_camera_lock);
        return ret;
    }
    case TEGRA_CAMERA_IOCTL_DISABLE:
    {
        int ret = 0;

        mutex_lock(&dev->tegra_camera_lock);
        if (tegra_camera_block[id].is_enabled) {
            ret = tegra_camera_block[id].disable(dev);
            tegra_camera_block[id].is_enabled = false;
        }
        /* Powergate camera blocks (vi, csi and isp)
           after disabling all the clocks */
        if (!ret) {
            ret = tegra_camera_power_off(dev);
        }
        mutex_unlock(&dev->tegra_camera_lock);
        return ret;
    }
    case TEGRA_CAMERA_IOCTL_CLK_SET_RATE:
    {
        int ret;

        if (copy_from_user(&dev->info, (const void __user *)arg,
                           sizeof(struct tegra_camera_clk_info))) {
            dev_err(dev->dev,
                    "%s: Failed to copy arg from user\n", __func__);
            return -EFAULT;
        }
        ret = tegra_camera_clk_set_rate(dev);
        if (ret)
            return ret;
        if (copy_to_user((void __user *)arg, &dev->info,
                         sizeof(struct tegra_camera_clk_info))) {
            dev_err(dev->dev,
                    "%s: Failed to copy arg to user\n", __func__);
            return -EFAULT;
        }
        return 0;
    }
    case TEGRA_CAMERA_IOCTL_RESET:
        return tegra_camera_reset(dev, id);

    case TEGRA_CAMERA_IOCTL_CAMERA_USECASE:
    {
        int buf[2];

        if (copy_from_user(buf, (const void __user *)arg, sizeof(buf))) {
            pr_err("%s: Failed to copy arg from user\n", __func__);
            return -EFAULT;
        }
        mutex_lock(&dev->tegra_camera_lock);
        current_usecase = buf[1];

#ifdef CONFIG_TEGRA_CPU_FREQ_LOCK
        if (current_usecase == CAMERA_USECASE_PREVIEW)
            // need test to optimize
            tegra_cpu_lock_speed(312000, 760000, 0); /* min and max cpu clock for preview */
        else if (current_usecase == CAMERA_USECASE_CAMERA_CAPTURE)
            tegra_cpu_lock_speed(1000000, 0, 5000); /* for snapshot performance */
        else if (current_usecase == CAMERA_USECASE_VIDEO_RECORD)
        {
            if (current_resolution[1]*current_resolution[2]*current_resolution[3] >= 1280*720*30)
            {
                tegra_cpu_lock_speed(816000, 0, 0); /* for hd-video performance */
            }
            else
            {
                tegra_cpu_unlock_speed();
            }
        }
        else if(current_usecase == CAMERA_USECASE_PREVIEW_STOP)
            tegra_cpu_lock_speed(1000000, 0, 5000); /* for stoping performance */
        else
            tegra_cpu_unlock_speed();
#endif /* CONFIG_TEGRA_CPU_FREQ_LOCK */

#if 1
        if (current_usecase == CAMERA_USECASE_CAMERA_CAPTURE)
            printk(" -- CAMERA_USECASE_CAMERA_CAPTURE --\n");
        else if (current_usecase == CAMERA_USECASE_PREVIEW)
            printk(" -- CAMERA_USECASE_PREVIEW --\n");
        else if ((current_usecase == CAMERA_USECASE_VIDEO_RECORD)
                 && (current_resolution[1]*current_resolution[2]*current_resolution[3] < 1280*720*30))
            printk(" -- CAMERA_USECASE_VIDEO_RECORD : LOW %d*%d*%d--\n", current_resolution[1], current_resolution[2], current_resolution[3]);
        else
        {
            printk(" -- CAMERA_USECASE_VIDEO_RECORD : HIGH over 1280*720*30 --\n");
            printk(" -- CAMERA_USECASE_VIDEO_RECORD : HIGH %d*%d*%d--\n", current_resolution[1], current_resolution[2], current_resolution[3]);
        }
#endif

        mutex_unlock(&dev->tegra_camera_lock);
        break;
    }
    case TEGRA_CAMERA_IOCTL_CAMERA_MODE:
    {

        mutex_lock(&dev->tegra_camera_lock);
        if (copy_from_user(current_resolution, (const void __user *)arg,
                           sizeof(current_resolution))) {
            pr_err("%s: Failed to copy arg from user\n", __func__);
            mutex_unlock(&dev->tegra_camera_lock);
            return -EFAULT;
        }

#if 1
        if (current_usecase == CAMERA_USECASE_CAMERA_CAPTURE)
            printk(" -- CAMERA_USECASE_CAMERA_CAPTURE --\n");
        else if (current_usecase == CAMERA_USECASE_PREVIEW)
            printk(" -- CAMERA_USECASE_PREVIEW --\n");
        else if ((current_usecase == CAMERA_USECASE_VIDEO_RECORD)
                 && (current_resolution[1]*current_resolution[2]*current_resolution[3] < 1280*720*30))
            printk(" -- CAMERA_USECASE_VIDEO_RECORD : LOW %d*%d*%d--\n", current_resolution[1], current_resolution[2], current_resolution[3]);
        else
        {
            printk(" -- CAMERA_USECASE_VIDEO_RECORD : HIGH over 1280*720*30 --\n");
            printk(" -- CAMERA_USECASE_VIDEO_RECORD : HIGH %d*%d*%d--\n", current_resolution[1], current_resolution[2], current_resolution[3]);
        }
#endif
        mutex_unlock(&dev->tegra_camera_lock);
        break;
    }
    default:
        dev_err(dev->dev,
                "%s: Unknown tegra_camera ioctl.\n", __func__);
        return -EINVAL;
    }
    return 0;
}