From 673abd92f999829bdd67d0273c43570a62123a63 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Fri, 18 Feb 2011 15:32:57 +0000 Subject: conf/machine: Drop older machines with no recent updates These are all moving to meta-extras. Ideally in the future machines such as these will be maintained to topic specific layers as we move to a more layer oriented model. If this causes a problem for anyone please discuss it on the mailing list. Signed-off-by: Richard Purdie --- .../0007-omap3isp-Add-CSI2-interface-support.patch | 2384 -------------------- 1 file changed, 2384 deletions(-) delete mode 100644 meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0007-omap3isp-Add-CSI2-interface-support.patch (limited to 'meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0007-omap3isp-Add-CSI2-interface-support.patch') diff --git a/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0007-omap3isp-Add-CSI2-interface-support.patch b/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0007-omap3isp-Add-CSI2-interface-support.patch deleted file mode 100644 index 842f39538..000000000 --- a/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/omap3camera/0007-omap3isp-Add-CSI2-interface-support.patch +++ /dev/null @@ -1,2384 +0,0 @@ -From 9fbe7b786427d981cac890a7407da09232f5d1e2 Mon Sep 17 00:00:00 2001 -From: Sakari Ailus -Date: Tue, 10 Mar 2009 10:49:02 +0200 -Subject: [PATCH] omap3isp: Add CSI2 interface support - -Signed-off-by: Sakari Ailus ---- - drivers/media/video/isp/ispcsi2.c | 2124 +++++++++++++++++++++++++++++++++++++ - drivers/media/video/isp/ispcsi2.h | 232 ++++ - 2 files changed, 2356 insertions(+), 0 deletions(-) - create mode 100644 drivers/media/video/isp/ispcsi2.c - create mode 100644 drivers/media/video/isp/ispcsi2.h - -diff --git a/drivers/media/video/isp/ispcsi2.c b/drivers/media/video/isp/ispcsi2.c -new file mode 100644 -index 0000000..5141b5a ---- /dev/null -+++ b/drivers/media/video/isp/ispcsi2.c -@@ -0,0 +1,2124 @@ -+/* -+ * ispcsi2.c -+ * -+ * Driver Library for ISP CSI Control module in TI's OMAP3 Camera ISP -+ * ISP CSI interface and IRQ related APIs are defined here. -+ * -+ * Copyright (C) 2009 Texas Instruments. -+ * -+ * Contributors: -+ * Sergio Aguirre -+ * Dominic Curran -+ * -+ * This package 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. -+ * -+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR -+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED -+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. -+ */ -+ -+#include -+#include -+ -+#include "isp.h" -+#include "ispreg.h" -+#include "ispcsi2.h" -+ -+static struct isp_csi2_cfg current_csi2_cfg; -+static struct isp_csi2_cfg_update current_csi2_cfg_update; -+ -+static bool update_complexio_cfg1; -+static bool update_phy_cfg0; -+static bool update_phy_cfg1; -+static bool update_ctx_ctrl1[8]; -+static bool update_ctx_ctrl2[8]; -+static bool update_ctx_ctrl3[8]; -+static bool update_timing; -+static bool update_ctrl; -+static bool uses_videoport; -+ -+/** -+ * isp_csi2_complexio_lanes_config - Configuration of CSI2 ComplexIO lanes. -+ * @reqcfg: Pointer to structure containing desired lane configuration -+ * -+ * Validates and saves to internal driver memory the passed configuration. -+ * Returns 0 if successful, or -EINVAL if null pointer is passed, invalid -+ * lane position or polarity is set, and if 2 lanes try to occupy the same -+ * position. To apply this settings, use the isp_csi2_complexio_lanes_update() -+ * function just after calling this function. -+ **/ -+int isp_csi2_complexio_lanes_config(struct isp_csi2_lanes_cfg *reqcfg) -+{ -+ int i; -+ bool pos_occupied[5] = {false, false, false, false, false}; -+ struct isp_csi2_lanes_cfg *currlanes = ¤t_csi2_cfg.lanes; -+ struct isp_csi2_lanes_cfg_update *currlanes_u = -+ ¤t_csi2_cfg_update.lanes; -+ -+ /* Validating parameters sent by driver */ -+ if (reqcfg == NULL) { -+ printk(KERN_ERR "Invalid Complex IO Configuration sent by" -+ " sensor\n"); -+ goto err_einval; -+ } -+ -+ /* Data lanes verification */ -+ for (i = 0; i < 4; i++) { -+ if ((reqcfg->data[i].pol > 1) || (reqcfg->data[i].pos > 5)) { -+ printk(KERN_ERR "Invalid CSI-2 Complex IO configuration" -+ " parameters for data lane #%d\n", i); -+ goto err_einval; -+ } -+ if (pos_occupied[reqcfg->data[i].pos - 1] && -+ reqcfg->data[i].pos > 0) { -+ printk(KERN_ERR "Lane #%d already occupied\n", -+ reqcfg->data[i].pos); -+ goto err_einval; -+ } else -+ pos_occupied[reqcfg->data[i].pos - 1] = true; -+ } -+ -+ /* Clock lane verification */ -+ if ((reqcfg->clk.pol > 1) || (reqcfg->clk.pos > 5) || -+ (reqcfg->clk.pos == 0)) { -+ printk(KERN_ERR "Invalid CSI-2 Complex IO configuration" -+ " parameters for clock lane\n"); -+ goto err_einval; -+ } -+ if (pos_occupied[reqcfg->clk.pos - 1]) { -+ printk(KERN_ERR "Lane #%d already occupied", -+ reqcfg->clk.pos); -+ goto err_einval; -+ } else -+ pos_occupied[reqcfg->clk.pos - 1] = true; -+ -+ for (i = 0; i < 4; i++) { -+ if (currlanes->data[i].pos != reqcfg->data[i].pos) { -+ currlanes->data[i].pos = reqcfg->data[i].pos; -+ currlanes_u->data[i] = true; -+ update_complexio_cfg1 = true; -+ } -+ if (currlanes->data[i].pol != reqcfg->data[i].pol) { -+ currlanes->data[i].pol = reqcfg->data[i].pol; -+ currlanes_u->data[i] = true; -+ update_complexio_cfg1 = true; -+ } -+ } -+ -+ if (currlanes->clk.pos != reqcfg->clk.pos) { -+ currlanes->clk.pos = reqcfg->clk.pos; -+ currlanes_u->clk = true; -+ update_complexio_cfg1 = true; -+ } -+ if (currlanes->clk.pol != reqcfg->clk.pol) { -+ currlanes->clk.pol = reqcfg->clk.pol; -+ currlanes_u->clk = true; -+ update_complexio_cfg1 = true; -+ } -+ return 0; -+err_einval: -+ return -EINVAL; -+} -+ -+/** -+ * isp_csi2_complexio_lanes_update - Applies CSI2 ComplexIO lanes configuration. -+ * @force_update: Flag to force rewrite of registers, even if they haven't been -+ * updated with the isp_csi2_complexio_lanes_config() function. -+ * -+ * It only saves settings when they were previously updated using the -+ * isp_csi2_complexio_lanes_config() function, unless the force_update flag is -+ * set to true. -+ * Always returns 0. -+ **/ -+int isp_csi2_complexio_lanes_update(bool force_update) -+{ -+ struct isp_csi2_lanes_cfg *currlanes = ¤t_csi2_cfg.lanes; -+ struct isp_csi2_lanes_cfg_update *currlanes_u = -+ ¤t_csi2_cfg_update.lanes; -+ u32 reg; -+ int i; -+ -+ if (!update_complexio_cfg1 && !force_update) -+ return 0; -+ -+ reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_COMPLEXIO_CFG1); -+ for (i = 0; i < 4; i++) { -+ if (currlanes_u->data[i] || force_update) { -+ reg &= ~(ISPCSI2_COMPLEXIO_CFG1_DATA_POL_MASK(i + 1) | -+ ISPCSI2_COMPLEXIO_CFG1_DATA_POSITION_MASK(i + -+ 1)); -+ reg |= (currlanes->data[i].pol << -+ ISPCSI2_COMPLEXIO_CFG1_DATA_POL_SHIFT(i + 1)); -+ reg |= (currlanes->data[i].pos << -+ ISPCSI2_COMPLEXIO_CFG1_DATA_POSITION_SHIFT(i + -+ 1)); -+ currlanes_u->data[i] = false; -+ } -+ } -+ -+ if (currlanes_u->clk || force_update) { -+ reg &= ~(ISPCSI2_COMPLEXIO_CFG1_CLOCK_POL_MASK | -+ ISPCSI2_COMPLEXIO_CFG1_CLOCK_POSITION_MASK); -+ reg |= (currlanes->clk.pol << -+ ISPCSI2_COMPLEXIO_CFG1_CLOCK_POL_SHIFT); -+ reg |= (currlanes->clk.pos << -+ ISPCSI2_COMPLEXIO_CFG1_CLOCK_POSITION_SHIFT); -+ currlanes_u->clk = false; -+ } -+ isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_COMPLEXIO_CFG1); -+ -+ update_complexio_cfg1 = false; -+ return 0; -+} -+ -+/** -+ * isp_csi2_complexio_lanes_get - Gets CSI2 ComplexIO lanes configuration. -+ * -+ * Gets settings from HW registers and fills in the internal driver memory -+ * Always returns 0. -+ **/ -+int isp_csi2_complexio_lanes_get(void) -+{ -+ struct isp_csi2_lanes_cfg *currlanes = ¤t_csi2_cfg.lanes; -+ struct isp_csi2_lanes_cfg_update *currlanes_u = -+ ¤t_csi2_cfg_update.lanes; -+ u32 reg; -+ int i; -+ -+ reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_COMPLEXIO_CFG1); -+ for (i = 0; i < 4; i++) { -+ currlanes->data[i].pol = (reg & -+ ISPCSI2_COMPLEXIO_CFG1_DATA_POL_MASK(i + 1)) >> -+ ISPCSI2_COMPLEXIO_CFG1_DATA_POL_SHIFT(i + 1); -+ currlanes->data[i].pos = (reg & -+ ISPCSI2_COMPLEXIO_CFG1_DATA_POSITION_MASK(i + 1)) >> -+ ISPCSI2_COMPLEXIO_CFG1_DATA_POSITION_SHIFT(i + 1); -+ currlanes_u->data[i] = false; -+ } -+ currlanes->clk.pol = (reg & ISPCSI2_COMPLEXIO_CFG1_CLOCK_POL_MASK) >> -+ ISPCSI2_COMPLEXIO_CFG1_CLOCK_POL_SHIFT; -+ currlanes->clk.pos = (reg & -+ ISPCSI2_COMPLEXIO_CFG1_CLOCK_POSITION_MASK) >> -+ ISPCSI2_COMPLEXIO_CFG1_CLOCK_POSITION_SHIFT; -+ currlanes_u->clk = false; -+ -+ update_complexio_cfg1 = false; -+ return 0; -+} -+ -+/** -+ * isp_csi2_complexio_power_status - Gets CSI2 ComplexIO power status. -+ * -+ * Returns 3 possible valid states: ISP_CSI2_POWER_OFF, ISP_CSI2_POWER_ON, -+ * and ISP_CSI2_POWER_ULPW. -+ **/ -+static enum isp_csi2_power_cmds isp_csi2_complexio_power_status(void) -+{ -+ enum isp_csi2_power_cmds ret; -+ u32 reg; -+ -+ reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_COMPLEXIO_CFG1) & -+ ISPCSI2_COMPLEXIO_CFG1_PWR_STATUS_MASK; -+ switch (reg) { -+ case ISPCSI2_COMPLEXIO_CFG1_PWR_STATUS_OFF: -+ ret = ISP_CSI2_POWER_OFF; -+ break; -+ case ISPCSI2_COMPLEXIO_CFG1_PWR_STATUS_ON: -+ ret = ISP_CSI2_POWER_ON; -+ break; -+ case ISPCSI2_COMPLEXIO_CFG1_PWR_STATUS_ULPW: -+ ret = ISP_CSI2_POWER_ULPW; -+ break; -+ default: -+ return -EINVAL; -+ } -+ return ret; -+} -+ -+/** -+ * isp_csi2_complexio_power_autoswitch - Sets CSI2 ComplexIO power autoswitch. -+ * @enable: Sets or clears the autoswitch function enable flag. -+ * -+ * Always returns 0. -+ **/ -+int isp_csi2_complexio_power_autoswitch(bool enable) -+{ -+ u32 reg; -+ -+ reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_COMPLEXIO_CFG1); -+ reg &= ~ISPCSI2_COMPLEXIO_CFG1_PWR_AUTO_MASK; -+ -+ if (enable) -+ reg |= ISPCSI2_COMPLEXIO_CFG1_PWR_AUTO_ENABLE; -+ else -+ reg |= ISPCSI2_COMPLEXIO_CFG1_PWR_AUTO_DISABLE; -+ -+ isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_COMPLEXIO_CFG1); -+ return 0; -+} -+ -+/** -+ * isp_csi2_complexio_power - Sets the desired power command for CSI2 ComplexIO. -+ * @power_cmd: Power command to be set. -+ * -+ * Returns 0 if successful, or -EBUSY if the retry count is exceeded. -+ **/ -+int isp_csi2_complexio_power(enum isp_csi2_power_cmds power_cmd) -+{ -+ enum isp_csi2_power_cmds current_state; -+ u32 reg; -+ u8 retry_count; -+ -+ reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_COMPLEXIO_CFG1) & -+ ~ISPCSI2_COMPLEXIO_CFG1_PWR_CMD_MASK; -+ switch (power_cmd) { -+ case ISP_CSI2_POWER_OFF: -+ reg |= ISPCSI2_COMPLEXIO_CFG1_PWR_CMD_OFF; -+ break; -+ case ISP_CSI2_POWER_ON: -+ reg |= ISPCSI2_COMPLEXIO_CFG1_PWR_CMD_ON; -+ break; -+ case ISP_CSI2_POWER_ULPW: -+ reg |= ISPCSI2_COMPLEXIO_CFG1_PWR_CMD_ULPW; -+ break; -+ default: -+ printk(KERN_ERR "CSI2: ERROR - Wrong Power command!\n"); -+ return -EINVAL; -+ } -+ isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_COMPLEXIO_CFG1); -+ -+ retry_count = 0; -+ do { -+ udelay(50); -+ current_state = isp_csi2_complexio_power_status(); -+ -+ if (current_state != power_cmd) { -+ printk(KERN_DEBUG "CSI2: Complex IO power command not" -+ " yet taken."); -+ if (++retry_count < 100) { -+ printk(KERN_DEBUG " Retrying...\n"); -+ udelay(50); -+ } else { -+ printk(KERN_DEBUG " Retry count exceeded!\n"); -+ } -+ } -+ } while ((current_state != power_cmd) && (retry_count < 100)); -+ -+ if (retry_count == 100) -+ return -EBUSY; -+ -+ return 0; -+} -+ -+/** -+ * isp_csi2_ctrl_config_frame_mode - Configure if_en behaviour for CSI2 -+ * @frame_mode: Desired action for IF_EN switch off. 0 - disable IF immediately -+ * 1 - disable after all Frame end Code is received in all -+ * contexts. -+ * -+ * Validates and saves to internal driver memory the passed configuration. -+ * Always returns 0. -+ **/ -+int isp_csi2_ctrl_config_frame_mode(enum isp_csi2_frame_mode frame_mode) -+{ -+ struct isp_csi2_ctrl_cfg *currctrl = ¤t_csi2_cfg.ctrl; -+ struct isp_csi2_ctrl_cfg_update *currctrl_u = -+ ¤t_csi2_cfg_update.ctrl; -+ -+ if (currctrl->frame_mode != frame_mode) { -+ currctrl->frame_mode = frame_mode; -+ currctrl_u->frame_mode = true; -+ update_ctrl = true; -+ } -+ return 0; -+} -+ -+/** -+ * isp_csi2_ctrl_config_vp_clk_enable - Enables/disables CSI2 Videoport clock. -+ * @vp_clk_enable: Boolean value to specify the Videoport clock state. -+ * -+ * Validates and saves to internal driver memory the passed configuration. -+ * Always returns 0. -+ **/ -+int isp_csi2_ctrl_config_vp_clk_enable(bool vp_clk_enable) -+{ -+ struct isp_csi2_ctrl_cfg *currctrl = ¤t_csi2_cfg.ctrl; -+ struct isp_csi2_ctrl_cfg_update *currctrl_u = -+ ¤t_csi2_cfg_update.ctrl; -+ -+ if (currctrl->vp_clk_enable != vp_clk_enable) { -+ currctrl->vp_clk_enable = vp_clk_enable; -+ currctrl_u->vp_clk_enable = true; -+ update_ctrl = true; -+ } -+ return 0; -+} -+ -+/** -+ * isp_csi2_ctrl_config_vp_only_enable - Sets CSI2 Videoport clock as exclusive -+ * @vp_only_enable: Boolean value to specify if the Videoport clock is -+ * exclusive, setting the OCP port as disabled. -+ * -+ * Validates and saves to internal driver memory the passed configuration. -+ * Always returns 0. -+ **/ -+int isp_csi2_ctrl_config_vp_only_enable(bool vp_only_enable) -+{ -+ struct isp_csi2_ctrl_cfg *currctrl = ¤t_csi2_cfg.ctrl; -+ struct isp_csi2_ctrl_cfg_update *currctrl_u = -+ ¤t_csi2_cfg_update.ctrl; -+ -+ if (currctrl->vp_only_enable != vp_only_enable) { -+ currctrl->vp_only_enable = vp_only_enable; -+ currctrl_u->vp_only_enable = true; -+ update_ctrl = true; -+ } -+ return 0; -+} -+ -+/** -+ * isp_csi2_ctrl_config_vp_out_ctrl - Sets CSI2 Videoport clock divider -+ * @vp_out_ctrl: Divider value for setting videoport clock frequency based on -+ * OCP port frequency, valid dividers are between 1 and 4. -+ * -+ * Validates and saves to internal driver memory the passed configuration. -+ * Returns 0 if successful, or -EINVAL if wrong divider value is passed. -+ **/ -+int isp_csi2_ctrl_config_vp_out_ctrl(u8 vp_out_ctrl) -+{ -+ struct isp_csi2_ctrl_cfg *currctrl = ¤t_csi2_cfg.ctrl; -+ struct isp_csi2_ctrl_cfg_update *currctrl_u = -+ ¤t_csi2_cfg_update.ctrl; -+ -+ if ((vp_out_ctrl == 0) || (vp_out_ctrl > 4)) { -+ printk(KERN_ERR "CSI2: Wrong divisor value. Must be between" -+ " 1 and 4"); -+ return -EINVAL; -+ } -+ -+ if (currctrl->vp_out_ctrl != vp_out_ctrl) { -+ currctrl->vp_out_ctrl = vp_out_ctrl; -+ currctrl_u->vp_out_ctrl = true; -+ update_ctrl = true; -+ } -+ return 0; -+} -+ -+/** -+ * isp_csi2_ctrl_config_debug_enable - Sets CSI2 debug -+ * @debug_enable: Boolean for setting debug configuration on CSI2. -+ * -+ * Always returns 0. -+ **/ -+int isp_csi2_ctrl_config_debug_enable(bool debug_enable) -+{ -+ struct isp_csi2_ctrl_cfg *currctrl = ¤t_csi2_cfg.ctrl; -+ struct isp_csi2_ctrl_cfg_update *currctrl_u = -+ ¤t_csi2_cfg_update.ctrl; -+ -+ if (currctrl->debug_enable != debug_enable) { -+ currctrl->debug_enable = debug_enable; -+ currctrl_u->debug_enable = true; -+ update_ctrl = true; -+ } -+ return 0; -+} -+ -+/** -+ * isp_csi2_ctrl_config_burst_size - Sets CSI2 burst size. -+ * @burst_size: Burst size of the memory saving capability of receiver. -+ * -+ * Returns 0 if successful, or -EINVAL if burst size is wrong. -+ **/ -+int isp_csi2_ctrl_config_burst_size(u8 burst_size) -+{ -+ struct isp_csi2_ctrl_cfg *currctrl = ¤t_csi2_cfg.ctrl; -+ struct isp_csi2_ctrl_cfg_update *currctrl_u = -+ ¤t_csi2_cfg_update.ctrl; -+ if (burst_size > 3) { -+ printk(KERN_ERR "CSI2: Wrong burst size. Must be between" -+ " 0 and 3"); -+ return -EINVAL; -+ } -+ -+ if (currctrl->burst_size != burst_size) { -+ currctrl->burst_size = burst_size; -+ currctrl_u->burst_size = true; -+ update_ctrl = true; -+ } -+ return 0; -+} -+ -+/** -+ * isp_csi2_ctrl_config_ecc_enable - Enables ECC on CSI2 Receiver -+ * @ecc_enable: Boolean to enable/disable the CSI2 receiver ECC handling. -+ * -+ * Always returns 0. -+ **/ -+int isp_csi2_ctrl_config_ecc_enable(bool ecc_enable) -+{ -+ struct isp_csi2_ctrl_cfg *currctrl = ¤t_csi2_cfg.ctrl; -+ struct isp_csi2_ctrl_cfg_update *currctrl_u = -+ ¤t_csi2_cfg_update.ctrl; -+ -+ if (currctrl->ecc_enable != ecc_enable) { -+ currctrl->ecc_enable = ecc_enable; -+ currctrl_u->ecc_enable = true; -+ update_ctrl = true; -+ } -+ return 0; -+} -+ -+/** -+ * isp_csi2_ctrl_config_ecc_enable - Enables ECC on CSI2 Receiver -+ * @ecc_enable: Boolean to enable/disable the CSI2 receiver ECC handling. -+ * -+ * Always returns 0. -+ **/ -+int isp_csi2_ctrl_config_secure_mode(bool secure_mode) -+{ -+ struct isp_csi2_ctrl_cfg *currctrl = ¤t_csi2_cfg.ctrl; -+ struct isp_csi2_ctrl_cfg_update *currctrl_u = -+ ¤t_csi2_cfg_update.ctrl; -+ -+ if (currctrl->secure_mode != secure_mode) { -+ currctrl->secure_mode = secure_mode; -+ currctrl_u->secure_mode = true; -+ update_ctrl = true; -+ } -+ return 0; -+} -+ -+/** -+ * isp_csi2_ctrl_config_if_enable - Enables CSI2 Receiver interface. -+ * @if_enable: Boolean to enable/disable the CSI2 receiver interface. -+ * -+ * Always returns 0. -+ **/ -+int isp_csi2_ctrl_config_if_enable(bool if_enable) -+{ -+ struct isp_csi2_ctrl_cfg *currctrl = ¤t_csi2_cfg.ctrl; -+ struct isp_csi2_ctrl_cfg_update *currctrl_u = -+ ¤t_csi2_cfg_update.ctrl; -+ -+ if (currctrl->if_enable != if_enable) { -+ currctrl->if_enable = if_enable; -+ currctrl_u->if_enable = true; -+ update_ctrl = true; -+ } -+ return 0; -+} -+ -+/** -+ * isp_csi2_ctrl_update - Applies CSI2 control configuration. -+ * @force_update: Flag to force rewrite of registers, even if they haven't been -+ * updated with the isp_csi2_ctrl_config_*() functions. -+ * -+ * It only saves settings when they were previously updated using the -+ * isp_csi2_ctrl_config_*() functions, unless the force_update flag is -+ * set to true. -+ * Always returns 0. -+ **/ -+int isp_csi2_ctrl_update(bool force_update) -+{ -+ struct isp_csi2_ctrl_cfg *currctrl = ¤t_csi2_cfg.ctrl; -+ struct isp_csi2_ctrl_cfg_update *currctrl_u = -+ ¤t_csi2_cfg_update.ctrl; -+ u32 reg; -+ -+ if (update_ctrl || force_update) { -+ reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_CTRL); -+ if (currctrl_u->frame_mode || force_update) { -+ reg &= ~ISPCSI2_CTRL_FRAME_MASK; -+ if (currctrl->frame_mode) -+ reg |= ISPCSI2_CTRL_FRAME_DISABLE_FEC; -+ else -+ reg |= ISPCSI2_CTRL_FRAME_DISABLE_IMM; -+ currctrl_u->frame_mode = false; -+ } -+ if (currctrl_u->vp_clk_enable || force_update) { -+ reg &= ~ISPCSI2_CTRL_VP_CLK_EN_MASK; -+ if (currctrl->vp_clk_enable) -+ reg |= ISPCSI2_CTRL_VP_CLK_EN_ENABLE; -+ else -+ reg |= ISPCSI2_CTRL_VP_CLK_EN_DISABLE; -+ currctrl_u->vp_clk_enable = false; -+ } -+ if (currctrl_u->vp_only_enable || force_update) { -+ reg &= ~ISPCSI2_CTRL_VP_ONLY_EN_MASK; -+ uses_videoport = currctrl->vp_only_enable; -+ if (currctrl->vp_only_enable) -+ reg |= ISPCSI2_CTRL_VP_ONLY_EN_ENABLE; -+ else -+ reg |= ISPCSI2_CTRL_VP_ONLY_EN_DISABLE; -+ currctrl_u->vp_only_enable = false; -+ } -+ if (currctrl_u->vp_out_ctrl || force_update) { -+ reg &= ~ISPCSI2_CTRL_VP_OUT_CTRL_MASK; -+ reg |= (currctrl->vp_out_ctrl - 1) << -+ ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT; -+ currctrl_u->vp_out_ctrl = false; -+ } -+ if (currctrl_u->debug_enable || force_update) { -+ reg &= ~ISPCSI2_CTRL_DBG_EN_MASK; -+ if (currctrl->debug_enable) -+ reg |= ISPCSI2_CTRL_DBG_EN_ENABLE; -+ else -+ reg |= ISPCSI2_CTRL_DBG_EN_DISABLE; -+ currctrl_u->debug_enable = false; -+ } -+ if (currctrl_u->burst_size || force_update) { -+ reg &= ~ISPCSI2_CTRL_BURST_SIZE_MASK; -+ reg |= currctrl->burst_size << -+ ISPCSI2_CTRL_BURST_SIZE_SHIFT; -+ currctrl_u->burst_size = false; -+ } -+ if (currctrl_u->ecc_enable || force_update) { -+ reg &= ~ISPCSI2_CTRL_ECC_EN_MASK; -+ if (currctrl->ecc_enable) -+ reg |= ISPCSI2_CTRL_ECC_EN_ENABLE; -+ else -+ reg |= ISPCSI2_CTRL_ECC_EN_DISABLE; -+ currctrl_u->ecc_enable = false; -+ } -+ if (currctrl_u->secure_mode || force_update) { -+ reg &= ~ISPCSI2_CTRL_SECURE_MASK; -+ if (currctrl->secure_mode) -+ reg |= ISPCSI2_CTRL_SECURE_ENABLE; -+ else -+ reg |= ISPCSI2_CTRL_SECURE_DISABLE; -+ currctrl_u->secure_mode = false; -+ } -+ if (currctrl_u->if_enable || force_update) { -+ reg &= ~ISPCSI2_CTRL_IF_EN_MASK; -+ if (currctrl->if_enable) -+ reg |= ISPCSI2_CTRL_IF_EN_ENABLE; -+ else -+ reg |= ISPCSI2_CTRL_IF_EN_DISABLE; -+ currctrl_u->if_enable = false; -+ } -+ isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_CTRL); -+ update_ctrl = false; -+ } -+ return 0; -+} -+ -+/** -+ * isp_csi2_ctrl_get - Gets CSI2 control configuration -+ * -+ * Always returns 0. -+ **/ -+int isp_csi2_ctrl_get(void) -+{ -+ struct isp_csi2_ctrl_cfg *currctrl = ¤t_csi2_cfg.ctrl; -+ struct isp_csi2_ctrl_cfg_update *currctrl_u = -+ ¤t_csi2_cfg_update.ctrl; -+ u32 reg; -+ -+ reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_CTRL); -+ currctrl->frame_mode = (reg & ISPCSI2_CTRL_FRAME_MASK) >> -+ ISPCSI2_CTRL_FRAME_SHIFT; -+ currctrl_u->frame_mode = false; -+ -+ if ((reg & ISPCSI2_CTRL_VP_CLK_EN_MASK) == -+ ISPCSI2_CTRL_VP_CLK_EN_ENABLE) -+ currctrl->vp_clk_enable = true; -+ else -+ currctrl->vp_clk_enable = false; -+ currctrl_u->vp_clk_enable = false; -+ -+ if ((reg & ISPCSI2_CTRL_VP_ONLY_EN_MASK) == -+ ISPCSI2_CTRL_VP_ONLY_EN_ENABLE) -+ currctrl->vp_only_enable = true; -+ else -+ currctrl->vp_only_enable = false; -+ uses_videoport = currctrl->vp_only_enable; -+ currctrl_u->vp_only_enable = false; -+ -+ currctrl->vp_out_ctrl = ((reg & ISPCSI2_CTRL_VP_OUT_CTRL_MASK) >> -+ ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT) + 1; -+ currctrl_u->vp_out_ctrl = false; -+ -+ if ((reg & ISPCSI2_CTRL_DBG_EN_MASK) == ISPCSI2_CTRL_DBG_EN_ENABLE) -+ currctrl->debug_enable = true; -+ else -+ currctrl->debug_enable = false; -+ currctrl_u->debug_enable = false; -+ -+ currctrl->burst_size = (reg & ISPCSI2_CTRL_BURST_SIZE_MASK) >> -+ ISPCSI2_CTRL_BURST_SIZE_SHIFT; -+ currctrl_u->burst_size = false; -+ -+ if ((reg & ISPCSI2_CTRL_ECC_EN_MASK) == ISPCSI2_CTRL_ECC_EN_ENABLE) -+ currctrl->ecc_enable = true; -+ else -+ currctrl->ecc_enable = false; -+ currctrl_u->ecc_enable = false; -+ -+ if ((reg & ISPCSI2_CTRL_SECURE_MASK) == ISPCSI2_CTRL_SECURE_ENABLE) -+ currctrl->secure_mode = true; -+ else -+ currctrl->secure_mode = false; -+ currctrl_u->secure_mode = false; -+ -+ if ((reg & ISPCSI2_CTRL_IF_EN_MASK) == ISPCSI2_CTRL_IF_EN_ENABLE) -+ currctrl->if_enable = true; -+ else -+ currctrl->if_enable = false; -+ currctrl_u->if_enable = false; -+ -+ update_ctrl = false; -+ return 0; -+} -+ -+/** -+ * isp_csi2_ctx_validate - Validates the context number value -+ * @ctxnum: Pointer to variable containing context number. -+ * -+ * If the value is not in range (3 bits), it is being ANDed with 0x7 to force -+ * it to be on range. -+ **/ -+static void isp_csi2_ctx_validate(u8 *ctxnum) -+{ -+ if (*ctxnum > 7) { -+ printk(KERN_ERR "Invalid context number. Forcing valid" -+ " value...\n"); -+ *ctxnum &= ~(0x7); -+ } -+} -+ -+/** -+ * isp_csi2_ctx_config_virtual_id - Maps a virtual ID with a CSI2 Rx context -+ * @ctxnum: Context number, valid between 0 and 7 values. -+ * @virtual_id: CSI2 Virtual ID to associate with specified context number. -+ * -+ * Returns 0 if successful, or -EINVAL if Virtual ID is not in range (0-3). -+ **/ -+int isp_csi2_ctx_config_virtual_id(u8 ctxnum, u8 virtual_id) -+{ -+ struct isp_csi2_ctx_cfg *selected_ctx; -+ struct isp_csi2_ctx_cfg_update *selected_ctx_u; -+ -+ isp_csi2_ctx_validate(&ctxnum); -+ -+ if (virtual_id > 3) { -+ printk(KERN_ERR "Wrong requested virtual_id\n"); -+ return -EINVAL; -+ } -+ -+ selected_ctx = ¤t_csi2_cfg.contexts[ctxnum]; -+ selected_ctx_u = ¤t_csi2_cfg_update.contexts[ctxnum]; -+ -+ if (selected_ctx->virtual_id != virtual_id) { -+ selected_ctx->virtual_id = virtual_id; -+ selected_ctx_u->virtual_id = true; -+ update_ctx_ctrl2[ctxnum] = true; -+ } -+ -+ return 0; -+} -+ -+/** -+ * isp_csi2_ctx_config_frame_count - Sets frame count to be received in CSI2 Rx. -+ * @ctxnum: Context number, valid between 0 and 7 values. -+ * @frame_count: Number of frames to acquire. -+ * -+ * Always returns 0. -+ **/ -+int isp_csi2_ctx_config_frame_count(u8 ctxnum, u8 frame_count) -+{ -+ struct isp_csi2_ctx_cfg *selected_ctx; -+ struct isp_csi2_ctx_cfg_update *selected_ctx_u; -+ -+ isp_csi2_ctx_validate(&ctxnum); -+ -+ selected_ctx = ¤t_csi2_cfg.contexts[ctxnum]; -+ selected_ctx_u = ¤t_csi2_cfg_update.contexts[ctxnum]; -+ -+ if (selected_ctx->frame_count != frame_count) { -+ selected_ctx->frame_count = frame_count; -+ selected_ctx_u->frame_count = true; -+ update_ctx_ctrl1[ctxnum] = true; -+ } -+ -+ return 0; -+} -+ -+/** -+ * isp_csi2_ctx_config_format - Maps a pixel format to a specified context. -+ * @ctxnum: Context number, valid between 0 and 7 values. -+ * @pixformat: V4L2 structure for pixel format. -+ * -+ * Returns 0 if successful, or -EINVAL if the format is not supported by the -+ * receiver. -+ **/ -+int isp_csi2_ctx_config_format(u8 ctxnum, u32 pixformat) -+{ -+ struct isp_csi2_ctx_cfg *selected_ctx; -+ struct isp_csi2_ctx_cfg_update *selected_ctx_u; -+ struct v4l2_pix_format pix; -+ -+ isp_csi2_ctx_validate(&ctxnum); -+ -+ pix.pixelformat = pixformat; -+ switch (pix.pixelformat) { -+ case V4L2_PIX_FMT_RGB565: -+ case V4L2_PIX_FMT_RGB565X: -+ case V4L2_PIX_FMT_YUYV: -+ case V4L2_PIX_FMT_UYVY: -+ case V4L2_PIX_FMT_RGB555: -+ case V4L2_PIX_FMT_RGB555X: -+ case V4L2_PIX_FMT_SGRBG10: -+ break; -+ default: -+ printk(KERN_ERR "Context config pixel format unsupported\n"); -+ return -EINVAL; -+ } -+ -+ selected_ctx = ¤t_csi2_cfg.contexts[ctxnum]; -+ selected_ctx_u = ¤t_csi2_cfg_update.contexts[ctxnum]; -+ -+ selected_ctx->format = pix; -+ selected_ctx_u->format = true; -+ update_ctx_ctrl2[ctxnum] = true; -+ -+ return 0; -+} -+ -+/** -+ * isp_csi2_ctx_config_alpha - Sets the alpha value for pixel format -+ * @ctxnum: Context number, valid between 0 and 7 values. -+ * @alpha: Alpha value. -+ * -+ * Returns 0 if successful, or -EINVAL if the alpha value is bigger than 16383. -+ **/ -+int isp_csi2_ctx_config_alpha(u8 ctxnum, u16 alpha) -+{ -+ struct isp_csi2_ctx_cfg *selected_ctx; -+ struct isp_csi2_ctx_cfg_update *selected_ctx_u; -+ -+ isp_csi2_ctx_validate(&ctxnum); -+ -+ if (alpha > 0x3FFF) { -+ printk(KERN_ERR "Wrong alpha value\n"); -+ return -EINVAL; -+ } -+ -+ selected_ctx = ¤t_csi2_cfg.contexts[ctxnum]; -+ selected_ctx_u = ¤t_csi2_cfg_update.contexts[ctxnum]; -+ -+ if (selected_ctx->alpha != alpha) { -+ selected_ctx->alpha = alpha; -+ selected_ctx_u->alpha = true; -+ update_ctx_ctrl3[ctxnum] = true; -+ } -+ return 0; -+} -+ -+/** -+ * isp_csi2_ctx_config_data_offset - Sets the offset between received lines -+ * @ctxnum: Context number, valid between 0 and 7 values. -+ * @data_offset: Offset between first pixel of each 2 contiguous lines. -+ * -+ * Returns 0 if successful, or -EINVAL if the line offset is bigger than 1023. -+ **/ -+int isp_csi2_ctx_config_data_offset(u8 ctxnum, u16 data_offset) -+{ -+ struct isp_csi2_ctx_cfg *selected_ctx; -+ struct isp_csi2_ctx_cfg_update *selected_ctx_u; -+ -+ isp_csi2_ctx_validate(&ctxnum); -+ -+ if (data_offset > 0x3FF) { -+ printk(KERN_ERR "Wrong line offset\n"); -+ return -EINVAL; -+ } -+ -+ selected_ctx = ¤t_csi2_cfg.contexts[ctxnum]; -+ selected_ctx_u = ¤t_csi2_cfg_update.contexts[ctxnum]; -+ -+ if (selected_ctx->data_offset != data_offset) { -+ selected_ctx->data_offset = data_offset; -+ selected_ctx_u->data_offset = true; -+ } -+ return 0; -+} -+ -+/** -+ * isp_csi2_ctx_config_ping_addr - Sets Ping address for CSI2 Rx. buffer saving -+ * @ctxnum: Context number, valid between 0 and 7 values. -+ * @ping_addr: 32 bit ISP MMU mapped address. -+ * -+ * Always returns 0. -+ **/ -+int isp_csi2_ctx_config_ping_addr(u8 ctxnum, u32 ping_addr) -+{ -+ struct isp_csi2_ctx_cfg *selected_ctx; -+ struct isp_csi2_ctx_cfg_update *selected_ctx_u; -+ -+ isp_csi2_ctx_validate(&ctxnum); -+ -+ ping_addr &= ~(0x1F); -+ -+ selected_ctx = ¤t_csi2_cfg.contexts[ctxnum]; -+ selected_ctx_u = ¤t_csi2_cfg_update.contexts[ctxnum]; -+ -+ if (selected_ctx->ping_addr != ping_addr) { -+ selected_ctx->ping_addr = ping_addr; -+ selected_ctx_u->ping_addr = true; -+ } -+ return 0; -+} -+ -+/** -+ * isp_csi2_ctx_config_pong_addr - Sets Pong address for CSI2 Rx. buffer saving -+ * @ctxnum: Context number, valid between 0 and 7 values. -+ * @pong_addr: 32 bit ISP MMU mapped address. -+ * -+ * Always returns 0. -+ **/ -+int isp_csi2_ctx_config_pong_addr(u8 ctxnum, u32 pong_addr) -+{ -+ struct isp_csi2_ctx_cfg *selected_ctx; -+ struct isp_csi2_ctx_cfg_update *selected_ctx_u; -+ -+ isp_csi2_ctx_validate(&ctxnum); -+ -+ pong_addr &= ~(0x1F); -+ -+ selected_ctx = ¤t_csi2_cfg.contexts[ctxnum]; -+ selected_ctx_u = ¤t_csi2_cfg_update.contexts[ctxnum]; -+ -+ if (selected_ctx->pong_addr != pong_addr) { -+ selected_ctx->pong_addr = pong_addr; -+ selected_ctx_u->pong_addr = true; -+ } -+ return 0; -+} -+ -+/** -+ * isp_csi2_ctx_config_eof_enabled - Enables EOF signal assertion -+ * @ctxnum: Context number, valid between 0 and 7 values. -+ * @eof_enabled: Boolean to enable/disable EOF signal assertion on received -+ * packets. -+ * -+ * Always returns 0. -+ **/ -+int isp_csi2_ctx_config_eof_enabled(u8 ctxnum, bool eof_enabled) -+{ -+ struct isp_csi2_ctx_cfg *selected_ctx; -+ struct isp_csi2_ctx_cfg_update *selected_ctx_u; -+ -+ isp_csi2_ctx_validate(&ctxnum); -+ -+ selected_ctx = ¤t_csi2_cfg.contexts[ctxnum]; -+ selected_ctx_u = ¤t_csi2_cfg_update.contexts[ctxnum]; -+ -+ if (selected_ctx->eof_enabled != eof_enabled) { -+ selected_ctx->eof_enabled = eof_enabled; -+ selected_ctx_u->eof_enabled = true; -+ update_ctx_ctrl1[ctxnum] = true; -+ } -+ return 0; -+} -+ -+/** -+ * isp_csi2_ctx_config_eol_enabled - Enables EOL signal assertion -+ * @ctxnum: Context number, valid between 0 and 7 values. -+ * @eol_enabled: Boolean to enable/disable EOL signal assertion on received -+ * packets. -+ * -+ * Always returns 0. -+ **/ -+int isp_csi2_ctx_config_eol_enabled(u8 ctxnum, bool eol_enabled) -+{ -+ struct isp_csi2_ctx_cfg *selected_ctx; -+ struct isp_csi2_ctx_cfg_update *selected_ctx_u; -+ -+ isp_csi2_ctx_validate(&ctxnum); -+ -+ selected_ctx = ¤t_csi2_cfg.contexts[ctxnum]; -+ selected_ctx_u = ¤t_csi2_cfg_update.contexts[ctxnum]; -+ -+ if (selected_ctx->eol_enabled != eol_enabled) { -+ selected_ctx->eol_enabled = eol_enabled; -+ selected_ctx_u->eol_enabled = true; -+ update_ctx_ctrl1[ctxnum] = true; -+ } -+ return 0; -+} -+ -+/** -+ * isp_csi2_ctx_config_checksum_enabled - Enables Checksum check in rcvd packets -+ * @ctxnum: Context number, valid between 0 and 7 values. -+ * @checksum_enabled: Boolean to enable/disable Checksum check on received -+ * packets -+ * -+ * Always returns 0. -+ **/ -+int isp_csi2_ctx_config_checksum_enabled(u8 ctxnum, bool checksum_enabled) -+{ -+ struct isp_csi2_ctx_cfg *selected_ctx; -+ struct isp_csi2_ctx_cfg_update *selected_ctx_u; -+ -+ isp_csi2_ctx_validate(&ctxnum); -+ -+ selected_ctx = ¤t_csi2_cfg.contexts[ctxnum]; -+ selected_ctx_u = ¤t_csi2_cfg_update.contexts[ctxnum]; -+ -+ if (selected_ctx->checksum_enabled != checksum_enabled) { -+ selected_ctx->checksum_enabled = checksum_enabled; -+ selected_ctx_u->checksum_enabled = true; -+ update_ctx_ctrl1[ctxnum] = true; -+ } -+ return 0; -+} -+ -+/** -+ * isp_csi2_ctx_config_enabled - Enables specified CSI2 context -+ * @ctxnum: Context number, valid between 0 and 7 values. -+ * @enabled: Boolean to enable/disable specified context. -+ * -+ * Always returns 0. -+ **/ -+int isp_csi2_ctx_config_enabled(u8 ctxnum, bool enabled) -+{ -+ struct isp_csi2_ctx_cfg *selected_ctx; -+ struct isp_csi2_ctx_cfg_update *selected_ctx_u; -+ -+ isp_csi2_ctx_validate(&ctxnum); -+ -+ selected_ctx = ¤t_csi2_cfg.contexts[ctxnum]; -+ selected_ctx_u = ¤t_csi2_cfg_update.contexts[ctxnum]; -+ -+ if (selected_ctx->enabled != enabled) { -+ selected_ctx->enabled = enabled; -+ selected_ctx_u->enabled = true; -+ update_ctx_ctrl1[ctxnum] = true; -+ } -+ return 0; -+} -+ -+/** -+ * isp_csi2_ctx_update - Applies CSI2 context configuration. -+ * @ctxnum: Context number, valid between 0 and 7 values. -+ * @force_update: Flag to force rewrite of registers, even if they haven't been -+ * updated with the isp_csi2_ctx_config_*() functions. -+ * -+ * It only saves settings when they were previously updated using the -+ * isp_csi2_ctx_config_*() functions, unless the force_update flag is -+ * set to true. -+ * Always returns 0. -+ **/ -+int isp_csi2_ctx_update(u8 ctxnum, bool force_update) -+{ -+ struct isp_csi2_ctx_cfg *selected_ctx; -+ struct isp_csi2_ctx_cfg_update *selected_ctx_u; -+ u32 reg; -+ -+ isp_csi2_ctx_validate(&ctxnum); -+ -+ selected_ctx = ¤t_csi2_cfg.contexts[ctxnum]; -+ selected_ctx_u = ¤t_csi2_cfg_update.contexts[ctxnum]; -+ -+ if (update_ctx_ctrl1[ctxnum] || force_update) { -+ reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_CTX_CTRL1(ctxnum)); -+ if (selected_ctx_u->frame_count || force_update) { -+ reg &= ~(ISPCSI2_CTX_CTRL1_COUNT_MASK); -+ reg |= selected_ctx->frame_count << -+ ISPCSI2_CTX_CTRL1_COUNT_SHIFT; -+ selected_ctx_u->frame_count = false; -+ } -+ if (selected_ctx_u->eof_enabled || force_update) { -+ reg &= ~(ISPCSI2_CTX_CTRL1_EOF_EN_MASK); -+ if (selected_ctx->eof_enabled) -+ reg |= ISPCSI2_CTX_CTRL1_EOF_EN_ENABLE; -+ else -+ reg |= ISPCSI2_CTX_CTRL1_EOF_EN_DISABLE; -+ selected_ctx_u->eof_enabled = false; -+ } -+ if (selected_ctx_u->eol_enabled || force_update) { -+ reg &= ~(ISPCSI2_CTX_CTRL1_EOL_EN_MASK); -+ if (selected_ctx->eol_enabled) -+ reg |= ISPCSI2_CTX_CTRL1_EOL_EN_ENABLE; -+ else -+ reg |= ISPCSI2_CTX_CTRL1_EOL_EN_DISABLE; -+ selected_ctx_u->eol_enabled = false; -+ } -+ if (selected_ctx_u->checksum_enabled || force_update) { -+ reg &= ~(ISPCSI2_CTX_CTRL1_CS_EN_MASK); -+ if (selected_ctx->checksum_enabled) -+ reg |= ISPCSI2_CTX_CTRL1_CS_EN_ENABLE; -+ else -+ reg |= ISPCSI2_CTX_CTRL1_CS_EN_DISABLE; -+ selected_ctx_u->checksum_enabled = false; -+ } -+ if (selected_ctx_u->enabled || force_update) { -+ reg &= ~(ISPCSI2_CTX_CTRL1_CTX_EN_MASK); -+ if (selected_ctx->enabled) -+ reg |= ISPCSI2_CTX_CTRL1_CTX_EN_ENABLE; -+ else -+ reg |= ISPCSI2_CTX_CTRL1_CTX_EN_DISABLE; -+ selected_ctx_u->enabled = false; -+ } -+ isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_CTX_CTRL1(ctxnum)); -+ update_ctx_ctrl1[ctxnum] = false; -+ } -+ -+ if (update_ctx_ctrl2[ctxnum] || force_update) { -+ reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_CTX_CTRL2(ctxnum)); -+ if (selected_ctx_u->virtual_id || force_update) { -+ reg &= ~(ISPCSI2_CTX_CTRL2_VIRTUAL_ID_MASK); -+ reg |= selected_ctx->virtual_id << -+ ISPCSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT; -+ selected_ctx_u->virtual_id = false; -+ } -+ -+ if (selected_ctx_u->format || force_update) { -+ struct v4l2_pix_format *pix; -+ u16 new_format = 0; -+ -+ reg &= ~(ISPCSI2_CTX_CTRL2_FORMAT_MASK); -+ pix = &selected_ctx->format; -+ switch (pix->pixelformat) { -+ case V4L2_PIX_FMT_RGB565: -+ case V4L2_PIX_FMT_RGB565X: -+ new_format = 0x22; -+ break; -+ case V4L2_PIX_FMT_YUYV: -+ case V4L2_PIX_FMT_UYVY: -+ if (uses_videoport) -+ new_format = 0x9E; -+ else -+ new_format = 0x1E; -+ break; -+ case V4L2_PIX_FMT_RGB555: -+ case V4L2_PIX_FMT_RGB555X: -+ new_format = 0xA1; -+ break; -+ case V4L2_PIX_FMT_SGRBG10: -+ if (uses_videoport) -+ new_format = 0x12F; -+ else -+ new_format = 0xAB; -+ break; -+ } -+ reg |= (new_format << ISPCSI2_CTX_CTRL2_FORMAT_SHIFT); -+ selected_ctx_u->format = false; -+ } -+ isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_CTX_CTRL2(ctxnum)); -+ update_ctx_ctrl2[ctxnum] = false; -+ } -+ -+ if (update_ctx_ctrl3[ctxnum] || force_update) { -+ reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_CTX_CTRL3(ctxnum)); -+ if (selected_ctx_u->alpha || force_update) { -+ reg &= ~(ISPCSI2_CTX_CTRL3_ALPHA_MASK); -+ reg |= (selected_ctx->alpha << -+ ISPCSI2_CTX_CTRL3_ALPHA_SHIFT); -+ selected_ctx_u->alpha = false; -+ } -+ isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_CTX_CTRL3(ctxnum)); -+ update_ctx_ctrl3[ctxnum] = false; -+ } -+ -+ if (selected_ctx_u->data_offset) { -+ reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_CTX_DAT_OFST(ctxnum)); -+ reg &= ~ISPCSI2_CTX_DAT_OFST_OFST_MASK; -+ reg |= selected_ctx->data_offset << -+ ISPCSI2_CTX_DAT_OFST_OFST_SHIFT; -+ isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_CTX_DAT_OFST(ctxnum)); -+ selected_ctx_u->data_offset = false; -+ } -+ -+ if (selected_ctx_u->ping_addr) { -+ reg = selected_ctx->ping_addr; -+ isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_CTX_DAT_PING_ADDR(ctxnum)); -+ selected_ctx_u->ping_addr = false; -+ } -+ -+ if (selected_ctx_u->pong_addr) { -+ reg = selected_ctx->pong_addr; -+ isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_CTX_DAT_PONG_ADDR(ctxnum)); -+ selected_ctx_u->pong_addr = false; -+ } -+ return 0; -+} -+ -+/** -+ * isp_csi2_ctx_get - Gets specific CSI2 Context configuration -+ * @ctxnum: Context number, valid between 0 and 7 values. -+ * -+ * Always returns 0. -+ **/ -+int isp_csi2_ctx_get(u8 ctxnum) -+{ -+ struct isp_csi2_ctx_cfg *selected_ctx; -+ struct isp_csi2_ctx_cfg_update *selected_ctx_u; -+ u32 reg; -+ -+ isp_csi2_ctx_validate(&ctxnum); -+ -+ selected_ctx = ¤t_csi2_cfg.contexts[ctxnum]; -+ selected_ctx_u = ¤t_csi2_cfg_update.contexts[ctxnum]; -+ -+ reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_CTX_CTRL1(ctxnum)); -+ selected_ctx->frame_count = (reg & ISPCSI2_CTX_CTRL1_COUNT_MASK) >> -+ ISPCSI2_CTX_CTRL1_COUNT_SHIFT; -+ selected_ctx_u->frame_count = false; -+ -+ if ((reg & ISPCSI2_CTX_CTRL1_EOF_EN_MASK) == -+ ISPCSI2_CTX_CTRL1_EOF_EN_ENABLE) -+ selected_ctx->eof_enabled = true; -+ else -+ selected_ctx->eof_enabled = false; -+ selected_ctx_u->eof_enabled = false; -+ -+ if ((reg & ISPCSI2_CTX_CTRL1_EOL_EN_MASK) == -+ ISPCSI2_CTX_CTRL1_EOL_EN_ENABLE) -+ selected_ctx->eol_enabled = true; -+ else -+ selected_ctx->eol_enabled = false; -+ selected_ctx_u->eol_enabled = false; -+ -+ if ((reg & ISPCSI2_CTX_CTRL1_CS_EN_MASK) == -+ ISPCSI2_CTX_CTRL1_CS_EN_ENABLE) -+ selected_ctx->checksum_enabled = true; -+ else -+ selected_ctx->checksum_enabled = false; -+ selected_ctx_u->checksum_enabled = false; -+ -+ if ((reg & ISPCSI2_CTX_CTRL1_CTX_EN_MASK) == -+ ISPCSI2_CTX_CTRL1_CTX_EN_ENABLE) -+ selected_ctx->enabled = true; -+ else -+ selected_ctx->enabled = false; -+ selected_ctx_u->enabled = false; -+ update_ctx_ctrl1[ctxnum] = false; -+ -+ reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_CTX_CTRL2(ctxnum)); -+ -+ selected_ctx->virtual_id = (reg & ISPCSI2_CTX_CTRL2_VIRTUAL_ID_MASK) >> -+ ISPCSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT; -+ selected_ctx_u->virtual_id = false; -+ -+ switch ((reg & ISPCSI2_CTX_CTRL2_FORMAT_MASK) >> -+ ISPCSI2_CTX_CTRL2_FORMAT_SHIFT) { -+ case 0x22: -+ selected_ctx->format.pixelformat = V4L2_PIX_FMT_RGB565; -+ break; -+ case 0x9E: -+ case 0x1E: -+ selected_ctx->format.pixelformat = V4L2_PIX_FMT_YUYV; -+ break; -+ case 0xA1: -+ selected_ctx->format.pixelformat = V4L2_PIX_FMT_RGB555; -+ break; -+ case 0xAB: -+ case 0x12F: -+ selected_ctx->format.pixelformat = V4L2_PIX_FMT_SGRBG10; -+ break; -+ } -+ selected_ctx_u->format = false; -+ update_ctx_ctrl2[ctxnum] = false; -+ -+ selected_ctx->alpha = (isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_CTX_CTRL3(ctxnum)) & -+ ISPCSI2_CTX_CTRL3_ALPHA_MASK) >> -+ ISPCSI2_CTX_CTRL3_ALPHA_SHIFT; -+ selected_ctx_u->alpha = false; -+ update_ctx_ctrl3[ctxnum] = false; -+ -+ selected_ctx->data_offset = (isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_CTX_DAT_OFST(ctxnum)) & -+ ISPCSI2_CTX_DAT_OFST_OFST_MASK) >> -+ ISPCSI2_CTX_DAT_OFST_OFST_SHIFT; -+ selected_ctx_u->data_offset = false; -+ -+ selected_ctx->ping_addr = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_CTX_DAT_PING_ADDR(ctxnum)); -+ selected_ctx_u->ping_addr = false; -+ -+ selected_ctx->pong_addr = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_CTX_DAT_PONG_ADDR(ctxnum)); -+ selected_ctx_u->pong_addr = false; -+ return 0; -+} -+ -+/** -+ * isp_csi2_ctx_update_all - Applies all CSI2 context configuration. -+ * @force_update: Flag to force rewrite of registers, even if they haven't been -+ * updated with the isp_csi2_ctx_config_*() functions. -+ * -+ * It only saves settings when they were previously updated using the -+ * isp_csi2_ctx_config_*() functions, unless the force_update flag is -+ * set to true. -+ * Always returns 0. -+ **/ -+int isp_csi2_ctx_update_all(bool force_update) -+{ -+ u8 ctxnum; -+ -+ for (ctxnum = 0; ctxnum < 8; ctxnum++) -+ isp_csi2_ctx_update(ctxnum, force_update); -+ -+ return 0; -+} -+ -+/** -+ * isp_csi2_ctx_get_all - Gets all CSI2 Context configurations -+ * -+ * Always returns 0. -+ **/ -+int isp_csi2_ctx_get_all(void) -+{ -+ u8 ctxnum; -+ -+ for (ctxnum = 0; ctxnum < 8; ctxnum++) -+ isp_csi2_ctx_get(ctxnum); -+ -+ return 0; -+} -+ -+int isp_csi2_phy_config(struct isp_csi2_phy_cfg *desiredphyconfig) -+{ -+ struct isp_csi2_phy_cfg *currphy = ¤t_csi2_cfg.phy; -+ struct isp_csi2_phy_cfg_update *currphy_u = -+ ¤t_csi2_cfg_update.phy; -+ -+ if ((desiredphyconfig->tclk_term > 0x7f) || -+ (desiredphyconfig->tclk_miss > 0x3)) { -+ printk(KERN_ERR "Invalid PHY configuration sent by the" -+ " driver\n"); -+ return -EINVAL; -+ } -+ -+ if (currphy->ths_term != desiredphyconfig->ths_term) { -+ currphy->ths_term = desiredphyconfig->ths_term; -+ currphy_u->ths_term = true; -+ update_phy_cfg0 = true; -+ } -+ if (currphy->ths_settle != desiredphyconfig->ths_settle) { -+ currphy->ths_settle = desiredphyconfig->ths_settle; -+ currphy_u->ths_settle = true; -+ update_phy_cfg0 = true; -+ } -+ if (currphy->tclk_term != desiredphyconfig->tclk_term) { -+ currphy->tclk_term = desiredphyconfig->tclk_term; -+ currphy_u->tclk_term = true; -+ update_phy_cfg1 = true; -+ } -+ if (currphy->tclk_miss != desiredphyconfig->tclk_miss) { -+ currphy->tclk_miss = desiredphyconfig->tclk_miss; -+ currphy_u->tclk_miss = true; -+ update_phy_cfg1 = true; -+ } -+ if (currphy->tclk_settle != desiredphyconfig->tclk_settle) { -+ currphy->tclk_settle = desiredphyconfig->tclk_settle; -+ currphy_u->tclk_settle = true; -+ update_phy_cfg1 = true; -+ } -+ return 0; -+} -+ -+/** -+ * isp_csi2_calc_phy_cfg0 - Calculates D-PHY config based on the MIPIClk speed. -+ * @mipiclk: MIPI clock frequency being used with CSI2 sensor. -+ * @lbound_hs_settle: Lower bound for CSI2 High Speed Settle transition. -+ * @ubound_hs_settle: Upper bound for CSI2 High Speed Settle transition. -+ * -+ * From TRM, we have the same calculation for HS Termination signal. -+ * THS_TERM = ceil( 12.5ns / DDRCLK period ) - 1 -+ * But for Settle, we use the mid value between the two passed boundaries from -+ * sensor: -+ * THS_SETTLE = (Upper bound + Lower bound) / 2 -+ * -+ * Always returns 0. -+ */ -+int isp_csi2_calc_phy_cfg0(u32 mipiclk, u32 lbound_hs_settle, -+ u32 ubound_hs_settle) -+{ -+ struct isp_csi2_phy_cfg *currphy = ¤t_csi2_cfg.phy; -+ struct isp_csi2_phy_cfg_update *currphy_u = -+ ¤t_csi2_cfg_update.phy; -+ u32 tmp, ddrclk = mipiclk >> 1; -+ -+ /* Calculate THS_TERM */ -+ tmp = ddrclk / 80000000; -+ if ((ddrclk % 80000000) > 0) -+ tmp++; -+ currphy->ths_term = tmp - 1; -+ currphy_u->ths_term = true; -+ -+ /* Calculate THS_SETTLE */ -+ currphy->ths_settle = (ubound_hs_settle + lbound_hs_settle) / 2; -+ -+ currphy_u->ths_settle = true; -+ isp_csi2_phy_update(true); -+ return 0; -+} -+EXPORT_SYMBOL(isp_csi2_calc_phy_cfg0); -+ -+/** -+ * isp_csi2_phy_update - Applies CSI2 D-PHY configuration. -+ * @force_update: Flag to force rewrite of registers, even if they haven't been -+ * updated with the isp_csi2_phy_config_*() functions. -+ * -+ * It only saves settings when they were previously updated using the -+ * isp_csi2_phy_config_*() functions, unless the force_update flag is -+ * set to true. -+ * Always returns 0. -+ **/ -+int isp_csi2_phy_update(bool force_update) -+{ -+ struct isp_csi2_phy_cfg *currphy = ¤t_csi2_cfg.phy; -+ struct isp_csi2_phy_cfg_update *currphy_u = -+ ¤t_csi2_cfg_update.phy; -+ u32 reg; -+ -+ if (update_phy_cfg0 || force_update) { -+ reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2PHY, ISPCSI2PHY_CFG0); -+ if (currphy_u->ths_term || force_update) { -+ reg &= ~ISPCSI2PHY_CFG0_THS_TERM_MASK; -+ reg |= (currphy->ths_term << -+ ISPCSI2PHY_CFG0_THS_TERM_SHIFT); -+ currphy_u->ths_term = false; -+ } -+ if (currphy_u->ths_settle || force_update) { -+ reg &= ~ISPCSI2PHY_CFG0_THS_SETTLE_MASK; -+ reg |= (currphy->ths_settle << -+ ISPCSI2PHY_CFG0_THS_SETTLE_SHIFT); -+ currphy_u->ths_settle = false; -+ } -+ isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2PHY, ISPCSI2PHY_CFG0); -+ update_phy_cfg0 = false; -+ } -+ -+ if (update_phy_cfg1 || force_update) { -+ reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2PHY, ISPCSI2PHY_CFG1); -+ if (currphy_u->tclk_term || force_update) { -+ reg &= ~ISPCSI2PHY_CFG1_TCLK_TERM_MASK; -+ reg |= (currphy->tclk_term << -+ ISPCSI2PHY_CFG1_TCLK_TERM_SHIFT); -+ currphy_u->tclk_term = false; -+ } -+ if (currphy_u->tclk_miss || force_update) { -+ reg &= ~ISPCSI2PHY_CFG1_TCLK_MISS_MASK; -+ reg |= (currphy->tclk_miss << -+ ISPCSI2PHY_CFG1_TCLK_MISS_SHIFT); -+ currphy_u->tclk_miss = false; -+ } -+ if (currphy_u->tclk_settle || force_update) { -+ reg &= ~ISPCSI2PHY_CFG1_TCLK_SETTLE_MASK; -+ reg |= (currphy->tclk_settle << -+ ISPCSI2PHY_CFG1_TCLK_SETTLE_SHIFT); -+ currphy_u->tclk_settle = false; -+ } -+ isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2PHY, ISPCSI2PHY_CFG1); -+ update_phy_cfg1 = false; -+ } -+ return 0; -+} -+ -+/** -+ * isp_csi2_phy_get - Gets CSI2 D-PHY configuration -+ * -+ * Gets settings from HW registers and fills in the internal driver memory -+ * Always returns 0. -+ **/ -+int isp_csi2_phy_get(void) -+{ -+ struct isp_csi2_phy_cfg *currphy = ¤t_csi2_cfg.phy; -+ struct isp_csi2_phy_cfg_update *currphy_u = -+ ¤t_csi2_cfg_update.phy; -+ u32 reg; -+ -+ reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2PHY, ISPCSI2PHY_CFG0); -+ currphy->ths_term = (reg & ISPCSI2PHY_CFG0_THS_TERM_MASK) >> -+ ISPCSI2PHY_CFG0_THS_TERM_SHIFT; -+ currphy_u->ths_term = false; -+ -+ currphy->ths_settle = (reg & ISPCSI2PHY_CFG0_THS_SETTLE_MASK) >> -+ ISPCSI2PHY_CFG0_THS_SETTLE_SHIFT; -+ currphy_u->ths_settle = false; -+ update_phy_cfg0 = false; -+ -+ reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2PHY, ISPCSI2PHY_CFG1); -+ -+ currphy->tclk_term = (reg & ISPCSI2PHY_CFG1_TCLK_TERM_MASK) >> -+ ISPCSI2PHY_CFG1_TCLK_TERM_SHIFT; -+ currphy_u->tclk_term = false; -+ -+ currphy->tclk_miss = (reg & ISPCSI2PHY_CFG1_TCLK_MISS_MASK) >> -+ ISPCSI2PHY_CFG1_TCLK_MISS_SHIFT; -+ currphy_u->tclk_miss = false; -+ -+ currphy->tclk_settle = (reg & ISPCSI2PHY_CFG1_TCLK_SETTLE_MASK) >> -+ ISPCSI2PHY_CFG1_TCLK_SETTLE_SHIFT; -+ currphy_u->tclk_settle = false; -+ -+ update_phy_cfg1 = false; -+ return 0; -+} -+ -+/** -+ * isp_csi2_timings_config_forcerxmode - Sets Force Rx mode on stop state count -+ * @force_rx_mode: Boolean to enable/disable forcing Rx mode in CSI2 receiver -+ * -+ * Returns 0 if successful, or -EINVAL if wrong ComplexIO number is selected. -+ **/ -+int isp_csi2_timings_config_forcerxmode(u8 io, bool force_rx_mode) -+{ -+ struct isp_csi2_timings_cfg *currtimings; -+ struct isp_csi2_timings_cfg_update *currtimings_u; -+ -+ if (io < 1 || io > 2) { -+ printk(KERN_ERR "CSI2 - Timings config: Invalid IO number\n"); -+ return -EINVAL; -+ } -+ -+ currtimings = ¤t_csi2_cfg.timings[io - 1]; -+ currtimings_u = ¤t_csi2_cfg_update.timings[io - 1]; -+ if (currtimings->force_rx_mode != force_rx_mode) { -+ currtimings->force_rx_mode = force_rx_mode; -+ currtimings_u->force_rx_mode = true; -+ update_timing = true; -+ } -+ return 0; -+} -+ -+/** -+ * isp_csi2_timings_config_stopstate_16x - Sets 16x factor for L3 cycles -+ * @stop_state_16x: Boolean to use or not use the 16x multiplier for stop count -+ * -+ * Returns 0 if successful, or -EINVAL if wrong ComplexIO number is selected. -+ **/ -+int isp_csi2_timings_config_stopstate_16x(u8 io, bool stop_state_16x) -+{ -+ struct isp_csi2_timings_cfg *currtimings; -+ struct isp_csi2_timings_cfg_update *currtimings_u; -+ -+ if (io < 1 || io > 2) { -+ printk(KERN_ERR "CSI2 - Timings config: Invalid IO number\n"); -+ return -EINVAL; -+ } -+ -+ currtimings = ¤t_csi2_cfg.timings[io - 1]; -+ currtimings_u = ¤t_csi2_cfg_update.timings[io - 1]; -+ if (currtimings->stop_state_16x != stop_state_16x) { -+ currtimings->stop_state_16x = stop_state_16x; -+ currtimings_u->stop_state_16x = true; -+ update_timing = true; -+ } -+ return 0; -+} -+ -+/** -+ * isp_csi2_timings_config_stopstate_4x - Sets 4x factor for L3 cycles -+ * @stop_state_4x: Boolean to use or not use the 4x multiplier for stop count -+ * -+ * Returns 0 if successful, or -EINVAL if wrong ComplexIO number is selected. -+ **/ -+int isp_csi2_timings_config_stopstate_4x(u8 io, bool stop_state_4x) -+{ -+ struct isp_csi2_timings_cfg *currtimings; -+ struct isp_csi2_timings_cfg_update *currtimings_u; -+ -+ if (io < 1 || io > 2) { -+ printk(KERN_ERR "CSI2 - Timings config: Invalid IO number\n"); -+ return -EINVAL; -+ } -+ -+ currtimings = ¤t_csi2_cfg.timings[io - 1]; -+ currtimings_u = ¤t_csi2_cfg_update.timings[io - 1]; -+ if (currtimings->stop_state_4x != stop_state_4x) { -+ currtimings->stop_state_4x = stop_state_4x; -+ currtimings_u->stop_state_4x = true; -+ update_timing = true; -+ } -+ return 0; -+} -+ -+/** -+ * isp_csi2_timings_config_stopstate_cnt - Sets L3 cycles -+ * @stop_state_counter: Stop state counter value for L3 cycles -+ * -+ * Returns 0 if successful, or -EINVAL if wrong ComplexIO number is selected. -+ **/ -+int isp_csi2_timings_config_stopstate_cnt(u8 io, u16 stop_state_counter) -+{ -+ struct isp_csi2_timings_cfg *currtimings; -+ struct isp_csi2_timings_cfg_update *currtimings_u; -+ -+ if (io < 1 || io > 2) { -+ printk(KERN_ERR "CSI2 - Timings config: Invalid IO number\n"); -+ return -EINVAL; -+ } -+ -+ currtimings = ¤t_csi2_cfg.timings[io - 1]; -+ currtimings_u = ¤t_csi2_cfg_update.timings[io - 1]; -+ if (currtimings->stop_state_counter != stop_state_counter) { -+ currtimings->stop_state_counter = (stop_state_counter & 0x1FFF); -+ currtimings_u->stop_state_counter = true; -+ update_timing = true; -+ } -+ return 0; -+} -+ -+/** -+ * isp_csi2_timings_update - Applies specified CSI2 timing configuration. -+ * @io: IO number (1 or 2) which specifies which ComplexIO are we updating -+ * @force_update: Flag to force rewrite of registers, even if they haven't been -+ * updated with the isp_csi2_timings_config_*() functions. -+ * -+ * It only saves settings when they were previously updated using the -+ * isp_csi2_timings_config_*() functions, unless the force_update flag is -+ * set to true. -+ * Returns 0 if successful, or -EINVAL if invalid IO number is passed. -+ **/ -+int isp_csi2_timings_update(u8 io, bool force_update) -+{ -+ struct isp_csi2_timings_cfg *currtimings; -+ struct isp_csi2_timings_cfg_update *currtimings_u; -+ u32 reg; -+ -+ if (io < 1 || io > 2) { -+ printk(KERN_ERR "CSI2 - Timings config: Invalid IO number\n"); -+ return -EINVAL; -+ } -+ -+ currtimings = ¤t_csi2_cfg.timings[io - 1]; -+ currtimings_u = ¤t_csi2_cfg_update.timings[io - 1]; -+ -+ if (update_timing || force_update) { -+ reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_TIMING); -+ if (currtimings_u->force_rx_mode || force_update) { -+ reg &= ~ISPCSI2_TIMING_FORCE_RX_MODE_IO_MASK(io); -+ if (currtimings->force_rx_mode) -+ reg |= ISPCSI2_TIMING_FORCE_RX_MODE_IO_ENABLE -+ (io); -+ else -+ reg |= ISPCSI2_TIMING_FORCE_RX_MODE_IO_DISABLE -+ (io); -+ currtimings_u->force_rx_mode = false; -+ } -+ if (currtimings_u->stop_state_16x || force_update) { -+ reg &= ~ISPCSI2_TIMING_STOP_STATE_X16_IO_MASK(io); -+ if (currtimings->stop_state_16x) -+ reg |= ISPCSI2_TIMING_STOP_STATE_X16_IO_ENABLE -+ (io); -+ else -+ reg |= ISPCSI2_TIMING_STOP_STATE_X16_IO_DISABLE -+ (io); -+ currtimings_u->stop_state_16x = false; -+ } -+ if (currtimings_u->stop_state_4x || force_update) { -+ reg &= ~ISPCSI2_TIMING_STOP_STATE_X4_IO_MASK(io); -+ if (currtimings->stop_state_4x) { -+ reg |= ISPCSI2_TIMING_STOP_STATE_X4_IO_ENABLE -+ (io); -+ } else { -+ reg |= ISPCSI2_TIMING_STOP_STATE_X4_IO_DISABLE -+ (io); -+ } -+ currtimings_u->stop_state_4x = false; -+ } -+ if (currtimings_u->stop_state_counter || force_update) { -+ reg &= ~ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_MASK(io); -+ reg |= currtimings->stop_state_counter << -+ ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_SHIFT(io); -+ currtimings_u->stop_state_counter = false; -+ } -+ isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_TIMING); -+ update_timing = false; -+ } -+ return 0; -+} -+ -+/** -+ * isp_csi2_timings_get - Gets specific CSI2 ComplexIO timing configuration -+ * @io: IO number (1 or 2) which specifies which ComplexIO are we getting -+ * -+ * Gets settings from HW registers and fills in the internal driver memory -+ * Returns 0 if successful, or -EINVAL if invalid IO number is passed. -+ **/ -+int isp_csi2_timings_get(u8 io) -+{ -+ struct isp_csi2_timings_cfg *currtimings; -+ struct isp_csi2_timings_cfg_update *currtimings_u; -+ u32 reg; -+ -+ if (io < 1 || io > 2) { -+ printk(KERN_ERR "CSI2 - Timings config: Invalid IO number\n"); -+ return -EINVAL; -+ } -+ -+ currtimings = ¤t_csi2_cfg.timings[io - 1]; -+ currtimings_u = ¤t_csi2_cfg_update.timings[io - 1]; -+ -+ reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_TIMING); -+ if ((reg & ISPCSI2_TIMING_FORCE_RX_MODE_IO_MASK(io)) == -+ ISPCSI2_TIMING_FORCE_RX_MODE_IO_ENABLE(io)) -+ currtimings->force_rx_mode = true; -+ else -+ currtimings->force_rx_mode = false; -+ currtimings_u->force_rx_mode = false; -+ -+ if ((reg & ISPCSI2_TIMING_STOP_STATE_X16_IO_MASK(io)) == -+ ISPCSI2_TIMING_STOP_STATE_X16_IO_ENABLE(io)) -+ currtimings->stop_state_16x = true; -+ else -+ currtimings->stop_state_16x = false; -+ currtimings_u->stop_state_16x = false; -+ -+ if ((reg & ISPCSI2_TIMING_STOP_STATE_X4_IO_MASK(io)) == -+ ISPCSI2_TIMING_STOP_STATE_X4_IO_ENABLE(io)) -+ currtimings->stop_state_4x = true; -+ else -+ currtimings->stop_state_4x = false; -+ currtimings_u->stop_state_4x = false; -+ -+ currtimings->stop_state_counter = (reg & -+ ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_MASK(io)) >> -+ ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_SHIFT(io); -+ currtimings_u->stop_state_counter = false; -+ update_timing = false; -+ return 0; -+} -+ -+/** -+ * isp_csi2_timings_update_all - Applies specified CSI2 timing configuration. -+ * @force_update: Flag to force rewrite of registers, even if they haven't been -+ * updated with the isp_csi2_timings_config_*() functions. -+ * -+ * It only saves settings when they were previously updated using the -+ * isp_csi2_timings_config_*() functions, unless the force_update flag is -+ * set to true. -+ * Always returns 0. -+ **/ -+int isp_csi2_timings_update_all(bool force_update) -+{ -+ int i; -+ -+ for (i = 1; i < 3; i++) -+ isp_csi2_timings_update(i, force_update); -+ return 0; -+} -+ -+/** -+ * isp_csi2_timings_get_all - Gets all CSI2 ComplexIO timing configurations -+ * -+ * Always returns 0. -+ **/ -+int isp_csi2_timings_get_all(void) -+{ -+ int i; -+ -+ for (i = 1; i < 3; i++) -+ isp_csi2_timings_get(i); -+ return 0; -+} -+ -+/** -+ * isp_csi2_isr - CSI2 interrupt handling. -+ **/ -+void isp_csi2_isr(void) -+{ -+ u32 csi2_irqstatus, cpxio1_irqstatus, ctxirqstatus; -+ -+ csi2_irqstatus = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_IRQSTATUS); -+ isp_reg_writel(csi2_irqstatus, OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_IRQSTATUS); -+ -+ if (csi2_irqstatus & ISPCSI2_IRQSTATUS_COMPLEXIO1_ERR_IRQ) { -+ cpxio1_irqstatus = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_COMPLEXIO1_IRQSTATUS); -+ isp_reg_writel(cpxio1_irqstatus, OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_COMPLEXIO1_IRQSTATUS); -+ printk(KERN_ERR "CSI2: ComplexIO Error IRQ %x\n", -+ cpxio1_irqstatus); -+ } -+ -+ if (csi2_irqstatus & ISPCSI2_IRQSTATUS_CONTEXT(0)) { -+ ctxirqstatus = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_CTX_IRQSTATUS(0)); -+ isp_reg_writel(ctxirqstatus, OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_CTX_IRQSTATUS(0)); -+ } -+ -+ if (csi2_irqstatus & ISPCSI2_IRQSTATUS_OCP_ERR_IRQ) -+ printk(KERN_ERR "CSI2: OCP Transmission Error\n"); -+ -+ if (csi2_irqstatus & ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ) -+ printk(KERN_ERR "CSI2: Short packet receive error\n"); -+ -+ if (csi2_irqstatus & ISPCSI2_IRQSTATUS_ECC_CORRECTION_IRQ) -+ printk(KERN_DEBUG "CSI2: ECC correction done\n"); -+ -+ if (csi2_irqstatus & ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ) -+ printk(KERN_ERR "CSI2: ECC correction failed\n"); -+ -+ if (csi2_irqstatus & ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ) -+ printk(KERN_ERR "CSI2: ComplexIO #2 failed\n"); -+ -+ if (csi2_irqstatus & ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ) -+ printk(KERN_ERR "CSI2: FIFO overflow error\n"); -+ -+ return; -+} -+EXPORT_SYMBOL(isp_csi2_isr); -+ -+/** -+ * isp_csi2_irq_complexio1_set - Enables CSI2 ComplexIO IRQs. -+ * @enable: Enable/disable CSI2 ComplexIO #1 interrupts -+ **/ -+void isp_csi2_irq_complexio1_set(int enable) -+{ -+ u32 reg; -+ reg = ISPCSI2_COMPLEXIO1_IRQENABLE_STATEALLULPMEXIT | -+ ISPCSI2_COMPLEXIO1_IRQENABLE_STATEALLULPMENTER | -+ ISPCSI2_COMPLEXIO1_IRQENABLE_STATEULPM5 | -+ ISPCSI2_COMPLEXIO1_IRQENABLE_ERRCONTROL5 | -+ ISPCSI2_COMPLEXIO1_IRQENABLE_ERRESC5 | -+ ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTSYNCHS5 | -+ ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTHS5 | -+ ISPCSI2_COMPLEXIO1_IRQENABLE_STATEULPM4 | -+ ISPCSI2_COMPLEXIO1_IRQENABLE_ERRCONTROL4 | -+ ISPCSI2_COMPLEXIO1_IRQENABLE_ERRESC4 | -+ ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTSYNCHS4 | -+ ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTHS4 | -+ ISPCSI2_COMPLEXIO1_IRQENABLE_STATEULPM3 | -+ ISPCSI2_COMPLEXIO1_IRQENABLE_ERRCONTROL3 | -+ ISPCSI2_COMPLEXIO1_IRQENABLE_ERRESC3 | -+ ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTSYNCHS3 | -+ ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTHS3 | -+ ISPCSI2_COMPLEXIO1_IRQENABLE_STATEULPM2 | -+ ISPCSI2_COMPLEXIO1_IRQENABLE_ERRCONTROL2 | -+ ISPCSI2_COMPLEXIO1_IRQENABLE_ERRESC2 | -+ ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTSYNCHS2 | -+ ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTHS2 | -+ ISPCSI2_COMPLEXIO1_IRQENABLE_STATEULPM1 | -+ ISPCSI2_COMPLEXIO1_IRQENABLE_ERRCONTROL1 | -+ ISPCSI2_COMPLEXIO1_IRQENABLE_ERRESC1 | -+ ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTSYNCHS1 | -+ ISPCSI2_COMPLEXIO1_IRQENABLE_ERRSOTHS1; -+ isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_COMPLEXIO1_IRQSTATUS); -+ if (enable) { -+ reg |= isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_COMPLEXIO1_IRQENABLE); -+ } else -+ reg = 0; -+ isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_COMPLEXIO1_IRQENABLE); -+} -+EXPORT_SYMBOL(isp_csi2_irq_complexio1_set); -+ -+/** -+ * isp_csi2_irq_ctx_set - Enables CSI2 Context IRQs. -+ * @enable: Enable/disable CSI2 Context interrupts -+ **/ -+void isp_csi2_irq_ctx_set(int enable) -+{ -+ u32 reg; -+ int i; -+ -+ reg = ISPCSI2_CTX_IRQSTATUS_FS_IRQ | ISPCSI2_CTX_IRQSTATUS_FE_IRQ; -+ for (i = 0; i < 8; i++) { -+ isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_CTX_IRQSTATUS(i)); -+ if (enable) { -+ isp_reg_or(OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_CTX_IRQENABLE(i), reg); -+ } else { -+ isp_reg_writel(0, OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_CTX_IRQENABLE(i)); -+ } -+ } -+ -+} -+EXPORT_SYMBOL(isp_csi2_irq_ctx_set); -+ -+/** -+ * isp_csi2_irq_status_set - Enables CSI2 Status IRQs. -+ * @enable: Enable/disable CSI2 Status interrupts -+ **/ -+void isp_csi2_irq_status_set(int enable) -+{ -+ u32 reg; -+ reg = ISPCSI2_IRQSTATUS_OCP_ERR_IRQ | -+ ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ | -+ ISPCSI2_IRQSTATUS_ECC_CORRECTION_IRQ | -+ ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ | -+ ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ | -+ ISPCSI2_IRQSTATUS_COMPLEXIO1_ERR_IRQ | -+ ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ | -+ ISPCSI2_IRQSTATUS_CONTEXT(0); -+ isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_IRQSTATUS); -+ if (enable) -+ reg |= isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_IRQENABLE); -+ else -+ reg = 0; -+ -+ isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_IRQENABLE); -+} -+EXPORT_SYMBOL(isp_csi2_irq_status_set); -+ -+/** -+ * isp_csi2_irq_status_set - Enables main CSI2 IRQ. -+ * @enable: Enable/disable main CSI2 interrupt -+ **/ -+void isp_csi2_irq_set(int enable) -+{ -+ isp_reg_writel(IRQ0STATUS_CSIA_IRQ, OMAP3_ISP_IOMEM_MAIN, -+ ISP_IRQ0STATUS); -+ isp_reg_and_or(OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE, -+ ~IRQ0ENABLE_CSIA_IRQ, -+ (enable ? IRQ0ENABLE_CSIA_IRQ : 0)); -+} -+EXPORT_SYMBOL(isp_csi2_irq_set); -+ -+/** -+ * isp_csi2_irq_all_set - Enable/disable CSI2 interrupts. -+ * @enable: 0-Disable, 1-Enable. -+ **/ -+void isp_csi2_irq_all_set(int enable) -+{ -+ if (enable) { -+ isp_csi2_irq_complexio1_set(enable); -+ isp_csi2_irq_ctx_set(enable); -+ isp_csi2_irq_status_set(enable); -+ isp_csi2_irq_set(enable); -+ } else { -+ isp_csi2_irq_set(enable); -+ isp_csi2_irq_status_set(enable); -+ isp_csi2_irq_ctx_set(enable); -+ isp_csi2_irq_complexio1_set(enable); -+ } -+ return; -+} -+EXPORT_SYMBOL(isp_csi2_irq_all_set); -+ -+/** -+ * isp_csi2_reset - Resets the CSI2 module. -+ * -+ * Returns 0 if successful, or -EBUSY if power command didn't respond. -+ **/ -+int isp_csi2_reset(void) -+{ -+ u32 reg; -+ u8 soft_reset_retries = 0; -+ int i; -+ -+ reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_SYSCONFIG); -+ reg |= ISPCSI2_SYSCONFIG_SOFT_RESET_RESET; -+ isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_SYSCONFIG); -+ -+ do { -+ reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_SYSSTATUS) & -+ ISPCSI2_SYSSTATUS_RESET_DONE_MASK; -+ if (reg == ISPCSI2_SYSSTATUS_RESET_DONE_DONE) -+ break; -+ soft_reset_retries++; -+ if (soft_reset_retries < 5) -+ udelay(100); -+ } while (soft_reset_retries < 5); -+ -+ if (soft_reset_retries == 5) { -+ printk(KERN_ERR "CSI2: Soft reset try count exceeded!\n"); -+ return -EBUSY; -+ } -+ -+ reg = isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_SYSCONFIG); -+ reg &= ~ISPCSI2_SYSCONFIG_MSTANDBY_MODE_MASK; -+ reg |= ISPCSI2_SYSCONFIG_MSTANDBY_MODE_NO; -+ reg &= ~ISPCSI2_SYSCONFIG_AUTO_IDLE_MASK; -+ isp_reg_writel(reg, OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_SYSCONFIG); -+ -+ uses_videoport = false; -+ update_complexio_cfg1 = false; -+ update_phy_cfg0 = false; -+ update_phy_cfg1 = false; -+ for (i = 0; i < 8; i++) { -+ update_ctx_ctrl1[i] = false; -+ update_ctx_ctrl2[i] = false; -+ update_ctx_ctrl3[i] = false; -+ } -+ update_timing = false; -+ update_ctrl = false; -+ -+ isp_csi2_complexio_lanes_get(); -+ isp_csi2_ctrl_get(); -+ isp_csi2_ctx_get_all(); -+ isp_csi2_phy_get(); -+ isp_csi2_timings_get_all(); -+ -+ isp_csi2_complexio_power_autoswitch(true); -+ isp_csi2_complexio_power(ISP_CSI2_POWER_ON); -+ -+ isp_csi2_timings_config_forcerxmode(1, true); -+ isp_csi2_timings_config_stopstate_cnt(1, 0x1FF); -+ isp_csi2_timings_update_all(true); -+ -+ return 0; -+} -+ -+/** -+ * isp_csi2_enable - Enables the CSI2 module. -+ * @enable: Enables/disables the CSI2 module. -+ **/ -+void isp_csi2_enable(int enable) -+{ -+ if (enable) { -+ isp_csi2_ctx_config_enabled(0, true); -+ isp_csi2_ctx_config_eof_enabled(0, true); -+ isp_csi2_ctx_config_checksum_enabled(0, true); -+ isp_csi2_ctx_update(0, false); -+ -+ isp_csi2_ctrl_config_ecc_enable(true); -+ isp_csi2_ctrl_config_if_enable(true); -+ isp_csi2_ctrl_update(false); -+ } else { -+ isp_csi2_ctx_config_enabled(0, false); -+ isp_csi2_ctx_config_eof_enabled(0, false); -+ isp_csi2_ctx_config_checksum_enabled(0, false); -+ isp_csi2_ctx_update(0, false); -+ -+ isp_csi2_ctrl_config_ecc_enable(false); -+ isp_csi2_ctrl_config_if_enable(false); -+ isp_csi2_ctrl_update(false); -+ } -+} -+EXPORT_SYMBOL(isp_csi2_enable); -+ -+/** -+ * isp_csi2_regdump - Prints CSI2 debug information. -+ **/ -+void isp_csi2_regdump(void) -+{ -+ printk(KERN_DEBUG "-------------Register dump-------------\n"); -+ -+ printk(KERN_DEBUG "ISP_CTRL: %x\n", -+ isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_CTRL)); -+ printk(KERN_DEBUG "ISP_TCTRL_CTRL: %x\n", -+ isp_reg_readl(OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL)); -+ -+ printk(KERN_DEBUG "ISPCCDC_SDR_ADDR: %x\n", -+ isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDR_ADDR)); -+ printk(KERN_DEBUG "ISPCCDC_SYN_MODE: %x\n", -+ isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE)); -+ printk(KERN_DEBUG "ISPCCDC_CFG: %x\n", -+ isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG)); -+ printk(KERN_DEBUG "ISPCCDC_FMTCFG: %x\n", -+ isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG)); -+ printk(KERN_DEBUG "ISPCCDC_HSIZE_OFF: %x\n", -+ isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HSIZE_OFF)); -+ printk(KERN_DEBUG "ISPCCDC_HORZ_INFO: %x\n", -+ isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HORZ_INFO)); -+ printk(KERN_DEBUG "ISPCCDC_VERT_START: %x\n", -+ isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, -+ ISPCCDC_VERT_START)); -+ printk(KERN_DEBUG "ISPCCDC_VERT_LINES: %x\n", -+ isp_reg_readl(OMAP3_ISP_IOMEM_CCDC, -+ ISPCCDC_VERT_LINES)); -+ -+ printk(KERN_DEBUG "ISPCSI2_COMPLEXIO_CFG1: %x\n", -+ isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_COMPLEXIO_CFG1)); -+ printk(KERN_DEBUG "ISPCSI2_SYSSTATUS: %x\n", -+ isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_SYSSTATUS)); -+ printk(KERN_DEBUG "ISPCSI2_SYSCONFIG: %x\n", -+ isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_SYSCONFIG)); -+ printk(KERN_DEBUG "ISPCSI2_IRQENABLE: %x\n", -+ isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_IRQENABLE)); -+ printk(KERN_DEBUG "ISPCSI2_IRQSTATUS: %x\n", -+ isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_IRQSTATUS)); -+ -+ printk(KERN_DEBUG "ISPCSI2_CTX_IRQENABLE(0): %x\n", -+ isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_CTX_IRQENABLE(0))); -+ printk(KERN_DEBUG "ISPCSI2_CTX_IRQSTATUS(0): %x\n", -+ isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_CTX_IRQSTATUS(0))); -+ printk(KERN_DEBUG "ISPCSI2_TIMING: %x\n", -+ isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_TIMING)); -+ printk(KERN_DEBUG "ISPCSI2PHY_CFG0: %x\n", -+ isp_reg_readl(OMAP3_ISP_IOMEM_CSI2PHY, -+ ISPCSI2PHY_CFG0)); -+ printk(KERN_DEBUG "ISPCSI2PHY_CFG1: %x\n", -+ isp_reg_readl(OMAP3_ISP_IOMEM_CSI2PHY, -+ ISPCSI2PHY_CFG1)); -+ printk(KERN_DEBUG "ISPCSI2_CTX_CTRL1(0): %x\n", -+ isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_CTX_CTRL1(0))); -+ printk(KERN_DEBUG "ISPCSI2_CTX_CTRL2(0): %x\n", -+ isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_CTX_CTRL2(0))); -+ printk(KERN_DEBUG "ISPCSI2_CTX_CTRL3(0): %x\n", -+ isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_CTX_CTRL3(0))); -+ printk(KERN_DEBUG "ISPCSI2_CTX_DAT_OFST(0): %x\n", -+ isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_CTX_DAT_OFST(0))); -+ printk(KERN_DEBUG "ISPCSI2_CTX_DAT_PING_ADDR(0): %x\n", -+ isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_CTX_DAT_PING_ADDR(0))); -+ printk(KERN_DEBUG "ISPCSI2_CTX_DAT_PONG_ADDR(0): %x\n", -+ isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, -+ ISPCSI2_CTX_DAT_PONG_ADDR(0))); -+ printk(KERN_DEBUG "ISPCSI2_CTRL: %x\n", -+ isp_reg_readl(OMAP3_ISP_IOMEM_CSI2A, ISPCSI2_CTRL)); -+ printk(KERN_DEBUG "---------------------------------------\n"); -+} -+ -+/** -+ * isp_csi2_cleanup - Routine for module driver cleanup -+ **/ -+void isp_csi2_cleanup(void) -+{ -+ return; -+} -+ -+/** -+ * isp_csi2_init - Routine for module driver init -+ **/ -+int __init isp_csi2_init(void) -+{ -+ int i; -+ -+ update_complexio_cfg1 = false; -+ update_phy_cfg0 = false; -+ update_phy_cfg1 = false; -+ for (i = 0; i < 8; i++) { -+ update_ctx_ctrl1[i] = false; -+ update_ctx_ctrl2[i] = false; -+ update_ctx_ctrl3[i] = false; -+ } -+ update_timing = false; -+ update_ctrl = false; -+ -+ memset(¤t_csi2_cfg, 0, sizeof(current_csi2_cfg)); -+ memset(¤t_csi2_cfg_update, 0, sizeof(current_csi2_cfg_update)); -+ return 0; -+} -+ -+MODULE_AUTHOR("Texas Instruments"); -+MODULE_DESCRIPTION("ISP CSI2 Receiver Module"); -+MODULE_LICENSE("GPL"); -diff --git a/drivers/media/video/isp/ispcsi2.h b/drivers/media/video/isp/ispcsi2.h -new file mode 100644 -index 0000000..4582c96 ---- /dev/null -+++ b/drivers/media/video/isp/ispcsi2.h -@@ -0,0 +1,232 @@ -+/* -+ * ispcsi2.h -+ * -+ * Copyright (C) 2009 Texas Instruments. -+ * -+ * Contributors: -+ * Sergio Aguirre -+ * Dominic Curran -+ * -+ * This package 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. -+ * -+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR -+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED -+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. -+ */ -+ -+#ifndef OMAP_ISP_CSI2_API_H -+#define OMAP_ISP_CSI2_API_H -+#include -+ -+enum isp_csi2_irqevents { -+ OCP_ERR_IRQ = 0x4000, -+ SHORT_PACKET_IRQ = 0x2000, -+ ECC_CORRECTION_IRQ = 0x1000, -+ ECC_NO_CORRECTION_IRQ = 0x800, -+ COMPLEXIO2_ERR_IRQ = 0x400, -+ COMPLEXIO1_ERR_IRQ = 0x200, -+ FIFO_OVF_IRQ = 0x100, -+ CONTEXT7 = 0x80, -+ CONTEXT6 = 0x40, -+ CONTEXT5 = 0x20, -+ CONTEXT4 = 0x10, -+ CONTEXT3 = 0x8, -+ CONTEXT2 = 0x4, -+ CONTEXT1 = 0x2, -+ CONTEXT0 = 0x1, -+}; -+ -+enum isp_csi2_ctx_irqevents { -+ CTX_ECC_CORRECTION = 0x100, -+ CTX_LINE_NUMBER = 0x80, -+ CTX_FRAME_NUMBER = 0x40, -+ CTX_CS = 0x20, -+ CTX_LE = 0x8, -+ CTX_LS = 0x4, -+ CTX_FE = 0x2, -+ CTX_FS = 0x1, -+}; -+ -+enum isp_csi2_power_cmds { -+ ISP_CSI2_POWER_OFF, -+ ISP_CSI2_POWER_ON, -+ ISP_CSI2_POWER_ULPW, -+}; -+ -+enum isp_csi2_frame_mode { -+ ISP_CSI2_FRAME_IMMEDIATE, -+ ISP_CSI2_FRAME_AFTERFEC, -+}; -+ -+struct csi2_lanecfg { -+ u8 pos; -+ u8 pol; -+}; -+ -+struct isp_csi2_lanes_cfg { -+ struct csi2_lanecfg data[4]; -+ struct csi2_lanecfg clk; -+}; -+ -+struct isp_csi2_lanes_cfg_update { -+ bool data[4]; -+ bool clk; -+}; -+ -+struct isp_csi2_phy_cfg { -+ u8 ths_term; -+ u8 ths_settle; -+ u8 tclk_term; -+ unsigned tclk_miss:1; -+ u8 tclk_settle; -+}; -+ -+struct isp_csi2_phy_cfg_update { -+ bool ths_term; -+ bool ths_settle; -+ bool tclk_term; -+ bool tclk_miss; -+ bool tclk_settle; -+}; -+ -+struct isp_csi2_ctx_cfg { -+ u8 virtual_id; -+ u8 frame_count; -+ struct v4l2_pix_format format; -+ u16 alpha; -+ u16 data_offset; -+ u32 ping_addr; -+ u32 pong_addr; -+ bool eof_enabled; -+ bool eol_enabled; -+ bool checksum_enabled; -+ bool enabled; -+}; -+ -+struct isp_csi2_ctx_cfg_update { -+ bool virtual_id; -+ bool frame_count; -+ bool format; -+ bool alpha; -+ bool data_offset; -+ bool ping_addr; -+ bool pong_addr; -+ bool eof_enabled; -+ bool eol_enabled; -+ bool checksum_enabled; -+ bool enabled; -+}; -+ -+struct isp_csi2_timings_cfg { -+ bool force_rx_mode; -+ bool stop_state_16x; -+ bool stop_state_4x; -+ u16 stop_state_counter; -+}; -+ -+struct isp_csi2_timings_cfg_update { -+ bool force_rx_mode; -+ bool stop_state_16x; -+ bool stop_state_4x; -+ bool stop_state_counter; -+}; -+ -+struct isp_csi2_ctrl_cfg { -+ bool vp_clk_enable; -+ bool vp_only_enable; -+ u8 vp_out_ctrl; -+ bool debug_enable; -+ u8 burst_size; -+ enum isp_csi2_frame_mode frame_mode; -+ bool ecc_enable; -+ bool secure_mode; -+ bool if_enable; -+}; -+ -+struct isp_csi2_ctrl_cfg_update { -+ bool vp_clk_enable; -+ bool vp_only_enable; -+ bool vp_out_ctrl; -+ bool debug_enable; -+ bool burst_size; -+ bool frame_mode; -+ bool ecc_enable; -+ bool secure_mode; -+ bool if_enable; -+}; -+ -+struct isp_csi2_cfg { -+ struct isp_csi2_lanes_cfg lanes; -+ struct isp_csi2_phy_cfg phy; -+ struct isp_csi2_ctx_cfg contexts[8]; -+ struct isp_csi2_timings_cfg timings[2]; -+ struct isp_csi2_ctrl_cfg ctrl; -+}; -+ -+struct isp_csi2_cfg_update { -+ struct isp_csi2_lanes_cfg_update lanes; -+ struct isp_csi2_phy_cfg_update phy; -+ struct isp_csi2_ctx_cfg_update contexts[8]; -+ struct isp_csi2_timings_cfg_update timings[2]; -+ struct isp_csi2_ctrl_cfg_update ctrl; -+}; -+ -+int isp_csi2_complexio_lanes_config(struct isp_csi2_lanes_cfg *reqcfg); -+int isp_csi2_complexio_lanes_update(bool force_update); -+int isp_csi2_complexio_lanes_get(void); -+int isp_csi2_complexio_power_autoswitch(bool enable); -+int isp_csi2_complexio_power(enum isp_csi2_power_cmds power_cmd); -+int isp_csi2_ctrl_config_frame_mode(enum isp_csi2_frame_mode frame_mode); -+int isp_csi2_ctrl_config_vp_clk_enable(bool vp_clk_enable); -+int isp_csi2_ctrl_config_vp_only_enable(bool vp_only_enable); -+int isp_csi2_ctrl_config_debug_enable(bool debug_enable); -+int isp_csi2_ctrl_config_burst_size(u8 burst_size); -+int isp_csi2_ctrl_config_ecc_enable(bool ecc_enable); -+int isp_csi2_ctrl_config_secure_mode(bool secure_mode); -+int isp_csi2_ctrl_config_if_enable(bool if_enable); -+int isp_csi2_ctrl_config_vp_out_ctrl(u8 vp_out_ctrl); -+int isp_csi2_ctrl_update(bool force_update); -+int isp_csi2_ctrl_get(void); -+int isp_csi2_ctx_config_virtual_id(u8 ctxnum, u8 virtual_id); -+int isp_csi2_ctx_config_frame_count(u8 ctxnum, u8 frame_count); -+int isp_csi2_ctx_config_format(u8 ctxnum, u32 pixformat); -+int isp_csi2_ctx_config_alpha(u8 ctxnum, u16 alpha); -+int isp_csi2_ctx_config_data_offset(u8 ctxnum, u16 data_offset); -+int isp_csi2_ctx_config_ping_addr(u8 ctxnum, u32 ping_addr); -+int isp_csi2_ctx_config_pong_addr(u8 ctxnum, u32 pong_addr); -+int isp_csi2_ctx_config_eof_enabled(u8 ctxnum, bool eof_enabled); -+int isp_csi2_ctx_config_eol_enabled(u8 ctxnum, bool eol_enabled); -+int isp_csi2_ctx_config_checksum_enabled(u8 ctxnum, bool checksum_enabled); -+int isp_csi2_ctx_config_enabled(u8 ctxnum, bool enabled); -+int isp_csi2_ctx_update(u8 ctxnum, bool force_update); -+int isp_csi2_ctx_get(u8 ctxnum); -+int isp_csi2_ctx_update_all(bool force_update); -+int isp_csi2_ctx_get_all(void); -+int isp_csi2_phy_config(struct isp_csi2_phy_cfg *desiredphyconfig); -+int isp_csi2_calc_phy_cfg0(u32 mipiclk, u32 lbound_hs_settle, -+ u32 ubound_hs_settle); -+int isp_csi2_phy_update(bool force_update); -+int isp_csi2_phy_get(void); -+int isp_csi2_timings_config_forcerxmode(u8 io, bool force_rx_mode); -+int isp_csi2_timings_config_stopstate_16x(u8 io, bool stop_state_16x); -+int isp_csi2_timings_config_stopstate_4x(u8 io, bool stop_state_4x); -+int isp_csi2_timings_config_stopstate_cnt(u8 io, u16 stop_state_counter); -+int isp_csi2_timings_update(u8 io, bool force_update); -+int isp_csi2_timings_get(u8 io); -+int isp_csi2_timings_update_all(bool force_update); -+int isp_csi2_timings_get_all(void); -+void isp_csi2_irq_complexio1_set(int enable); -+void isp_csi2_irq_ctx_set(int enable); -+void isp_csi2_irq_status_set(int enable); -+void isp_csi2_irq_set(int enable); -+void isp_csi2_irq_all_set(int enable); -+ -+void isp_csi2_isr(void); -+int isp_csi2_reset(void); -+void isp_csi2_enable(int enable); -+void isp_csi2_regdump(void); -+ -+#endif /* OMAP_ISP_CSI2_H */ -+ --- -1.5.6.5 - -- cgit v1.2.3