[RESEND RFC PATCH v4 12/15] davinci: vpfe: add hardware interface for dm365 aew

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



add the hardware functionality for enablling the dm365
auto exposure and white balance unit. The module supports
hardware setup, isr management, and parameter validation.

Signed-off-by: Manjunath Hadli <manjunath.hadli@xxxxxx>
---
 drivers/media/video/davinci/dm365_a3_hw.c |  387 ++++++++++++++++++++
 drivers/media/video/davinci/dm365_a3_hw.h |  253 +++++++++++++
 drivers/media/video/davinci/dm365_aew.c   |  544 +++++++++++++++++++++++++++++
 drivers/media/video/davinci/dm365_aew.h   |   55 +++
 include/linux/dm365_aew.h                 |  153 ++++++++
 5 files changed, 1392 insertions(+), 0 deletions(-)
 create mode 100644 drivers/media/video/davinci/dm365_a3_hw.c
 create mode 100644 drivers/media/video/davinci/dm365_a3_hw.h
 create mode 100644 drivers/media/video/davinci/dm365_aew.c
 create mode 100644 drivers/media/video/davinci/dm365_aew.h
 create mode 100644 include/linux/dm365_aew.h

diff --git a/drivers/media/video/davinci/dm365_a3_hw.c b/drivers/media/video/davinci/dm365_a3_hw.c
new file mode 100644
index 0000000..b929c22
--- /dev/null
+++ b/drivers/media/video/davinci/dm365_a3_hw.c
@@ -0,0 +1,387 @@
+/*
+* Copyright (C) 2011 Texas Instruments Inc
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as
+* published by the Free Software Foundation version 2.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+*/
+#include "dm365_af.h"
+#include "dm365_aew.h"
+#include "dm365_a3_hw.h"
+
+/* 3A hardware module configuration */
+struct a3_config {
+	/* lock for write protection */
+	struct mutex lock;
+	/* base address */
+	void __iomem *base;
+};
+
+/* H3A module configuration */
+static struct a3_config a3_cfg;
+
+/* register access routines */
+static inline u32 regr(unsigned int offset)
+{
+	return __raw_readl(a3_cfg.base + offset);
+}
+
+static inline u32 regw(u32 val, unsigned int offset)
+{
+	__raw_writel(val, (a3_cfg.base + offset));
+
+	return val;
+}
+
+/* Function to set register */
+int af_register_setup(struct device *dev, struct af_device *af_dev)
+{
+	unsigned int address;
+	unsigned int utemp;
+	int index;
+
+	/* Lock resource since this register is written by
+	 * both the AF and AEW drivers
+	 */
+	mutex_lock(&a3_cfg.lock);
+	/* Configure Hardware Registers */
+	/* Set PCR Register */
+	utemp = regr(AFPCR);	/* Read PCR Register */
+
+	/*Set Accumulator Mode */
+	utemp &= ~FVMODE;
+	if (af_dev->config->mode == ACCUMULATOR_PEAK)
+		utemp |= FVMODE;
+	/* Set A-law */
+	utemp &= ~AF_ALAW_EN;
+	if (af_dev->config->alaw_enable == H3A_AF_ENABLE)
+		utemp |= AF_ALAW_EN;
+
+	/* Set HFV only or HFV and VFV */
+	utemp &= ~AF_VF_EN;
+	if (af_dev->config->fv_sel == AF_HFV_AND_VFV)
+		utemp |= AF_VF_EN;
+	/* Set RGB Position */
+	utemp &= ~RGBPOS;
+	utemp |= (af_dev->config->rgb_pos) << AF_RGBPOS_SHIFT;
+
+	utemp &= ~AF_MED_EN;
+	/*HMF Configurations */
+	if (af_dev->config->hmf_config.enable == H3A_AF_ENABLE) {
+		/* Enable HMF */
+		utemp |= AF_MED_EN;
+		/* Set Median Threshold */
+		utemp &= ~MED_TH;
+		utemp |= (af_dev->config->hmf_config.threshold <<
+				AF_MED_TH_SHIFT) & MED_TH;
+	}
+	/* Set PCR Register */
+	regw(utemp , AFPCR);
+	mutex_unlock(&a3_cfg.lock);
+
+	/* Configure AFPAX1 */
+	/*Paxel parameter configuration */
+	/*Set Width in AFPAX1 Register */
+	utemp = SET_VAL(af_dev->config->paxel_config.width) << AF_PAXW_SHIFT;
+
+	/* Set height in AFPAX1 */
+	utemp &= ~PAXH;
+	utemp |= SET_VAL(af_dev->config->paxel_config.height);
+	regw(utemp , AFPAX1);
+	/* Configure AFPAX2 Register */
+	/* Set Column Increment in AFPAX2 Register */
+	utemp = 0;
+	utemp &= ~AFINCH;
+	utemp |= SET_VAL(af_dev->config->paxel_config.column_incr) <<
+			AF_COLUMN_INCR_SHIFT;
+
+	/* Set Line Increment in AFPAX2 Register */
+	utemp &= ~AFINCV;
+	utemp |= SET_VAL(af_dev->config->paxel_config.line_incr) <<
+			AF_LINE_INCR_SHIFT;
+
+	/* Set Vertical Count */
+	utemp &= ~PAXVC;
+	utemp |= (af_dev->config->paxel_config.vt_cnt - 1) << AF_VT_COUNT_SHIFT;
+	/* Set Horizontal Count */
+	utemp &= ~PAXHC;
+	utemp |= af_dev->config->paxel_config.hz_cnt - 1;
+	regw(utemp, AFPAX2);
+
+	/* Configure PAXSTART Register */
+	/*Configure Horizontal Start */
+	utemp = 0;
+	utemp &= ~PAXSH;
+	utemp |= af_dev->config->paxel_config.hz_start << AF_HZ_START_SHIFT;
+	/* Configure Vertical Start */
+	utemp &= ~PAXSV;
+	utemp |= af_dev->config->paxel_config.vt_start;
+	regw(utemp , AFPAXSTART);
+
+	/*SetIIRSH Register */
+	regw(af_dev->config->iir_config.hz_start_pos, AFIIRSH);
+
+	/* Set IIR Filter0 Coefficients */
+	address = AFCOEF010;
+	for (index = 0; index < AF_NUMBER_OF_HFV_COEF; index += 2) {
+		utemp = af_dev->config->iir_config.coeff_set0[index] &
+			COEF_MASK0;
+		if (index < AF_NUMBER_OF_HFV_COEF - 1) {
+			utemp |= (af_dev->config->iir_config.
+			coeff_set0[index + 1] << AF_COEF_SHIFT) & COEF_MASK1;
+		}
+		regw(utemp, address);
+		dev_dbg(dev, "COEF0 %x\n", regr(address));
+		address = address + AF_OFFSET;
+	}
+
+	/* Set IIR Filter1 Coefficients */
+	address = AFCOEF110;
+	for (index = 0; index < AF_NUMBER_OF_HFV_COEF; index += 2) {
+		utemp = af_dev->config->iir_config.coeff_set1[index] &
+					COEF_MASK0;
+		if (index < AF_NUMBER_OF_HFV_COEF-1) {
+			utemp |= (af_dev->config->iir_config.
+			coeff_set1[index + 1] << AF_COEF_SHIFT) & COEF_MASK1;
+		}
+		regw(utemp, address);
+		dev_dbg(dev, "COEF0 %x\n", regr(address));
+		address = address + AF_OFFSET;
+	}
+
+	/* HFV thresholds for FIR 1 & 2 */
+	utemp = af_dev->config->fir_config.hfv_thr1 & HFV_THR0_MASK;
+	utemp |= (af_dev->config->fir_config.hfv_thr2 << HFV_THR2_SHIFT) &
+			HFV_THR2_MASK;
+	regw(utemp, AF_HFV_THR);
+
+	/* VFV coefficients and thresholds */
+	utemp = af_dev->config->fir_config.coeff_1[0] & VFV_COEF_MASK0;
+	utemp |= (af_dev->config->fir_config.coeff_1[1] << 8) & VFV_COEF_MASK1;
+	utemp |= (af_dev->config->fir_config.coeff_1[2] << 16) & VFV_COEF_MASK2;
+	utemp |= (af_dev->config->fir_config.coeff_1[3] << 24) & VFV_COEF_MASK3;
+	regw(utemp, AF_VFV_CFG1);
+
+	utemp = af_dev->config->fir_config.coeff_1[4] & VFV_COEF_MASK0;
+	utemp |= (af_dev->config->fir_config.vfv_thr1 << VFV_THR_SHIFT) &
+				VFV_THR_MASK;
+	regw(utemp, AF_VFV_CFG2);
+
+	/* VFV coefficients and thresholds */
+	utemp = af_dev->config->fir_config.coeff_2[0] & VFV_COEF_MASK0;
+	utemp |= (af_dev->config->fir_config.coeff_2[1] << 8) & VFV_COEF_MASK1;
+	utemp |= (af_dev->config->fir_config.coeff_2[2] << 16) & VFV_COEF_MASK2;
+	utemp |= (af_dev->config->fir_config.coeff_2[3] << 24) & VFV_COEF_MASK3;
+	regw(utemp, AF_VFV_CFG3);
+
+	utemp = af_dev->config->fir_config.coeff_2[4] & VFV_COEF_MASK0;
+	utemp |= (af_dev->config->fir_config.vfv_thr2 << VFV_THR_SHIFT) &
+			VFV_THR_MASK;
+	regw(utemp, AF_VFV_CFG4);
+	/* Set AFBUFST to Current buffer Physical Address */
+	regw((unsigned int)(virt_to_phys(af_dev->buff_curr)), AFBUFST);
+
+	return 0;
+}
+EXPORT_SYMBOL(af_register_setup);
+
+inline u32 af_get_hw_state(void)
+{
+	return (regr(AFPCR) & AF_BUSYAF) >> AF_BUSYAF_SHIFT;
+}
+EXPORT_SYMBOL(af_get_hw_state);
+
+inline u32 aew_get_hw_state(void)
+{
+	return (regr(AEWPCR) & AEW_BUSYAEWB) >> AEW_BUSYAEW_SHIFT;
+}
+EXPORT_SYMBOL(aew_get_hw_state);
+
+inline u32 af_get_enable(void)
+{
+	return regr(AFPCR) & AF_EN;
+}
+EXPORT_SYMBOL(af_get_enable);
+
+inline u32 aew_get_enable(void)
+{
+	return (regr(AEWPCR) & AEW_EN) >> AEW_EN_SHIFT;
+}
+EXPORT_SYMBOL(aew_get_enable);
+
+/* Function to Enable/Disable AF Engine */
+inline void af_engine_setup(struct device *dev, int enable)
+{
+	unsigned int pcr;
+
+	mutex_lock(&a3_cfg.lock);
+	pcr = regr(AFPCR);
+	dev_dbg(dev, "Engine Setup value before PCR : %x\n", pcr);
+
+	/* Set AF_EN bit in PCR Register */
+	if (enable)
+		pcr |= AF_EN;
+	else
+		pcr &= ~AF_EN;
+
+	regw(pcr, AFPCR);
+	mutex_unlock(&a3_cfg.lock);
+
+	dev_dbg(dev, "Engine Setup value after PCR : %x\n", pcr);
+}
+EXPORT_SYMBOL(af_engine_setup);
+
+/* Function to set address */
+inline void af_set_address(struct device *dev, unsigned long address)
+{
+	regw((address & ~0x3F), AFBUFST);
+}
+EXPORT_SYMBOL(af_set_address);
+
+/* Function to set hardware configuration registers */
+int aew_register_setup(struct device *dev, struct aew_device *aew_dev)
+{
+	unsigned utemp;
+
+	mutex_lock(&a3_cfg.lock);
+	/* Set up the registers */
+	utemp = regr(AEWPCR);
+
+	/* Enable A Law */
+	if (aew_dev->config->alaw_enable == H3A_AEW_ENABLE)
+		utemp |= AEW_ALAW_EN;
+	else
+		utemp &= ~AEW_ALAW_EN;
+
+	utemp &= ~AEW_MED_EN;
+	/*HMF Configurations */
+	if (aew_dev->config->hmf_config.enable == H3A_AEW_ENABLE) {
+		/* Enable HMF */
+		utemp |= AEW_MED_EN;
+		/* Set Median Threshold */
+		utemp &= ~MED_TH;
+		utemp |= (aew_dev->config->hmf_config.threshold <<
+			AF_MED_TH_SHIFT) & MED_TH;
+	}
+
+	/*Configure Saturation limit */
+	utemp &= ~AVE2LMT;
+	utemp |= aew_dev->config->saturation_limit << AEW_AVE2LMT_SHIFT;
+	regw(utemp, AEWPCR);
+	mutex_unlock(&a3_cfg.lock);
+
+	/*Window parameter configuration */
+	/* Configure Window Width in AEWWIN1 register */
+	utemp = SET_VAL(aew_dev->config->window_config.height) <<
+				AEW_WINH_SHIFT;
+
+	/* Configure Window height  in AEWWIN1 register */
+	utemp |= SET_VAL(aew_dev->config->window_config.width) <<
+				AEW_WINW_SHIFT;
+
+	/* Configure Window vertical count  in AEWWIN2 register */
+	utemp |= (aew_dev->config->window_config.vt_cnt - 1) <<
+				AEW_VT_COUNT_SHIFT;
+
+	/* Configure Window horizontal count  in AEWWIN1 register */
+	utemp |= (aew_dev->config->window_config).hz_cnt - 1;
+
+	/* Configure Window vertical start  in AEWWIN1 register */
+	regw(utemp, AEWWIN1);
+
+	/*Window Start parameter configuration */
+	utemp = aew_dev->config->window_config.vt_start << AEW_VT_START_SHIFT;
+
+	/* Configure Window horizontal start  in AEWWIN2 register */
+	utemp &= ~WINSH;
+	utemp |= (aew_dev->config->window_config).hz_start;
+	regw(utemp, AEWINSTART);
+
+	/*Window Line Increment configuration */
+	/*Configure vertical line increment in AEWSUBWIN */
+	utemp = SET_VAL(aew_dev->config->window_config.
+			 vt_line_incr) << AEW_LINE_INCR_SHIFT;
+
+	/* Configuring Horizontal Line increment in AEWSUBWIN */
+	utemp &= ~AEWINCH;
+	utemp |= SET_VAL(aew_dev->config->window_config.hz_line_incr);
+
+	regw(utemp, AEWSUBWIN);
+
+	/* Black Window Configuration */
+	/* Configure vertical start and height in AEWWINBLK */
+	utemp = (aew_dev->config->blackwindow_config).vt_start <<
+			AEW_BLKWIN_VT_START_SHIFT;
+
+	/* Configure height in Black window */
+	utemp &= ~BLKWINH;
+	utemp |= SET_VAL(aew_dev->config->blackwindow_config.height);
+	regw(utemp, AEWINBLK);
+
+	/* AE/AWB engine configuration */
+	utemp = aew_dev->config->sum_shift & AEW_SUMSHFT_MASK;
+	utemp |= (aew_dev->config->out_format << AEFMT_SHFT) & AEFMT_MASK;
+	regw(utemp, AEW_CFG);
+
+	/* Set AFBUFST to Current buffer Physical Address */
+	regw((unsigned int)(virt_to_phys(aew_dev->buff_curr)), AEWBUFST);
+
+	return 0;
+}
+EXPORT_SYMBOL(aew_register_setup);
+
+/* Function to enable/ disable AEW Engine */
+inline void aew_engine_setup(struct device *dev, int value)
+{
+	unsigned int pcr;
+
+	dev_dbg(dev, "AEW_REG(PCR) Before Setting %x\n", regr(AEWPCR));
+	mutex_lock(&a3_cfg.lock);
+	/* Read Pcr Register */
+	pcr = regr(AEWPCR);
+	pcr &= ~AEW_EN;
+	pcr |= value << AEW_EN_SHIFT;
+	/*Set AF_EN bit in PCR Register */
+	regw(pcr, AEWPCR);
+	mutex_unlock(&a3_cfg.lock);
+	dev_dbg(dev, "After Setting %d : PCR VALUE %x\n", value, regr(AEWPCR));
+
+}
+EXPORT_SYMBOL(aew_engine_setup);
+
+/* Function used to set adddress */
+inline void aew_set_address(struct device *dev, unsigned long address)
+{
+	regw((address & ~0x3F), AEWBUFST);
+}
+EXPORT_SYMBOL(aew_set_address);
+
+static int  dm365_afew_hw_init(void)
+{
+	mutex_init(&a3_cfg.lock);
+	a3_cfg.base = ioremap(DM365_A3_HW_ADDR, DM365_A3_HW_ADDR_SIZE);
+	if (!a3_cfg.base) {
+		printk(KERN_ERR "Unable to ioremap 3A registers\n");
+		return -EINVAL;
+	}
+	regw(0, LINE_START);
+
+	return 0;
+}
+
+static void dm365_afew_hw_exit(void)
+{
+	iounmap(a3_cfg.base);
+}
+subsys_initcall(dm365_afew_hw_init);
+module_exit(dm365_afew_hw_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/davinci/dm365_a3_hw.h b/drivers/media/video/davinci/dm365_a3_hw.h
new file mode 100644
index 0000000..eb5a1d4
--- /dev/null
+++ b/drivers/media/video/davinci/dm365_a3_hw.h
@@ -0,0 +1,253 @@
+/*
+* Copyright (C) 2011 Texas Instruments Inc
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as
+* published by the Free Software Foundation version 2.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+*/
+
+#ifndef DM365_A3_HW_H
+#define DM365_A3_HW_H
+
+#include <linux/io.h>
+#include <linux/device.h>
+#include <mach/hardware.h>
+#include "dm365_aew.h"
+#include "dm365_af.h"
+
+/* AF/AE/AWB Base address and range */
+#define DM365_A3_HW_ADDR	0x1c71400
+#define DM365_A3_HW_ADDR_SIZE	128
+/* AF Register Offsets */
+
+/* Peripheral Revision and Class Information */
+#define AFPID			0x0
+/* Peripheral Control Register */
+#define AFPCR			0x4
+/* Setup for the Paxel Configuration */
+#define AFPAX1			0x8
+/* Setup for the Paxel Configuration */
+#define AFPAX2			0xc
+/* Start Position for AF Engine Paxels */
+#define AFPAXSTART		0x10
+/* Start Position for IIRSH */
+#define AFIIRSH			0x14
+/* SDRAM/DDRAM Start address */
+#define AFBUFST			0x18
+/* IIR filter coefficient data for SET 0 */
+#define AFCOEF010		0x1c
+/* IIR filter coefficient data for SET 0 */
+#define AFCOEF032		0x20
+/* IIR filter coefficient data for SET 0 */
+#define AFCOEF054		0x24
+/* IIR filter coefficient data for SET 0 */
+#define AFCOEF076		0x28
+/* IIR filter coefficient data for SET 0 */
+#define AFCOEF098		0x2c
+/* IIR filter coefficient data for SET 0 */
+#define AFCOEF0010		0x30
+/* IIR filter coefficient data for SET 1 */
+#define AFCOEF110		0x34
+/* IIR filter coefficient data for SET 1 */
+#define AFCOEF132		0x38
+/* IIR filter coefficient data for SET 1 */
+#define AFCOEF154		0x3c
+/* IIR filter coefficient data for SET 1 */
+#define AFCOEF176		0x40
+/* IIR filter coefficient data for SET 1 */
+#define AFCOEF198		0x44
+/* IIR filter coefficient data for SET 1 */
+#define AFCOEF1010		0x48
+
+/* Vertical Focus vlaue configuration 1 */
+#define AF_VFV_CFG1		0x68
+/* Vertical Focus vlaue configuration 2 */
+#define AF_VFV_CFG2		0x6c
+/* Vertical Focus vlaue configuration 3 */
+#define AF_VFV_CFG3		0x70
+/* Vertical Focus vlaue configuration 4 */
+#define AF_VFV_CFG4		0x74
+/* Horizontal Focus vlaue Threshold */
+#define AF_HFV_THR		0x78
+/* COEFFICIENT BASE ADDRESS */
+
+#define AF_OFFSET	0x00000004
+
+/* AEW Register offsets */
+#define AEWPID			AFPID
+/* Peripheral Control Register */
+#define AEWPCR			AFPCR
+/* Configuration for AE/AWB Windows */
+#define AEWWIN1			0x4c
+/* Start position for AE/AWB Windows */
+#define AEWINSTART		0x50
+/* Start position and height for black linr of AE/AWB Windows */
+#define AEWINBLK		0x54
+/* Configuration for subsampled data in AE/AWB windows */
+#define AEWSUBWIN		0x58
+/* SDRAM/DDRAM Start address for AEW Engine */
+#define AEWBUFST		0x5c
+/* Line start */
+#define LINE_START		0x64
+
+/* AEW Engine configuration */
+#define AEW_CFG			0x60
+
+/* PID fields */
+#define PID_MINOR		(0x3f << 0)
+#define PID_MAJOR		(7 << 8)
+#define PID_RTL			(0x1f << 11)
+#define PID_FUNC		(0xfff << 16)
+#define PID_SCHEME		(3 << 30)
+
+/* PCR FIELDS */
+
+/*Saturation Limit */
+#define AVE2LMT			(0x3ff << 22)
+#define AF_VF_EN		(1 << 20)
+#define AEW_MED_EN		(1 << 19)
+/* Busy bit for AEW */
+#define AEW_BUSYAEWB		(1 << 18)
+/* Alaw Enable/Disable Bit */
+#define AEW_ALAW_EN		(1 << 17)
+/* AEW Engine Enable/Disable bit */
+#define AEW_EN			(1 << 16)
+/* Busy Bit for AF */
+#define AF_BUSYAF		(1 << 15)
+#define FVMODE			(1 << 14)
+#define RGBPOS			(7 << 11)
+#define MED_TH			(0xff << 3)
+#define AF_MED_EN		(1 << 2)
+#define AF_ALAW_EN		(1 << 1)
+#define AF_EN			(1 << 0)
+
+/*
+ * AFPAX1 fields
+ */
+#define PAXW		(0xff << 16)
+#define PAXH		0xff
+
+/*
+ * AFPAX2 fields
+ */
+#define  AFINCH		(0xf << 17)
+#define  AFINCV		(0xf << 13)
+#define  PAXVC		(0x7f << 6)
+#define  PAXHC		0x3f
+
+/*
+ * AFPAXSTART fields
+ */
+#define  PAXSH		(0xfff << 16)
+#define  PAXSV		0xfff
+
+/*
+ * IIR COEFFICIENT MASKS
+ */
+#define COEF_MASK0	0xfff
+#define COEF_MASK1	(0xfff << 16)
+
+/*
+ * VFV_CFGX COEFFICIENT MASKS
+ */
+#define VFV_COEF_MASK0		0xff
+#define VFV_COEF_MASK1		(0xff << 8)
+#define VFV_COEF_MASK2		(0xff << 16)
+#define VFV_COEF_MASK3		(0xff << 24)
+
+/* HFV THR MASKS */
+#define HFV_THR0_MASK		0xffff
+#define HFV_THR2_SHIFT		16
+#define HFV_THR2_MASK		(0xffff << HFV_THR2_SHIFT)
+
+/* VFV THR MASKS */
+#define VFV_THR_SHIFT		16
+#define VFV_THR_MASK		(0xffff << VFV_THR_SHIFT)
+
+/* BIT SHIFTS */
+#define AF_BUSYAF_SHIFT		15
+#define AEW_EN_SHIFT		16
+#define AEW_BUSYAEW_SHIFT	18
+#define AF_RGBPOS_SHIFT		11
+#define AF_MED_TH_SHIFT		3
+#define AF_PAXW_SHIFT		16
+#define AF_LINE_INCR_SHIFT	13
+#define AF_COLUMN_INCR_SHIFT	17
+#define AF_VT_COUNT_SHIFT	6
+#define AF_HZ_START_SHIFT	16
+#define AF_COEF_SHIFT		16
+
+/* AEWWIN1 fields */
+/* Window Height */
+#define WINH			(0x7f << 24)
+/* Window Width */
+#define WINW			(0x7f << 13)
+/* Window vertical Count */
+#define WINVC			(0x7f << 6)
+/* Window Horizontal Count */
+#define WINHC			0x3f
+
+/* AEWWINSTART fields */
+/* Window Vertical Start */
+#define WINSV			(0xfff << 16)
+/* Window Horizontal start */
+#define WINSH			0xfff
+
+/* AEWWINBLK fields
+ * Black Window Vertical Start
+ */
+#define BLKWINSV		(0xfff << 16)
+/* Black Window height */
+#define BLKWINH			0x7f
+
+/* AEWSUBWIN fields
+ * Vertical Lime Increment
+ */
+#define AEWINCV			(0xf << 8)
+/* Horizontal Line Increment */
+#define AEWINCH			0xf
+
+/* BIT POSITIONS */
+#define AEW_AVE2LMT_SHIFT	22
+#define AEW_WINH_SHIFT		24
+#define AEW_WINW_SHIFT		13
+#define AEW_VT_COUNT_SHIFT	6
+#define AEW_VT_START_SHIFT	16
+#define AEW_LINE_INCR_SHIFT	8
+
+#define AEW_EN_SHIFT			16
+#define AEW_BUSYAEWB_SHIFT		18
+#define AEW_BLKWIN_VT_START_SHIFT	16
+
+#define AEFMT_SHFT		8
+#define AEFMT_MASK		(3 << AEFMT_SHFT)
+#define AEW_SUMSHFT_MASK	0xf
+
+#define SET_VAL(x)		(((x) / 2) - 1)
+#define NOT_EVEN		1
+#define CHECK_EVEN(x)		((x) % 2)
+
+/* Function declaration for af */
+int af_register_setup(struct device *, struct af_device *);
+void af_set_address(struct device *, unsigned long);
+void af_engine_setup(struct device *, int);
+u32 af_get_hw_state(void);
+u32 af_get_enable(void);
+
+/* Function Declaration for aew */
+int aew_register_setup(struct device *, struct aew_device *);
+void aew_set_address(struct device *, unsigned long);
+void aew_engine_setup(struct device *, int);
+u32 aew_get_hw_state(void);
+u32 aew_get_enable(void);
+
+#endif				/*end of #ifdef __DAVINCI_A3_HW_H */
diff --git a/drivers/media/video/davinci/dm365_aew.c b/drivers/media/video/davinci/dm365_aew.c
new file mode 100644
index 0000000..8c193c8
--- /dev/null
+++ b/drivers/media/video/davinci/dm365_aew.c
@@ -0,0 +1,544 @@
+/*
+* Copyright (C) 2011 Texas Instruments Inc
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as
+* published by the Free Software Foundation version 2.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+*/
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+#include <media/v4l2-device.h>
+#include "dm365_a3_hw.h"
+#include "vpss.h"
+#include "vpfe_aew.h"
+
+#define DRIVERNAME  "DM365AEW"
+
+/* Global structure */
+static struct aew_device *aew_dev_configptr;
+static struct device *aewdev;
+
+int aew_validate_parameters(void)
+{
+
+	/* Check horizontal Count */
+	if (aew_dev_configptr->config->window_config.hz_cnt <
+		AEW_WINDOW_HORIZONTAL_COUNT_MIN ||
+		aew_dev_configptr->config->window_config.hz_cnt >
+			AEW_WINDOW_HORIZONTAL_COUNT_MAX) {
+		dev_err(aewdev, "Horizontal Count is incorrect\n");
+		return -EINVAL;
+	}
+	/* Check Vertical Count */
+	if (aew_dev_configptr->config->window_config.vt_cnt <
+		AEW_WINDOW_VERTICAL_COUNT_MIN ||
+		aew_dev_configptr->config->window_config.vt_cnt >
+		AEW_WINDOW_VERTICAL_COUNT_MAX) {
+		dev_err(aewdev, "Vertical Count is incorrect\n");
+		return -EINVAL;
+	}
+	/* Check line increment */
+	if (NOT_EVEN == CHECK_EVEN(aew_dev_configptr->config->window_config.
+		hz_line_incr) || aew_dev_configptr->config->window_config.
+		hz_line_incr < AEW_HZ_LINEINCR_MIN ||
+		aew_dev_configptr->config->window_config.hz_line_incr >
+		AEW_HZ_LINEINCR_MAX) {
+		dev_err(aewdev, "Invalid Parameters\n");
+		dev_err(aewdev, "Horizontal Line Increment is incorrect\n");
+		return -EINVAL;
+	}
+	/* Check line increment */
+	if (NOT_EVEN == CHECK_EVEN(aew_dev_configptr->config->window_config.
+		vt_line_incr) || aew_dev_configptr->config->window_config.
+		vt_line_incr < AEW_VT_LINEINCR_MIN ||
+		aew_dev_configptr->config->window_config.vt_line_incr >
+		AEW_VT_LINEINCR_MAX) {
+		dev_err(aewdev, "Invalid Parameters\n");
+		dev_err(aewdev, "Vertical Line Increment is incorrect\n");
+		return -EINVAL;
+	}
+	/* Check width */
+	if (NOT_EVEN == CHECK_EVEN(aew_dev_configptr->config->window_config.
+		width) || aew_dev_configptr->config->window_config.width <
+		AEW_WIDTH_MIN ||
+		aew_dev_configptr->config->window_config.width >
+			AEW_WIDTH_MAX) {
+		dev_err(aewdev, "Width is incorrect\n");
+		return -EINVAL;
+	}
+	/* Check Height */
+	if (NOT_EVEN == CHECK_EVEN(aew_dev_configptr->config->window_config.
+		height) || aew_dev_configptr->config->window_config.height <
+		AEW_HEIGHT_MIN ||
+		aew_dev_configptr->config->window_config.height >
+			AEW_HEIGHT_MAX) {
+		dev_err(aewdev, "height incorrect\n");
+		return -EINVAL;
+	}
+	/* Check Horizontal Start */
+	if (aew_dev_configptr->config->window_config.hz_start <
+		AEW_HZSTART_MIN ||
+		aew_dev_configptr->config->window_config.hz_start >
+			AEW_HZSTART_MAX) {
+		dev_err(aewdev, "horizontal start is  incorrect\n");
+		return -EINVAL;
+	}
+	if (aew_dev_configptr->config->window_config.vt_start >
+			AEW_VTSTART_MAX) {
+		dev_err(aewdev, "Vertical start is  incorrect\n");
+		return -EINVAL;
+	}
+	if (aew_dev_configptr->config->alaw_enable > H3A_AEW_ENABLE ||
+		aew_dev_configptr->config->alaw_enable < H3A_AEW_DISABLE) {
+		dev_err(aewdev, "A Law setting is incorrect\n");
+		return -EINVAL;
+	}
+	if (aew_dev_configptr->config->saturation_limit > AEW_AVELMT_MAX) {
+		dev_err(aewdev, "Saturation Limit is incorrect\n");
+		return -EINVAL;
+	}
+	/* Check Black Window Height */
+	if (NOT_EVEN == CHECK_EVEN(aew_dev_configptr->config->
+		blackwindow_config.height) ||
+		aew_dev_configptr->config->blackwindow_config.height <
+		AEW_BLKWINHEIGHT_MIN ||
+		aew_dev_configptr->config->blackwindow_config.height >
+			AEW_BLKWINHEIGHT_MAX) {
+		dev_err(aewdev, "Black Window height incorrect\n");
+		return -EINVAL;
+	}
+	/* Check Black Window Height */
+	if (NOT_EVEN == CHECK_EVEN(aew_dev_configptr->config->
+		blackwindow_config.height) ||
+		aew_dev_configptr->config->blackwindow_config.vt_start <
+		AEW_BLKWINVTSTART_MIN ||
+		aew_dev_configptr->config->blackwindow_config.vt_start >
+			AEW_BLKWINVTSTART_MAX) {
+		dev_err(aewdev, "Black Window vertical Start is incorrect\n");
+		return -EINVAL;
+	}
+
+	if (aew_dev_configptr->config->out_format < AEW_OUT_SUM_OF_SQUARES ||
+	    aew_dev_configptr->config->out_format > AEW_OUT_SUM_ONLY) {
+		dev_err(aewdev, "Invalid out_format\n");
+		return -EINVAL;
+	}
+
+	if (aew_dev_configptr->config->sum_shift > AEW_SUMSHIFT_MAX) {
+		dev_err(aewdev, "sum_shift param is invalid, max = %d\n",
+			AEW_SUMSHIFT_MAX);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* inline function to free reserver pages  */
+inline void aew_free_pages(unsigned long addr, unsigned long bufsize)
+{
+	unsigned long tempaddr;
+	unsigned long size;
+
+	tempaddr = addr;
+	if (!addr)
+		return;
+
+	size = PAGE_SIZE << (get_order(bufsize));
+	while (size > 0) {
+		ClearPageReserved(virt_to_page(addr));
+		addr += PAGE_SIZE;
+		size -= PAGE_SIZE;
+	}
+	free_pages(tempaddr, get_order(bufsize));
+}
+
+/* Function to perform hardware Configuration */
+int aew_hardware_setup(void)
+{
+	unsigned int busyaew;
+	unsigned long size;
+	unsigned long adr;
+	/* Size for buffer in bytes */
+	int buff_size;
+	int result;
+
+	/* Get the value of PCR register */
+	busyaew = aew_get_hw_state();
+
+	/* If H3A Engine is busy then return */
+	if (busyaew == 1) {
+		dev_err(aewdev, "Error : AEW Engine is busy\n");
+		return -EBUSY;
+	}
+
+	result = aew_validate_parameters();
+	dev_dbg(aewdev, "Result =  %d\n", result);
+	if (result < 0) {
+		dev_err(aewdev, "Error : Parameters are incorrect\n");
+		return result;
+	}
+
+	/* Deallocate the previously allocated buffers */
+	if (aew_dev_configptr->buff_old)
+		aew_free_pages((unsigned long)aew_dev_configptr->buff_old,
+			       aew_dev_configptr->size_window);
+
+	if (aew_dev_configptr->buff_curr)
+		aew_free_pages((unsigned long)aew_dev_configptr->
+			       buff_curr, aew_dev_configptr->size_window);
+
+	if (aew_dev_configptr->buff_app)
+		aew_free_pages((unsigned long)aew_dev_configptr->
+			       buff_app, aew_dev_configptr->size_window);
+
+	/*
+	 * Allocat the buffers as per the new buffer size
+	 * Allocate memory for old buffer
+	 */
+	if (aew_dev_configptr->config->out_format == AEW_OUT_SUM_ONLY)
+		buff_size = (aew_dev_configptr->config->window_config.hz_cnt) *
+			    (aew_dev_configptr->config->window_config.vt_cnt) *
+				AEW_WINDOW_SIZE_SUM_ONLY;
+	else
+		buff_size = (aew_dev_configptr->config->window_config.hz_cnt) *
+			    (aew_dev_configptr->config->window_config.vt_cnt) *
+				AEW_WINDOW_SIZE;
+
+	aew_dev_configptr->buff_old = (void *)__get_free_pages(GFP_KERNEL |
+				GFP_DMA, get_order(buff_size));
+
+	if (aew_dev_configptr->buff_old == NULL)
+		return -ENOMEM;
+
+	/* Make pges reserved so that they will be swapped out */
+	adr = (unsigned long)aew_dev_configptr->buff_old;
+	size = PAGE_SIZE << (get_order(buff_size));
+	while (size > 0) {
+		/*
+		 * make sure the frame buffers
+		 * are never swapped out of memory
+		 */
+		SetPageReserved(virt_to_page(adr));
+		adr += PAGE_SIZE;
+		size -= PAGE_SIZE;
+	}
+
+	/* Allocate memory for current buffer */
+	aew_dev_configptr->buff_curr = (void *)__get_free_pages(GFP_KERNEL |
+					GFP_DMA, get_order(buff_size));
+
+	if (aew_dev_configptr->buff_curr == NULL) {
+		/*Free all  buffer that are allocated */
+		if (aew_dev_configptr->buff_old)
+			aew_free_pages((unsigned long)aew_dev_configptr->
+				       buff_old, buff_size);
+		return -ENOMEM;
+	}
+
+	/* Make pges reserved so that they will be swapped out */
+	adr = (unsigned long)aew_dev_configptr->buff_curr;
+	size = PAGE_SIZE << (get_order(buff_size));
+	while (size > 0) {
+		/*
+		 * make sure the frame buffers
+		 * are never swapped out of memory
+		 */
+		SetPageReserved(virt_to_page(adr));
+		adr += PAGE_SIZE;
+		size -= PAGE_SIZE;
+	}
+
+	/* Allocate memory for application buffer */
+	aew_dev_configptr->buff_app = (void *)__get_free_pages(GFP_KERNEL |
+					GFP_DMA, get_order(buff_size));
+
+	if (aew_dev_configptr->buff_app == NULL) {
+		/* Free all  buffer that were allocated previously */
+		if (aew_dev_configptr->buff_old)
+			aew_free_pages((unsigned long)aew_dev_configptr->
+				       buff_old, buff_size);
+		if (aew_dev_configptr->buff_curr)
+			aew_free_pages((unsigned long)aew_dev_configptr->
+				       buff_curr, buff_size);
+		return -ENOMEM;
+	}
+
+	/* Make pages reserved so that they will be swapped out */
+	adr = (unsigned long)aew_dev_configptr->buff_app;
+	size = PAGE_SIZE << (get_order(buff_size));
+	while (size > 0) {
+		/*
+		 * make sure the frame buffers
+		 * are never swapped out of memory
+		 */
+		SetPageReserved(virt_to_page(adr));
+		adr += PAGE_SIZE;
+		size -= PAGE_SIZE;
+	}
+
+	/* Set the registers */
+	aew_register_setup(aewdev, aew_dev_configptr);
+	aew_dev_configptr->size_window = buff_size;
+	aew_dev_configptr->aew_config = H3A_AEW_CONFIG;
+
+	return 0;
+}
+
+int aew_open(void)
+{
+	/* Return if Device is in use (Single Channel Support is provided) */
+	if (aew_dev_configptr->in_use == AEW_IN_USE)
+		return -EBUSY;
+
+	/* Set the aew_dev_configptr structure */
+	aew_dev_configptr->config = NULL;
+
+	/* Allocate memory for configuration  structure of this channel */
+	aew_dev_configptr->config = (struct aew_configuration *)
+	kmalloc(sizeof(struct aew_configuration), GFP_KERNEL);
+
+	if (aew_dev_configptr->config == NULL) {
+		dev_err(aewdev, "Error : Kmalloc fail\n");
+		return -ENOMEM;
+	}
+
+	/* Device is in use */
+	aew_dev_configptr->in_use = AEW_IN_USE;
+	/* No Hardware Set up done */
+	aew_dev_configptr->aew_config = H3A_AEW_CONFIG_NOT_DONE;
+	/* No statistics are available */
+	aew_dev_configptr->buffer_filled = 0;
+	/* Set Window Size to 0 */
+	aew_dev_configptr->size_window = 0;
+
+	return 0;
+}
+
+int aew_release(void)
+{
+	aew_engine_setup(aewdev, 0);
+	/* The Application has closed device so device is not in use */
+	aew_dev_configptr->in_use = AEW_NOT_IN_USE;
+
+	/* Release memory for configuration structure of this channel */
+	kfree(aew_dev_configptr->config);
+
+	/* Free Old Buffer */
+	if (aew_dev_configptr->buff_old)
+		aew_free_pages((unsigned long)aew_dev_configptr->buff_old,
+			       aew_dev_configptr->size_window);
+
+	/* Free Current Buffer */
+	if (aew_dev_configptr->buff_curr)
+		aew_free_pages((unsigned long)aew_dev_configptr->
+			       buff_curr, aew_dev_configptr->size_window);
+
+	/* Free Application Buffer */
+	if (aew_dev_configptr->buff_app)
+		aew_free_pages((unsigned long)aew_dev_configptr->buff_app,
+			       aew_dev_configptr->size_window);
+
+	aew_dev_configptr->buff_old = NULL;
+	aew_dev_configptr->buff_curr = NULL;
+	aew_dev_configptr->config = NULL;
+	aew_dev_configptr->buff_app = NULL;
+
+	return 0;
+}
+
+/*
+ * This function will process IOCTL commands sent by the application and
+ * control the devices IO operations.
+ */
+int aew_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+	/* Stores Previous Configurations */
+	struct aew_configuration aewconfig = *(aew_dev_configptr->config);
+	struct aew_statdata *stat_data = (struct aew_statdata *)arg;
+	void *buffer_temp;
+	int result;
+
+	/* Switch according to IOCTL command */
+	switch (cmd) {
+		/*
+		 * This ioctl is used to perform hardware set up
+		 * and will set all the registers for AF engine
+		 */
+	case AEW_S_PARAM:
+		/* Copy config structure passed by user */
+		memcpy(aew_dev_configptr->config,
+				   (struct aew_configuration *)arg,
+				   sizeof(struct aew_configuration));
+
+		/* Call aew_hardware_setup to perform register configuration */
+		result = aew_hardware_setup();
+		if (!result) {
+			/*
+			 * Hardware Set up is successful
+			 * Return the no of bytes required for buffer
+			 */
+			result = aew_dev_configptr->size_window;
+		} else {
+			/* Change Configuration Structure to original */
+			*(aew_dev_configptr->config) = aewconfig;
+			dev_err(aewdev, "Error : AEW_S_PARAM  failed\n");
+		}
+		break;
+
+		/* This ioctl is used to return parameters in user space */
+	case AEW_G_PARAM:
+		if (aew_dev_configptr->aew_config == H3A_AEW_CONFIG) {
+			memcpy((struct aew_configuration *)arg,
+			     aew_dev_configptr->config,
+			     sizeof(struct aew_configuration));
+			result = aew_dev_configptr->size_window;
+		} else {
+			dev_err(aewdev,
+				"Error : AEW Hardware is not configured.\n");
+			result = -EINVAL;
+		}
+		break;
+	case AEW_GET_STAT:
+		/* Implement the read  functionality */
+		if (aew_dev_configptr->buffer_filled != 1)
+			return -EINVAL;
+
+		if (stat_data->buf_length < aew_dev_configptr->size_window)
+			return -EINVAL;
+
+		/* Disable the interrupts and then swap the buffers */
+		disable_irq(6);
+
+		/* New Statistics are availaible */
+		aew_dev_configptr->buffer_filled = 0;
+
+		/* Swap application buffer and old buffer */
+		buffer_temp = aew_dev_configptr->buff_old;
+		aew_dev_configptr->buff_old = aew_dev_configptr->buff_app;
+		aew_dev_configptr->buff_app = buffer_temp;
+
+		/* Interrupts are enabled */
+		enable_irq(6);
+
+		/*
+		* Copy the entire statistics located in application
+		* buffer to user space
+		*/
+		memcpy(stat_data->buffer, aew_dev_configptr->buff_app,
+				aew_dev_configptr->size_window);
+
+		result = aew_dev_configptr->size_window;
+		break;
+	default:
+		dev_err(aewdev, "Error: It should not come here!!\n");
+		result = -ENOTTY;
+		break;
+	}
+	return result;
+}
+
+/* This function will handle interrupt generated by H3A Engine. */
+static irqreturn_t aew_isr(int irq, void *dev_id)
+{
+	struct v4l2_subdev *sd = dev_id;
+	/* EN AF Bit */
+	unsigned int enaew;
+	/* Temporary Buffer for Swapping */
+	void *buffer_temp;
+
+	/* Get the value of PCR register */
+	enaew = aew_get_enable();
+
+	/* If AEW engine is not enabled, interrupt is not for AEW */
+	if (!enaew || !aew_dev_configptr)
+		return IRQ_RETVAL(IRQ_NONE);
+
+	/*
+	 * Interrupt is generated by AEW, so Service the Interrupt
+	 * Swap current buffer and old buffer
+	 */
+	buffer_temp = aew_dev_configptr->buff_curr;
+	aew_dev_configptr->buff_curr = aew_dev_configptr->buff_old;
+	aew_dev_configptr->buff_old = buffer_temp;
+
+	/* Set the AEWBUFSTAT REgister to current buffer Address */
+	aew_set_address(aewdev,
+		(unsigned long)(virt_to_phys(aew_dev_configptr->buff_curr)));
+	/*
+	  * Set buffer filled flag to indicate statistics are available
+	  */
+	aew_dev_configptr->buffer_filled = 1;
+	/* queue the event with v4l2 */
+	aew_queue_event(sd);
+
+	return IRQ_RETVAL(IRQ_HANDLED);
+}
+
+int aew_set_stream(struct v4l2_subdev *sd, int enable)
+{
+	int result;
+
+	if (!enable) {
+		/* stop capture */
+		free_irq(6, sd);
+		/* Disable AEW Engine */
+		aew_engine_setup(aewdev, 0);
+		return 0;
+	}
+	/* start capture */
+	/* Enable AEW Engine if Hardware set up is done */
+	if (aew_dev_configptr->aew_config == H3A_AEW_CONFIG_NOT_DONE) {
+		dev_err(aewdev, "Error : AEW Hardware is not configured.\n");
+		return -EINVAL;
+	}
+	result = request_irq(6, aew_isr, IRQF_SHARED, "dm365_h3a_aew",
+			(void *)sd);
+	if (result != 0)
+		return result;
+	/* Enable AF Engine */
+	aew_engine_setup(aewdev, 1);
+
+	return 0;
+}
+
+int aew_init(struct platform_device *pdev)
+{
+	aew_dev_configptr =  kmalloc(sizeof(struct aew_device), GFP_KERNEL);
+	if (!aew_dev_configptr) {
+		printk(KERN_ERR "aew_init: Error : kmalloc fail\n");
+		return -ENOMEM;
+	}
+	/* Initialize device structure */
+	memset(aew_dev_configptr, 0, sizeof(struct aew_device));
+	aew_dev_configptr->in_use = AEW_NOT_IN_USE;
+	aew_dev_configptr->buffer_filled = 0;
+	aewdev = &pdev->dev;
+
+	return 0;
+}
+
+void aew_cleanup(void)
+{
+	/* in use */
+	if (aew_dev_configptr->in_use == AEW_IN_USE) {
+		printk(KERN_ERR "aew_cleanup: Error : dm365_aew in use");
+		return;
+	}
+	/* Free device structure */
+	kfree(aew_dev_configptr);
+	aew_dev_configptr = NULL;
+}
diff --git a/drivers/media/video/davinci/dm365_aew.h b/drivers/media/video/davinci/dm365_aew.h
new file mode 100644
index 0000000..47bfda5
--- /dev/null
+++ b/drivers/media/video/davinci/dm365_aew.h
@@ -0,0 +1,55 @@
+/*
+* Copyright (C) 2011 Texas Instruments Inc
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as
+* published by the Free Software Foundation version 2.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+*/
+#ifndef DM365_AEW_DRIVER_H
+#define DM365_AEW_DRIVER_H
+
+#include <linux/ioctl.h>
+#include <linux/wait.h>
+#include <linux/mutex.h>
+#include <linux/io.h>
+#include <linux/dm365_aew.h>
+
+/* Contains information about device structure of AEW*/
+struct aew_device {
+	/* Driver usage flag */
+	enum aew_in_use_flag in_use;
+	/* Device configuration */
+	struct aew_configuration *config;
+	/* Contains latest statistics */
+	void *buff_old;
+	/* Buffer in which HW will fill the statistics or HW is already
+	 * filling
+	 */
+	void *buff_curr;
+	/* statistics Buffer which will be passed */
+	void *buff_app;
+	/* to user on read call. Flag indicates statistics are available */
+	int buffer_filled;
+	/* Window size in bytes */
+	unsigned int size_window;
+	/* Wait queue for the driver */
+	wait_queue_head_t aew_wait_queue;
+	/* Mutex for driver */
+	struct mutex read_blocked;
+	/* Flag indicates Engine is configured */
+	enum aew_config_flag aew_config;
+};
+
+int aew_validate_parameters(void);
+int aew_hardware_setup(void);
+
+#endif				/*End of DM365_AEW_H */
diff --git a/include/linux/dm365_aew.h b/include/linux/dm365_aew.h
new file mode 100644
index 0000000..3882d79
--- /dev/null
+++ b/include/linux/dm365_aew.h
@@ -0,0 +1,153 @@
+/*
+* Copyright (C) 2011 Texas Instruments Inc
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License as
+* published by the Free Software Foundation version 2.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+*/
+
+#ifndef _DM365_AEW_INCLUDE_H
+#define _DM365_AEW_INCLUDE_H
+
+/* Driver Range Constants */
+#define AEW_WINDOW_VERTICAL_COUNT_MIN		1
+#define AEW_WINDOW_VERTICAL_COUNT_MAX		128
+#define AEW_WINDOW_HORIZONTAL_COUNT_MIN		2
+#define AEW_WINDOW_HORIZONTAL_COUNT_MAX		36
+
+#define AEW_WIDTH_MIN		8
+#define AEW_WIDTH_MAX		256
+
+#define AEW_AVELMT_MAX		1023
+
+#define AEW_HZ_LINEINCR_MIN	2
+#define AEW_HZ_LINEINCR_MAX	32
+
+#define AEW_VT_LINEINCR_MIN	2
+#define AEW_VT_LINEINCR_MAX	32
+
+#define AEW_HEIGHT_MIN		2
+#define AEW_HEIGHT_MAX		256
+
+#define AEW_HZSTART_MIN		0
+#define AEW_HZSTART_MAX		4095
+
+#define AEW_VTSTART_MIN		0
+#define AEW_VTSTART_MAX		4095
+
+#define AEW_BLKWINHEIGHT_MIN	2
+#define AEW_BLKWINHEIGHT_MAX	256
+#define AEW_BLKWINVTSTART_MIN	0
+#define AEW_BLKWINVTSTART_MAX	4095
+
+#define AEW_SUMSHIFT_MAX	15
+
+/* Statistics data size per window */
+#define AEW_WINDOW_SIZE			32
+#define AEW_WINDOW_SIZE_SUM_ONLY	16
+
+/* List of ioctls */
+#define AEW_MAGIC_NO	'e'
+#define AEW_S_PARAM	_IOWR(AEW_MAGIC_NO, 1, struct aew_configuration)
+#define AEW_G_PARAM	_IOWR(AEW_MAGIC_NO, 2, struct aew_configuration)
+#define AEW_GET_STAT	_IOWR(AEW_MAGIC_NO, 5, struct aew_statdata)
+
+/* Enum for device usage */
+enum aew_in_use_flag {
+	/* Device is not in use */
+	AEW_NOT_IN_USE,
+	/* Device in use */
+	AEW_IN_USE
+};
+
+/* Enum for Enable/Disable specific feature */
+enum aew_enable_flag {
+	H3A_AEW_DISABLE,
+	H3A_AEW_ENABLE
+};
+
+enum aew_config_flag {
+	H3A_AEW_CONFIG_NOT_DONE,
+	H3A_AEW_CONFIG
+};
+
+
+/* Contains the information regarding Window Structure in AEW Engine */
+struct aew_window {
+	/* Width of the window */
+	unsigned int width;
+	/* Height of the window */
+	unsigned int height;
+	/* Horizontal Start of the window */
+	unsigned int hz_start;
+	/* Vertical Start of the window */
+	unsigned int vt_start;
+	/* Horizontal Count */
+	unsigned int hz_cnt;
+	/* Vertical Count */
+	unsigned int vt_cnt;
+	/* Horizontal Line Increment */
+	unsigned int hz_line_incr;
+	/* Vertical Line Increment */
+	unsigned int vt_line_incr;
+};
+
+/* Contains the information regarding the AEW Black Window Structure */
+struct aew_black_window {
+	/* Height of the Black Window */
+	unsigned int height;
+	/* Vertical Start of the black Window */
+	unsigned int vt_start;
+};
+
+/* Contains the information regarding the Horizontal Median Filter */
+struct aew_hmf {
+	/* Status of Horizontal Median Filter */
+	enum aew_enable_flag enable;
+	/* Threshhold Value for Horizontal Median Filter. Make sure
+	 * to keep this same as AF threshold since we have a common
+	 * threshold for both
+	 */
+	unsigned int threshold;
+};
+
+/* AE/AWB output format */
+enum aew_output_format {
+	AEW_OUT_SUM_OF_SQUARES,
+	AEW_OUT_MIN_MAX,
+	AEW_OUT_SUM_ONLY
+};
+
+/* Contains configuration required for setup of AEW engine */
+struct aew_configuration {
+	/* A-law status */
+	enum aew_enable_flag alaw_enable;
+	/* AE/AWB output format */
+	enum aew_output_format out_format;
+	/* AW/AWB right shift value for sum of pixels */
+	char sum_shift;
+	/* Saturation Limit */
+	int saturation_limit;
+	/* HMF configurations */
+	struct aew_hmf hmf_config;
+	/* Window for AEW Engine */
+	struct aew_window window_config;
+	/* Black Window */
+	struct aew_black_window blackwindow_config;
+};
+
+struct aew_statdata {
+	void *buffer;
+	int buf_length;
+};
+
+#endif
-- 
1.6.2.4

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux