Version:  2.0.40 2.2.26 2.4.37 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6

Linux/drivers/media/platform/exynos4-is/fimc-is.c

  1 /*
  2  * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver
  3  *
  4  * Copyright (C) 2013 Samsung Electronics Co., Ltd.
  5  *
  6  * Authors: Sylwester Nawrocki <s.nawrocki@samsung.com>
  7  *          Younghwan Joo <yhwan.joo@samsung.com>
  8  *
  9  * This program is free software; you can redistribute it and/or modify
 10  * it under the terms of the GNU General Public License version 2 as
 11  * published by the Free Software Foundation.
 12  */
 13 #define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__
 14 
 15 #include <linux/device.h>
 16 #include <linux/debugfs.h>
 17 #include <linux/delay.h>
 18 #include <linux/dma-contiguous.h>
 19 #include <linux/errno.h>
 20 #include <linux/firmware.h>
 21 #include <linux/interrupt.h>
 22 #include <linux/kernel.h>
 23 #include <linux/module.h>
 24 #include <linux/i2c.h>
 25 #include <linux/of_irq.h>
 26 #include <linux/of_address.h>
 27 #include <linux/of_graph.h>
 28 #include <linux/of_platform.h>
 29 #include <linux/platform_device.h>
 30 #include <linux/pm_runtime.h>
 31 #include <linux/slab.h>
 32 #include <linux/types.h>
 33 #include <linux/videodev2.h>
 34 #include <media/videobuf2-dma-contig.h>
 35 
 36 #include "media-dev.h"
 37 #include "fimc-is.h"
 38 #include "fimc-is-command.h"
 39 #include "fimc-is-errno.h"
 40 #include "fimc-is-i2c.h"
 41 #include "fimc-is-param.h"
 42 #include "fimc-is-regs.h"
 43 
 44 
 45 static char *fimc_is_clocks[ISS_CLKS_MAX] = {
 46         [ISS_CLK_PPMUISPX]              = "ppmuispx",
 47         [ISS_CLK_PPMUISPMX]             = "ppmuispmx",
 48         [ISS_CLK_LITE0]                 = "lite0",
 49         [ISS_CLK_LITE1]                 = "lite1",
 50         [ISS_CLK_MPLL]                  = "mpll",
 51         [ISS_CLK_ISP]                   = "isp",
 52         [ISS_CLK_DRC]                   = "drc",
 53         [ISS_CLK_FD]                    = "fd",
 54         [ISS_CLK_MCUISP]                = "mcuisp",
 55         [ISS_CLK_UART]                  = "uart",
 56         [ISS_CLK_ISP_DIV0]              = "ispdiv0",
 57         [ISS_CLK_ISP_DIV1]              = "ispdiv1",
 58         [ISS_CLK_MCUISP_DIV0]           = "mcuispdiv0",
 59         [ISS_CLK_MCUISP_DIV1]           = "mcuispdiv1",
 60         [ISS_CLK_ACLK200]               = "aclk200",
 61         [ISS_CLK_ACLK200_DIV]           = "div_aclk200",
 62         [ISS_CLK_ACLK400MCUISP]         = "aclk400mcuisp",
 63         [ISS_CLK_ACLK400MCUISP_DIV]     = "div_aclk400mcuisp",
 64 };
 65 
 66 static void fimc_is_put_clocks(struct fimc_is *is)
 67 {
 68         int i;
 69 
 70         for (i = 0; i < ISS_CLKS_MAX; i++) {
 71                 if (IS_ERR(is->clocks[i]))
 72                         continue;
 73                 clk_put(is->clocks[i]);
 74                 is->clocks[i] = ERR_PTR(-EINVAL);
 75         }
 76 }
 77 
 78 static int fimc_is_get_clocks(struct fimc_is *is)
 79 {
 80         int i, ret;
 81 
 82         for (i = 0; i < ISS_CLKS_MAX; i++)
 83                 is->clocks[i] = ERR_PTR(-EINVAL);
 84 
 85         for (i = 0; i < ISS_CLKS_MAX; i++) {
 86                 is->clocks[i] = clk_get(&is->pdev->dev, fimc_is_clocks[i]);
 87                 if (IS_ERR(is->clocks[i])) {
 88                         ret = PTR_ERR(is->clocks[i]);
 89                         goto err;
 90                 }
 91         }
 92