]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
media: video: tegra: Add SOC1040 (mt9m114) driver
authorFrank Chen <frankc@nvidia.com>
Tue, 10 Sep 2013 00:21:17 +0000 (17:21 -0700)
committerDan Willemsen <dwillemsen@nvidia.com>
Fri, 27 Sep 2013 02:46:13 +0000 (19:46 -0700)
Add SOC1040 (mt9m114) YUV sensor driver

Bug 1327952

Change-Id: I91fc5ac9cbb7b537bdb6f31684d99725689a61a3
Signed-off-by: Frank Chen <frankc@nvidia.com>
Reviewed-on: http://git-master/r/274669
Reviewed-by: Charlie Huang <chahuang@nvidia.com>
Reviewed-by: Jean Huang <jeanh@nvidia.com>
Reviewed-by: Hu He <hhe@nvidia.com>
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
drivers/media/platform/tegra/Kconfig
drivers/media/platform/tegra/Makefile
drivers/media/platform/tegra/mt9m114.c [new file with mode: 0644]
include/media/mt9m114.h [new file with mode: 0644]

index da4668c32143259ae0fb6c419f6ff19e64fb2cc1..14a4e2aa15b7c1f2b7f365150211dd61ec8ff69f 100644 (file)
@@ -198,6 +198,13 @@ config VIDEO_AR0833
           This is a driver for the AR0833 camera sensor
           for use with the tegra isp.
 
+config VIDEO_MT9M114
+        tristate "SOC1040 camera sensor support"
+        depends on I2C && ARCH_TEGRA
+        ---help---
+          This is a driver for the SOC1040 camera sensor
+          for use with the tegra isp.
+
 config VIDEO_CAMERA
         tristate "generic camera device support"
         depends on I2C && ARCH_TEGRA
index 9d79e24946dcb5d8f1a6543736d588de1c9d6aee..1197d020d36f63fc06439016f304dac28f8b5cba 100644 (file)
@@ -37,4 +37,5 @@ obj-$(CONFIG_DEBUG_FS)                += nvc_debugfs.o
 obj-$(CONFIG_VIDEO_OV5693)     += ov5693.o
 obj-$(CONFIG_VIDEO_AD5823)     += ad5823.o
 obj-$(CONFIG_VIDEO_OV7695)     += ov7695.o
+obj-$(CONFIG_VIDEO_MT9M114)    += mt9m114.o
 obj-$(CONFIG_VIDEO_CAMERA)     += camera.o
