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; }
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; }
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; }
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; }