Re: [PATCH v4 03/13] [media] exynos5-fimc-is: Add driver core files
Hi, On 08/07/2013 11:03 AM, Arun Kumar K wrote: This driver is for the FIMC-IS IP available in Samsung Exynos5 SoC onwards. This patch adds the core files for the new driver. Signed-off-by: Arun Kumar Karun...@samsung.com Signed-off-by: Kilyeon Imkilyeon...@samsung.com --- drivers/media/platform/exynos5-is/fimc-is-core.c | 413 ++ drivers/media/platform/exynos5-is/fimc-is-core.h | 134 +++ 2 files changed, 547 insertions(+) create mode 100644 drivers/media/platform/exynos5-is/fimc-is-core.c create mode 100644 drivers/media/platform/exynos5-is/fimc-is-core.h diff --git a/drivers/media/platform/exynos5-is/fimc-is-core.c b/drivers/media/platform/exynos5-is/fimc-is-core.c new file mode 100644 index 000..067dea6 --- /dev/null +++ b/drivers/media/platform/exynos5-is/fimc-is-core.c @@ -0,0 +1,413 @@ +/* + * Samsung EXYNOS5 FIMC-IS (Imaging Subsystem) driver +* + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Arun Kumar Karun...@samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#includelinux/bug.h +#includelinux/ctype.h +#includelinux/device.h +#includelinux/debugfs.h +#includelinux/delay.h +#includelinux/errno.h +#includelinux/err.h +#includelinux/firmware.h +#includelinux/fs.h +#includelinux/gpio.h +#includelinux/interrupt.h +#includelinux/kernel.h +#includelinux/list.h +#includelinux/module.h +#includelinux/types.h +#includelinux/platform_device.h +#includelinux/pm_runtime.h +#includelinux/slab.h +#includelinux/videodev2.h +#includelinux/of.h +#includelinux/of_gpio.h +#includelinux/of_address.h +#includelinux/of_platform.h +#includelinux/of_irq.h +#includelinux/pinctrl/consumer.h nit: some entries are not in alphabetical order +#includemedia/v4l2-device.h +#includemedia/v4l2-ioctl.h +#includemedia/v4l2-mem2mem.h +#includemedia/v4l2-of.h +#includemedia/videobuf2-core.h +#includemedia/videobuf2-dma-contig.h + +#include fimc-is.h +#include fimc-is-i2c.h + +#define CLK_MCU_ISP_DIV0_FREQ (200 * 100) +#define CLK_MCU_ISP_DIV1_FREQ (100 * 100) +#define CLK_ISP_DIV0_FREQ (134 * 100) +#define CLK_ISP_DIV1_FREQ (68 * 100) +#define CLK_ISP_DIVMPWM_FREQ (34 * 100) + +static char *fimc_is_clock_name[] = { static const * char const fimc_is_clock_name[] ? + [IS_CLK_ISP]= isp, + [IS_CLK_MCU_ISP]= mcu_isp, + [IS_CLK_ISP_DIV0] = isp_div0, + [IS_CLK_ISP_DIV1] = isp_div1, + [IS_CLK_ISP_DIVMPWM]= isp_divmpwm, + [IS_CLK_MCU_ISP_DIV0] = mcu_isp_div0, + [IS_CLK_MCU_ISP_DIV1] = mcu_isp_div1, +}; + +static void fimc_is_put_clocks(struct fimc_is *is) +{ + int i; + + for (i = 0; i IS_CLK_MAX_NUM; i++) { + if (IS_ERR(is-clock[i])) + continue; + clk_unprepare(is-clock[i]); + clk_put(is-clock[i]); + is-clock[i] = NULL; is-clock[i] = ERR_PTR(-EINVAL); + } +} + +static int fimc_is_get_clocks(struct fimc_is *is) +{ + struct device *dev =is-pdev-dev; + int i, ret; + + for (i = 0; i IS_CLK_MAX_NUM; i++) { + is-clock[i] = clk_get(dev, fimc_is_clock_name[i]); + if (IS_ERR(is-clock[i])) + goto err; + ret = clk_prepare(is-clock[i]); + if (ret 0) { + clk_put(is-clock[i]); + is-clock[i] = ERR_PTR(-EINVAL); + goto err; + } + } + return 0; +err: + fimc_is_put_clocks(is); + pr_err(Failed to get clock: %s\n, fimc_is_clock_name[i]); dev_err(dev, ... + return -ENXIO; +} + +static int fimc_is_configure_clocks(struct fimc_is *is) +{ + int i, ret; + + for (i = 0; i IS_CLK_MAX_NUM; i++) + is-clock[i] = ERR_PTR(-EINVAL); + + ret = fimc_is_get_clocks(is); + if (ret) + return ret; + + /* Set rates */ + ret = clk_set_rate(is-clock[IS_CLK_MCU_ISP_DIV0], + CLK_MCU_ISP_DIV0_FREQ); + if (ret) + return ret; + ret = clk_set_rate(is-clock[IS_CLK_MCU_ISP_DIV1], + CLK_MCU_ISP_DIV1_FREQ); + if (ret) + return ret; + ret = clk_set_rate(is-clock[IS_CLK_ISP_DIV0], CLK_ISP_DIV0_FREQ); + if (ret) + return ret; + ret = clk_set_rate(is-clock[IS_CLK_ISP_DIV1], CLK_ISP_DIV1_FREQ); + if (ret) + return ret; + ret = clk_set_rate(is-clock[IS_CLK_ISP_DIVMPWM], + CLK_ISP_DIVMPWM_FREQ); + return ret; +} + +static void fimc_is_pipelines_destroy(struct fimc_is *is) +{ + int i; + + for (i = 0; i is-drvdata-num_instance; i++) + fimc_is_pipeline_destroy(is-pipeline[i]); +} + +static
[PATCH v4 03/13] [media] exynos5-fimc-is: Add driver core files
This driver is for the FIMC-IS IP available in Samsung Exynos5 SoC onwards. This patch adds the core files for the new driver. Signed-off-by: Arun Kumar K arun...@samsung.com Signed-off-by: Kilyeon Im kilyeon...@samsung.com --- drivers/media/platform/exynos5-is/fimc-is-core.c | 413 ++ drivers/media/platform/exynos5-is/fimc-is-core.h | 134 +++ 2 files changed, 547 insertions(+) create mode 100644 drivers/media/platform/exynos5-is/fimc-is-core.c create mode 100644 drivers/media/platform/exynos5-is/fimc-is-core.h diff --git a/drivers/media/platform/exynos5-is/fimc-is-core.c b/drivers/media/platform/exynos5-is/fimc-is-core.c new file mode 100644 index 000..067dea6 --- /dev/null +++ b/drivers/media/platform/exynos5-is/fimc-is-core.c @@ -0,0 +1,413 @@ +/* + * Samsung EXYNOS5 FIMC-IS (Imaging Subsystem) driver +* + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Arun Kumar K arun...@samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include linux/bug.h +#include linux/ctype.h +#include linux/device.h +#include linux/debugfs.h +#include linux/delay.h +#include linux/errno.h +#include linux/err.h +#include linux/firmware.h +#include linux/fs.h +#include linux/gpio.h +#include linux/interrupt.h +#include linux/kernel.h +#include linux/list.h +#include linux/module.h +#include linux/types.h +#include linux/platform_device.h +#include linux/pm_runtime.h +#include linux/slab.h +#include linux/videodev2.h +#include linux/of.h +#include linux/of_gpio.h +#include linux/of_address.h +#include linux/of_platform.h +#include linux/of_irq.h +#include linux/pinctrl/consumer.h + +#include media/v4l2-device.h +#include media/v4l2-ioctl.h +#include media/v4l2-mem2mem.h +#include media/v4l2-of.h +#include media/videobuf2-core.h +#include media/videobuf2-dma-contig.h + +#include fimc-is.h +#include fimc-is-i2c.h + +#define CLK_MCU_ISP_DIV0_FREQ (200 * 100) +#define CLK_MCU_ISP_DIV1_FREQ (100 * 100) +#define CLK_ISP_DIV0_FREQ (134 * 100) +#define CLK_ISP_DIV1_FREQ (68 * 100) +#define CLK_ISP_DIVMPWM_FREQ (34 * 100) + +static char *fimc_is_clock_name[] = { + [IS_CLK_ISP]= isp, + [IS_CLK_MCU_ISP]= mcu_isp, + [IS_CLK_ISP_DIV0] = isp_div0, + [IS_CLK_ISP_DIV1] = isp_div1, + [IS_CLK_ISP_DIVMPWM]= isp_divmpwm, + [IS_CLK_MCU_ISP_DIV0] = mcu_isp_div0, + [IS_CLK_MCU_ISP_DIV1] = mcu_isp_div1, +}; + +static void fimc_is_put_clocks(struct fimc_is *is) +{ + int i; + + for (i = 0; i IS_CLK_MAX_NUM; i++) { + if (IS_ERR(is-clock[i])) + continue; + clk_unprepare(is-clock[i]); + clk_put(is-clock[i]); + is-clock[i] = NULL; + } +} + +static int fimc_is_get_clocks(struct fimc_is *is) +{ + struct device *dev = is-pdev-dev; + int i, ret; + + for (i = 0; i IS_CLK_MAX_NUM; i++) { + is-clock[i] = clk_get(dev, fimc_is_clock_name[i]); + if (IS_ERR(is-clock[i])) + goto err; + ret = clk_prepare(is-clock[i]); + if (ret 0) { + clk_put(is-clock[i]); + is-clock[i] = ERR_PTR(-EINVAL); + goto err; + } + } + return 0; +err: + fimc_is_put_clocks(is); + pr_err(Failed to get clock: %s\n, fimc_is_clock_name[i]); + return -ENXIO; +} + +static int fimc_is_configure_clocks(struct fimc_is *is) +{ + int i, ret; + + for (i = 0; i IS_CLK_MAX_NUM; i++) + is-clock[i] = ERR_PTR(-EINVAL); + + ret = fimc_is_get_clocks(is); + if (ret) + return ret; + + /* Set rates */ + ret = clk_set_rate(is-clock[IS_CLK_MCU_ISP_DIV0], + CLK_MCU_ISP_DIV0_FREQ); + if (ret) + return ret; + ret = clk_set_rate(is-clock[IS_CLK_MCU_ISP_DIV1], + CLK_MCU_ISP_DIV1_FREQ); + if (ret) + return ret; + ret = clk_set_rate(is-clock[IS_CLK_ISP_DIV0], CLK_ISP_DIV0_FREQ); + if (ret) + return ret; + ret = clk_set_rate(is-clock[IS_CLK_ISP_DIV1], CLK_ISP_DIV1_FREQ); + if (ret) + return ret; + ret = clk_set_rate(is-clock[IS_CLK_ISP_DIVMPWM], + CLK_ISP_DIVMPWM_FREQ); + return ret; +} + +static void fimc_is_pipelines_destroy(struct fimc_is *is) +{ + int i; + + for (i = 0; i is-drvdata-num_instance; i++) + fimc_is_pipeline_destroy(is-pipeline[i]); +} + +static int fimc_is_parse_sensor_config(struct fimc_is *is, unsigned int index, + struct device_node *node) +{ + struct fimc_is_sensor *sensor =