diff --git a/drivers/media/platform/tegra/mt9m114.c b/drivers/media/platform/tegra/mt9m114.c
new file mode 100644 (file)
index 0000000..4384137
--- /dev/null
@@ -0,0 +1,807 @@
+/*
+ * Copyright (c) 2013, NVIDIA CORPORATION.  All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/i2c.h>
+#include <linux/miscdevice.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/gpio.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/atomic.h>
+#include <linux/regulator/consumer.h>
+#include <linux/export.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+
+#include <media/mt9m114.h>
+
+#define SIZEOF_I2C_TRANSBUF 128
+
+struct mt9m114_reg {
+       u16 cmd; /* command */
+       u16 addr;
+       u16 val;
+};
+
+static struct mt9m114_reg mode_1280x960_30fps[] = {
+       {MT9M114_SENSOR_WORD_WRITE, 0x001A, 0x0001},
+       {MT9M114_SENSOR_WAIT_MS, 0, 10},
+       {MT9M114_SENSOR_WORD_WRITE, 0x001A, 0x0000},
+       {MT9M114_SENSOR_WAIT_MS, 0, 50},
+       {MT9M114_SENSOR_WORD_WRITE, 0x301A, 0x0234},
+
+       {MT9M114_SENSOR_WORD_WRITE, 0x098E, 0x1000},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC97E, 0x01},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC980, 0x0120},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC982, 0x0700},
+
+       {MT9M114_SENSOR_WORD_WRITE, 0xC800, 0x0004},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC802, 0x0004},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC804, 0x03CB},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC806, 0x050B},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC808, 0x02DC},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC80A, 0x6C00},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC80C, 0x0001},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC80E, 0x00DB},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC810, 0x05B3},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC812, 0x03EE},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC814, 0x0636},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC816, 0x0060},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC818, 0x03C3},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC834, 0x0000},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC854, 0x0000},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC856, 0x0000},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC858, 0x0500},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC85A, 0x03C0},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC85C, 0x03},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC868, 0x0500},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC86A, 0x03C0},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC88C, 0x1E02},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC88E, 0x0780},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC914, 0x0000},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC916, 0x0000},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC918, 0x04FF},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC91A, 0x03BF},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC91C, 0x0000},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC91E, 0x0000},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC920, 0x00FF},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC922, 0x00BF},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xE801, 0x00},
+
+       {MT9M114_SENSOR_WORD_WRITE, 0x316A, 0x8270},
+       {MT9M114_SENSOR_WORD_WRITE, 0x316C, 0x8270},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3ED0, 0x2305},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3ED2, 0x77CF},
+       {MT9M114_SENSOR_WORD_WRITE, 0x316E, 0x8202},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3180, 0x87FF},
+       {MT9M114_SENSOR_WORD_WRITE, 0x30D4, 0x6080},
+       {MT9M114_SENSOR_WORD_WRITE, 0xA802, 0x0008},
+
+       {MT9M114_SENSOR_WORD_WRITE, 0x3E14, 0xFF39},
+       {MT9M114_SENSOR_WORD_WRITE, 0x301A, 0x8234},
+
+       {MT9M114_SENSOR_WORD_WRITE, 0x098E, 0x495E},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC95E, 0x0000},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3640, 0x02B0},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3642, 0x8063},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3644, 0x78D0},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3646, 0x50CC},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3648, 0x3511},
+       {MT9M114_SENSOR_WORD_WRITE, 0x364A, 0x0110},
+       {MT9M114_SENSOR_WORD_WRITE, 0x364C, 0xBD8A},
+       {MT9M114_SENSOR_WORD_WRITE, 0x364E, 0x0CD1},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3650, 0x24ED},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3652, 0x7C11},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3654, 0x0150},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3656, 0x124C},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3658, 0x3130},
+       {MT9M114_SENSOR_WORD_WRITE, 0x365A, 0x508C},
+       {MT9M114_SENSOR_WORD_WRITE, 0x365C, 0x21F1},
+       {MT9M114_SENSOR_WORD_WRITE, 0x365E, 0x0090},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3660, 0xBFCA},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3662, 0x0A11},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3664, 0x4F4B},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3666, 0x28B1},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3680, 0x50A9},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3682, 0xA04B},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3684, 0x0E2D},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3686, 0x73EC},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3688, 0x164F},
+       {MT9M114_SENSOR_WORD_WRITE, 0x368A, 0xF829},
+       {MT9M114_SENSOR_WORD_WRITE, 0x368C, 0xC1A8},
+       {MT9M114_SENSOR_WORD_WRITE, 0x368E, 0xB0EC},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3690, 0xE76A},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3692, 0x69AF},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3694, 0x378C},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3696, 0xA70D},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3698, 0x884F},
+       {MT9M114_SENSOR_WORD_WRITE, 0x369A, 0xEE8B},
+       {MT9M114_SENSOR_WORD_WRITE, 0x369C, 0x5DEF},
+       {MT9M114_SENSOR_WORD_WRITE, 0x369E, 0x27CC},
+       {MT9M114_SENSOR_WORD_WRITE, 0x36A0, 0xCAAC},
+       {MT9M114_SENSOR_WORD_WRITE, 0x36A2, 0x840E},
+       {MT9M114_SENSOR_WORD_WRITE, 0x36A4, 0xDAA9},
+       {MT9M114_SENSOR_WORD_WRITE, 0x36A6, 0xF00C},
+       {MT9M114_SENSOR_WORD_WRITE, 0x36C0, 0x1371},
+       {MT9M114_SENSOR_WORD_WRITE, 0x36C2, 0x272F},
+       {MT9M114_SENSOR_WORD_WRITE, 0x36C4, 0x2293},
+       {MT9M114_SENSOR_WORD_WRITE, 0x36C6, 0xE6D0},
+       {MT9M114_SENSOR_WORD_WRITE, 0x36C8, 0xEC32},
+       {MT9M114_SENSOR_WORD_WRITE, 0x36CA, 0x11B1},
+       {MT9M114_SENSOR_WORD_WRITE, 0x36CC, 0x7BAF},
+       {MT9M114_SENSOR_WORD_WRITE, 0x36CE, 0x5813},
+       {MT9M114_SENSOR_WORD_WRITE, 0x36D0, 0xB871},
+       {MT9M114_SENSOR_WORD_WRITE, 0x36D2, 0x8913},
+       {MT9M114_SENSOR_WORD_WRITE, 0x36D4, 0x4610},
+       {MT9M114_SENSOR_WORD_WRITE, 0x36D6, 0x7EEE},
+       {MT9M114_SENSOR_WORD_WRITE, 0x36D8, 0x0DF3},
+       {MT9M114_SENSOR_WORD_WRITE, 0x36DA, 0xB84F},
+       {MT9M114_SENSOR_WORD_WRITE, 0x36DC, 0xB532},
+       {MT9M114_SENSOR_WORD_WRITE, 0x36DE, 0x1171},
+       {MT9M114_SENSOR_WORD_WRITE, 0x36E0, 0x13CF},
+       {MT9M114_SENSOR_WORD_WRITE, 0x36E2, 0x22F3},
+       {MT9M114_SENSOR_WORD_WRITE, 0x36E4, 0xE090},
+       {MT9M114_SENSOR_WORD_WRITE, 0x36E6, 0x8133},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3700, 0x88AE},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3702, 0x00EA},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3704, 0x344F},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3706, 0xEC88},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3708, 0x3E91},
+       {MT9M114_SENSOR_WORD_WRITE, 0x370A, 0xF12D},
+       {MT9M114_SENSOR_WORD_WRITE, 0x370C, 0xB0EF},
+       {MT9M114_SENSOR_WORD_WRITE, 0x370E, 0x77CD},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3710, 0x7930},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3712, 0x5C12},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3714, 0x500C},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3716, 0x22CE},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3718, 0x2370},
+       {MT9M114_SENSOR_WORD_WRITE, 0x371A, 0x258F},
+       {MT9M114_SENSOR_WORD_WRITE, 0x371C, 0x3D30},
+       {MT9M114_SENSOR_WORD_WRITE, 0x371E, 0x370C},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3720, 0x03ED},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3722, 0x9AD0},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3724, 0x7ECF},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3726, 0x1093},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3740, 0x2391},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3742, 0xAAD0},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3744, 0x28F2},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3746, 0xBA4F},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3748, 0xC536},
+       {MT9M114_SENSOR_WORD_WRITE, 0x374A, 0x1472},
+       {MT9M114_SENSOR_WORD_WRITE, 0x374C, 0xD110},
+       {MT9M114_SENSOR_WORD_WRITE, 0x374E, 0x2933},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3750, 0xD0D1},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3752, 0x9F37},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3754, 0x34D1},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3756, 0x1C6C},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3758, 0x3FD2},
+       {MT9M114_SENSOR_WORD_WRITE, 0x375A, 0xCB72},
+       {MT9M114_SENSOR_WORD_WRITE, 0x375C, 0xBA96},
+       {MT9M114_SENSOR_WORD_WRITE, 0x375E, 0x1551},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3760, 0xB74F},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3762, 0x1672},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3764, 0x84F1},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3766, 0xC2D6},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3782, 0x01E0},
+       {MT9M114_SENSOR_WORD_WRITE, 0x3784, 0x0280},
+       {MT9M114_SENSOR_WORD_WRITE, 0x37C0, 0xA6EA},
+       {MT9M114_SENSOR_WORD_WRITE, 0x37C2, 0x874B},
+       {MT9M114_SENSOR_WORD_WRITE, 0x37C4, 0x85CB},
+       {MT9M114_SENSOR_WORD_WRITE, 0x37C6, 0x968A},
+       {MT9M114_SENSOR_WORD_WRITE, 0x098E, 0x0000},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC960, 0x0AF0},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC962, 0x79E2},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC964, 0x5EC8},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC966, 0x791F},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC968, 0x76EE},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC96A, 0x0FA0},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC96C, 0x7DFA},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC96E, 0x7DAF},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC970, 0x7E02},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC972, 0x7E0A},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC974, 0x1964},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC976, 0x7CDC},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC978, 0x7838},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC97A, 0x7C2F},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC97C, 0x7792},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC95E, 0x0003},
+
+       {MT9M114_SENSOR_WORD_WRITE, 0x098E, 0x0000},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC95E, 0x0003},
+
+       {MT9M114_SENSOR_WORD_WRITE, 0xC892, 0x0267},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC894, 0xFF1A},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC896, 0xFFB3},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC898, 0xFF80},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC89A, 0x0166},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC89C, 0x0003},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC89E, 0xFF9A},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8A0, 0xFEB4},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8A2, 0x024D},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8A4, 0x01BF},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8A6, 0xFF01},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8A8, 0xFFF3},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8AA, 0xFF75},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8AC, 0x0198},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8AE, 0xFFFD},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8B0, 0xFF9A},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8B2, 0xFEE7},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8B4, 0x02A8},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8B6, 0x01D9},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8B8, 0xFF26},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8BA, 0xFFF3},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8BC, 0xFFB3},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8BE, 0x0132},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8C0, 0xFFE8},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8C2, 0xFFDA},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8C4, 0xFECD},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8C6, 0x02C2},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8C8, 0x0075},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8CA, 0x011C},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8CC, 0x009A},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8CE, 0x0105},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8D0, 0x00A4},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8D2, 0x00AC},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8D4, 0x0A8C},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8D6, 0x0F0A},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8D8, 0x1964},
+
+       {MT9M114_SENSOR_WORD_WRITE, 0xC914, 0x0000},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC916, 0x0000},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC918, 0x04FF},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC91A, 0x03BF},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC904, 0x003B},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC906, 0x0041},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC8F2, 0x03},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC8F3, 0x02},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC906, 0x003C},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8F4, 0x0000},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8F6, 0x0000},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8F8, 0x0000},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8FA, 0xE724},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8FC, 0x1583},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC8FE, 0x2045},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC900, 0x05DC},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC902, 0x007C},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC90C, 0x80},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC90D, 0x80},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC90E, 0x80},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC90F, 0x88},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC910, 0x80},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC911, 0x80},
+
+       {MT9M114_SENSOR_WORD_WRITE, 0xC926, 0x0060},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC928, 0x009A},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC946, 0x0070},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC948, 0x00F3},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC952, 0x0060},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC954, 0x009A},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC92A, 0x80},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC92B, 0x4B},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC92C, 0x00},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC92D, 0xFF},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC92E, 0x3C},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC92F, 0x02},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC930, 0x06},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC931, 0x64},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC932, 0x01},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC933, 0x0C},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC934, 0x3C},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC935, 0x3C},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC936, 0x3C},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC937, 0x0F},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC938, 0x64},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC939, 0x64},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC93A, 0x64},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC93B, 0x32},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC93C, 0x0060},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC93E, 0x009A},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC940, 0x00DC},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC942, 0x38},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC943, 0x30},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC944, 0x50},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC945, 0x19},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC94A, 0x00F0},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC94C, 0x0010},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC94E, 0x01CD},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC950, 0x05},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC951, 0x40},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC87A, 0x42},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC87B, 0x21},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xC878, 0x0E},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC890, 0x0080},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC886, 0x0100},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC87C, 0x0010},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xB42A, 0x05},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xA80A, 0x20},
+       {MT9M114_SENSOR_WORD_WRITE, 0x098E, 0x0000},
+       {MT9M114_SENSOR_WORD_WRITE, 0xC984, 0x8041},
+       {MT9M114_SENSOR_WORD_WRITE, 0x001E, 0x0777},
+       {MT9M114_SENSOR_WORD_WRITE, 0x098E, 0xDC00},
+       {MT9M114_SENSOR_BYTE_WRITE, 0xDC00, 0x28},
+       {MT9M114_SENSOR_WAIT_MS, 0, 50},
+       {MT9M114_SENSOR_WORD_WRITE, 0x0080, 0x8002},
+       {MT9M114_SENSOR_TABLE_END, 0x0000}
+};
+
+struct mt9m114_info {
+       struct miscdevice               miscdev_info;
+       struct mt9m114_power_rail       power;
+       struct mt9m114_sensordata       sensor_data;
+       struct i2c_client               *i2c_client;
+       struct mt9m114_platform_data    *pdata;
+       atomic_t                        in_use;
+       const struct mt9m114_reg                *mode;
+       u8                              i2c_trans_buf[SIZEOF_I2C_TRANSBUF];
+       struct clk *mclk;
+};
+
+struct mt9m114_mode_desc {
+       u16                     xres;
+       u16                     yres;
+       const struct mt9m114_reg *mode_tbl;
+       struct mt9m114_modeinfo mode_info;
+};
+
+static struct mt9m114_mode_desc mode_table[] = {
+       {
+               .xres = 1280,
+               .yres = 960,
+               .mode_tbl = mode_1280x960_30fps,
+       },
+       { },
+};
+
+static long mt9m114_ioctl(struct file *file,
+                       unsigned int cmd, unsigned long arg);
+
+static inline void mt9m114_msleep(u32 t)
+{
+       usleep_range(t*1000, t*1000 + 500);
+}
+
+static int mt9m114_read_reg(struct i2c_client *client, u16 addr, u8 *val)
+{
+       int err;
+       struct i2c_msg msg[2];
+       unsigned char data[3];
+
+       if (!client->adapter)
+               return -ENODEV;
+
+       msg[0].addr = client->addr;
+       msg[0].flags = 0;
+       msg[0].len = 2;
+       msg[0].buf = data;
+
+       data[0] = (u8) (addr >> 8);
+       data[1] = (u8) (addr & 0xff);
+
+       msg[1].addr = client->addr;
+       msg[1].flags = I2C_M_RD;
+       msg[1].len = 1;
+       msg[1].buf = data + 2;
+
+       err = i2c_transfer(client->adapter, msg, 2);
+
+       if (err != 2)
+               return -EINVAL;
+
+       *val = data[2];
+
+       return 0;
+}
+
+static int mt9m114_write_bulk_reg(struct i2c_client *client, u8 *data, int len)
+{
+       int err;
+       struct i2c_msg msg;
+
+       if (!client->adapter)
+               return -ENODEV;
+
+       msg.addr = client->addr;
+       msg.flags = 0;
+       msg.len = len;
+       msg.buf = data;
+
+       dev_dbg(&client->dev,
+               "%s {0x%04x,", __func__, (int)data[0] << 8 | data[1]);
+       for (err = 2; err < len; err++)
+               dev_dbg(&client->dev, " 0x%02x", data[err]);
+       dev_dbg(&client->dev, "},\n");
+
+       err = i2c_transfer(client->adapter, &msg, 1);
+       if (err == 1)
+               return 0;
+
+       dev_err(&client->dev, "mt9m114: i2c bulk transfer failed at %x\n",
+               (int)data[0] << 8 | data[1]);
+
+       return err;
+}
+
+static int mt9m114_write_reg8(struct i2c_client *client, u16 addr, u8 val)
+{
+       unsigned char data[3];
+
+       if (!client->adapter)
+               return -ENODEV;
+
+       data[0] = (u8) (addr >> 8);
+       data[1] = (u8) (addr & 0xff);
+       data[2] = (u8) (val & 0xff);
+
+       dev_dbg(&client->dev, "0x%x = 0x%x\n", addr, val);
+       return mt9m114_write_bulk_reg(client, data, sizeof(data));
+}
+
+static int mt9m114_write_reg16(struct i2c_client *client, u16 addr, u16 val)
+{
+       unsigned char data[4];
+
+       if (!client->adapter)
+               return -ENODEV;
+
+       data[0] = (u8) (addr >> 8);
+       data[1] = (u8) (addr & 0xff);
+       data[2] = (u8) (val >> 8);
+       data[3] = (u8) (val & 0xff);
+
+       dev_dbg(&client->dev, "0x%x = 0x%x\n", addr, val);
+       return mt9m114_write_bulk_reg(client, data, sizeof(data));
+}
+
+static int mt9m114_write_table(
+       struct mt9m114_info *info,
+       const struct mt9m114_reg table[])
+{
+       int err;
+       const struct mt9m114_reg *next;
+       u16 val;
+
+       dev_dbg(&info->i2c_client->dev, "yuv %s\n", __func__);
+
+       for (next = table; next->cmd != MT9M114_SENSOR_TABLE_END; next++) {
+               if (next->cmd == MT9M114_SENSOR_WAIT_MS) {
+                       msleep(next->val);
+               continue;
+               }
+
+               val = next->val;
+
+               if (next->cmd == MT9M114_SENSOR_BYTE_WRITE)
+                       err = mt9m114_write_reg8(info->i2c_client,
+                                       next->addr, val);
+               else if (next->cmd == MT9M114_SENSOR_WORD_WRITE)
+                       err = mt9m114_write_reg16(info->i2c_client,
+                                       next->addr, val);
+               if (err)
+                       return err;
+       }
+       return 0;
+}
+
+static void mt9m114_mclk_disable(struct mt9m114_info *info)
+{
+       dev_info(&info->i2c_client->dev, "%s: disable MCLK\n", __func__);
+       clk_disable_unprepare(info->mclk);
+}
+
+static int mt9m114_mclk_enable(struct mt9m114_info *info)
+{
+       int err;
+       unsigned long mclk_init_rate = 24000000;
+
+       dev_info(&info->i2c_client->dev, "%s: enable MCLK with %lu Hz\n",
+               __func__, mclk_init_rate);
+
+       err = clk_set_rate(info->mclk, mclk_init_rate);
+       if (!err)
+               err = clk_prepare_enable(info->mclk);
+       return err;
+}
+
+static int mt9m114_open(struct inode *inode, struct file *file)
+{
+       struct miscdevice       *miscdev = file->private_data;
+       struct mt9m114_info *info = dev_get_drvdata(miscdev->parent);
+
+       dev_dbg(&info->i2c_client->dev, "mt9m114: open.\n");
+       info = container_of(miscdev, struct mt9m114_info, miscdev_info);
+       /* check if the device is in use */
+       if (atomic_xchg(&info->in_use, 1)) {
+               dev_info(&info->i2c_client->dev, "%s:BUSY!\n", __func__);
+               return -EBUSY;
+       }
+
+       file->private_data = info;
+
+       if (info->pdata && info->pdata->power_on) {
+               mt9m114_mclk_enable(info);
+               info->pdata->power_on(&info->power);
+       } else {
+               dev_err(&info->i2c_client->dev,
+                       "%s:no valid power_on function.\n", __func__);
+               return -EFAULT;
+       }
+       return 0;
+}
+
+int mt9m114_release(struct inode *inode, struct file *file)
+{
+       struct mt9m114_info *info = file->private_data;
+
+       if (info->pdata && info->pdata->power_off)
+               info->pdata->power_off(&info->power);
+       file->private_data = NULL;
+
+       /* warn if device is already released */
+       WARN_ON(!atomic_xchg(&info->in_use, 0));
+       return 0;
+}
+
+static int mt9m114_regulator_get(struct mt9m114_info *info,
+       struct regulator **vreg, char vreg_name[])
+{
+       struct regulator *reg = NULL;
+       int err = 0;
+
+       reg = devm_regulator_get(&info->i2c_client->dev, vreg_name);
+       if (unlikely(IS_ERR(reg))) {
+               dev_err(&info->i2c_client->dev, "%s %s ERR: %d\n",
+                       __func__, vreg_name, (int)reg);
+               err = PTR_ERR(reg);
+               reg = NULL;
+       } else {
+               dev_dbg(&info->i2c_client->dev, "%s: %s\n",
+                       __func__, vreg_name);
+       }
+
+       *vreg = reg;
+       return err;
+}
+
+static int mt9m114_power_get(struct mt9m114_info *info)
+{
+       struct mt9m114_power_rail *pw = &info->power;
+
+       dev_dbg(&info->i2c_client->dev, "mt9m114: %s\n", __func__);
+
+       /* note: mt9m114 uses i2c address 0x90, which is different from
+        * most of other sensors that using 0x64 or 0x20.
+        *
+        * This needs us to define a new vif2 as 2-0048
+        * for platform board file that uses mt9m114
+        * otherwise below could not get the regulator
+        *
+        * This rails of "vif2" and "vana" can be modified as needed
+        * for a new platform.
+        *
+        * mt9m114: need to get 1.8v first
+        */
+       mt9m114_regulator_get(info, &pw->iovdd, "vif"); /* interface 1.8v */
+       mt9m114_regulator_get(info, &pw->avdd, "vana"); /* ananlog 2.8v */
+
+       return 0;
+}
+
+static const struct file_operations mt9m114_fileops = {
+       .owner = THIS_MODULE,
+       .open = mt9m114_open,
+       .unlocked_ioctl = mt9m114_ioctl,
+       .release = mt9m114_release,
+};
+
+static struct miscdevice mt9m114_device = {
+       .minor = MISC_DYNAMIC_MINOR,
+       .name = "mt9m114",
+       .fops = &mt9m114_fileops,
+};
+
+static struct mt9m114_modeinfo def_modeinfo = {
+       .xres = 1280,
+       .yres = 960,
+};
+
+static struct mt9m114_mode_desc *mt9m114_get_mode(
+       struct mt9m114_info *info, struct mt9m114_mode *mode)
+{
+       struct mt9m114_mode_desc *mt = mode_table;
+
+       while (mt->xres) {
+               if ((mt->xres == mode->xres) &&
+                       (mt->yres == mode->yres))
+                               break;
+               mt++;
+       }
+
+       if (!mt->xres)
+               mt = NULL;
+       return mt;
+}
+
+static int mt9m114_mode_info_init(struct mt9m114_info *info)
+{
+       struct mt9m114_mode_desc *md = mode_table;
+       const struct mt9m114_reg *mt;
+       struct mt9m114_modeinfo *mi;
+
+       dev_dbg(&info->i2c_client->dev, "%s", __func__);
+       while (md->xres) {
+               mi = &md->mode_info;
+               mt = md->mode_tbl;
+               memcpy(mi, &def_modeinfo, sizeof(*mi));
+               dev_dbg(&info->i2c_client->dev, "mode %d x %d ",
+                       md->xres, md->yres);
+               mi->xres = md->xres;
+               mi->yres = md->yres;
+               md++;
+       }
+       return 0;
+}
+
+static int mt9m114_set_mode(struct mt9m114_info *info,
+       struct mt9m114_mode *mode)
+{
+       struct mt9m114_mode_desc *sensor_mode;
+       int err;
+
+       dev_info(&info->i2c_client->dev,
+               "%s: xres %u yres %u\n", __func__, mode->xres, mode->yres);
+
+       sensor_mode = mt9m114_get_mode(info, mode);
+       if (sensor_mode == NULL) {
+               dev_err(&info->i2c_client->dev,
+                       "%s: invalid params supplied to set mode %d %d\n",
+                               __func__, mode->xres, mode->yres);
+               return -EINVAL;
+       }
+
+       err = mt9m114_write_table(
+               info, sensor_mode->mode_tbl);
+       if (err)
+               return err;
+
+       info->mode = sensor_mode->mode_tbl;
+
+       return 0;
+}
+
+static long mt9m114_ioctl(struct file *file,
+                        unsigned int cmd, unsigned long arg)
+{
+       int err = 0;
+       struct mt9m114_info *info = file->private_data;
+
+       switch (cmd) {
+       case MT9M114_SENSOR_IOCTL_SET_MODE:
+       {
+               struct mt9m114_mode mode;
+
+               dev_dbg(&info->i2c_client->dev, "MT9M114_IOCTL_SET_MODE\n");
+               if (copy_from_user(&mode, (const void __user *)arg,
+                       sizeof(struct mt9m114_mode))) {
+                       err = -EFAULT;
+                       break;
+               }
+               err = mt9m114_set_mode(info, &mode);
+               break;
+       }
+
+       default:
+               dev_dbg(&info->i2c_client->dev, "INVALID IOCTL\n");
+               err = -EINVAL;
+       }
+
+       if (err)
+               dev_err(&info->i2c_client->dev,
+                       "%s - %x: ERR = %d\n", __func__, cmd, err);
+       return err;
+}
+
+static int mt9m114_probe(struct i2c_client *client,
+                       const struct i2c_device_id *id)
+{
+       int err;
+       struct mt9m114_info *info;
+       const char *mclk_name;
+       dev_dbg(&client->dev, "mt9m114: probing sensor.\n");
+
+       info = devm_kzalloc(&client->dev, sizeof(*info), GFP_KERNEL);
+       if (info == NULL) {
+               dev_err(&client->dev, "%s: kzalloc error\n", __func__);
+               return -ENOMEM;
+       }
+
+       info->pdata = client->dev.platform_data;
+       info->i2c_client = client;
+       atomic_set(&info->in_use, 0);
+       info->mode = NULL;
+
+       i2c_set_clientdata(client, info);
+
+       mclk_name = info->pdata->mclk_name ?
+                   info->pdata->mclk_name : "default_mclk";
+       info->mclk = devm_clk_get(&client->dev, mclk_name);
+       if (IS_ERR(info->mclk)) {
+               dev_err(&client->dev, "%s: unable to get clock %s\n",
+                       __func__, mclk_name);
+               return PTR_ERR(info->mclk);
+       }
+
+       mt9m114_power_get(info);
+       mt9m114_mode_info_init(info);
+
+       memcpy(&info->miscdev_info,
+               &mt9m114_device,
+               sizeof(struct miscdevice));
+
+       err = misc_register(&info->miscdev_info);
+       if (err) {
+               dev_err(&info->i2c_client->dev, "mt9m114: Unable to register misc device!\n");
+               kfree(info);
+               return err;
+       }
+
+       return 0;
+}
+
+static int mt9m114_remove(struct i2c_client *client)
+{
+       struct mt9m114_info *info;
+       info = i2c_get_clientdata(client);
+       misc_deregister(&mt9m114_device);
+       kfree(info);
+
+       return 0;
+}
+
+static const struct i2c_device_id mt9m114_id[] = {
+       { "mt9m114", 0 },
+       { },
+};
+
+MODULE_DEVICE_TABLE(i2c, mt9m114_id);
+
+static struct i2c_driver mt9m114_i2c_driver = {
+       .driver = {
+               .name = "mt9m114",
+               .owner = THIS_MODULE,
+       },
+       .probe = mt9m114_probe,
+       .remove = mt9m114_remove,
+       .id_table = mt9m114_id,
+};
+
+static int __init mt9m114_init(void)
+{
+       pr_info("mt9m114 sensor driver loading\n");
+       return i2c_add_driver(&mt9m114_i2c_driver);
+}
+
+static void __exit mt9m114_exit(void)
+{
+       i2c_del_driver(&mt9m114_i2c_driver);
+}
+
+module_init(mt9m114_init);
+module_exit(mt9m114_exit);
+MODULE_LICENSE("GPL v2");
diff --git a/include/media/mt9m114.h b/include/media/mt9m114.h
new file mode 100644 (file)
index 0000000..d52aa0b
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2013 NVIDIA Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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 __MT9M114_H__
+#define __MT9M114_H__
+
+#include <linux/ioctl.h>  /* For IOCTL macros */
+
+#define SENSOR_NAME     "mt9m114"
+#define DEV(x)          "/dev/"x
+#define SENSOR_PATH     DEV(SENSOR_NAME)
+#define LOG_NAME(x)     "ImagerODM-"x
+#define LOG_TAG         LOG_NAME(SENSOR_NAME)
+
+#define MT9M114_SENSOR_WAIT_MS          0
+#define MT9M114_SENSOR_TABLE_END        1
+#define MT9M114_SENSOR_BYTE_WRITE       2
+#define MT9M114_SENSOR_WORD_WRITE       3
+#define MT9M114_SENSOR_MASK_BYTE_WRITE  4
+#define MT9M114_SENSOR_MASK_WORD_WRITE  5
+#define MT9M114_SEQ_WRITE_START         6
+#define MT9M114_SEQ_WRITE_END           7
+
+#define MT9M114_SENSOR_MAX_RETRIES      3 /* max counter for retry I2C access */
+#define MT9M114_MAX_FACEDETECT_WINDOWS  5
+#define MT9M114_SENSOR_IOCTL_SET_MODE  _IOW('o', 1, struct mt9m114_modeinfo)
+#define MT9M114_SENSOR_IOCTL_GET_STATUS         _IOR('o', 2, __u8)
+#define MT9M114_SENSOR_IOCTL_SET_COLOR_EFFECT   _IOW('o', 3, __u16)
+#define MT9M114_SENSOR_IOCTL_SET_WHITE_BALANCE  _IOW('o', 4, __u8)
+#define MT9M114_SENSOR_IOCTL_SET_SCENE_MODE     _IOW('o', 5, __u8)
+#define MT9M114_SENSOR_IOCTL_SET_AF_MODE        _IOW('o', 6, __u8)
+#define MT9M114_SENSOR_IOCTL_GET_AF_STATUS      _IOR('o', 7, __u8)
+#define MT9M114_SENSOR_IOCTL_SET_CAMERA         _IOW('o', 8, __u8)
+
+struct mt9m114_mode {
+       int xres;
+       int yres;
+};
+
+struct mt9m114_modeinfo {
+       int xres;
+       int yres;
+};
+
+#define  AF_CMD_START 0
+#define  AF_CMD_ABORT 1
+#define  AF_CMD_SET_POSITION  2
+#define  AF_CMD_SET_WINDOW_POSITION 3
+#define  AF_CMD_SET_WINDOW_SIZE 4
+#define  AF_CMD_SET_AFMODE  5
+#define  AF_CMD_SET_CAF 6
+#define  AF_CMD_GET_AF_STATUS 7
+
+enum {
+       YUV_COLOR_EFFECT = 0,
+       YUV_WHITE_BALANCE,
+       YUV_SCENE_MODE,
+};
+
+enum {
+       YUV_COLOR_EFFECT_INVALID = 0,
+       YUV_COLOR_EFFECT_NONE,
+       YUV_COLOR_EFFECT_MONO,
+       YUV_COLOR_EFFECT_NEGATIVE,
+       YUV_COLOR_EFFECT_POSTERIZE,
+       YUV_COLOR_EFFECT_SEPIA,
+       YUV_COLOR_EFFECT_SOLARIZE,
+       YUV_COLOR_EFFECT_MAX
+};
+
+enum {
+       YUV_WHITE_BALANCE_INVALID = 0,
+       YUV_WHITE_BALANCE_AUTO,
+       YUV_WHITE_BALANCE_INCANDESCENT,
+       YUV_WHITE_BALANCE_FLUORESCENT,
+       YUV_WHITE_BALANCE_DAYLIGHT,
+       YUV_WHITE_BALANCE_CUSTOME
+};
+
+struct mt9m114_sensordata {
+       __u32 fuse_id_size;
+       __u8  fuse_id[16];
+};
+
+#ifdef __KERNEL__
+struct mt9m114_power_rail {
+       struct regulator *dvdd;
+       struct regulator *avdd;
+       struct regulator *iovdd;
+};
+
+struct mt9m114_platform_data {
+       int (*power_on)(struct mt9m114_power_rail *pw);
+       int (*power_off)(struct mt9m114_power_rail *pw);
+       const char *mclk_name;
+};
+#endif /* __KERNEL__ */
+
+#endif  /* __MT9M114_H__ */