From: John Kramer <john.kramer@motorola.com>
Date: Tue, 19 Oct 2010 19:31:30 +0000 (-0500)
Subject: media: video: tegra: Add features to soc2030
X-Git-Tag: firefly_0821_release~9834^2~408
X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=bf7331d28b9139e6e9ba1b52cba0a3328a2e5739;p=firefly-linux-kernel-4.4.55.git

media: video: tegra: Add features to soc2030

Add user white balance, effects and exposure support
to the soc2030 2MP camera sensor driver

Change-Id: I8f572b9369bbbbab89b49a60046f48dbcb54b33d
Signed-off-by: John Kramer <john.kramer@motorola.com>
---

diff --git a/drivers/media/video/tegra/soc2030.c b/drivers/media/video/tegra/soc2030.c
index c7ed07bb237d..74dc15e264af 100644
--- a/drivers/media/video/tegra/soc2030.c
+++ b/drivers/media/video/tegra/soc2030.c
@@ -35,101 +35,120 @@ struct soc2030_info {
  * 1600X1200 15fps (Max), 800X600 30fps (Max)
  */
 static struct soc2030_regs base_mode[] = {
-	{WRITE_REG_DATA, 0x321C, 0x0000},	/*By Pass TxFIFO = 0*/
-	{WRITE_REG_DATA, 0x098C, 0x2703},	/*Output Width (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x0320},	/*      = 800*/
-	{WRITE_REG_DATA, 0x098C, 0x2705},	/*Output Height (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x0258},	/*      = 600*/
-	{WRITE_REG_DATA, 0x098C, 0x2707},	/*Output Width (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x0640},	/*      = 1600*/
-	{WRITE_REG_DATA, 0x098C, 0x2709},	/*Output Height (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x04B0},	/*      = 1200*/
-	{WRITE_REG_DATA, 0x098C, 0x270D},	/*Row Start (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x000},	/*      = 0*/
-	{WRITE_REG_DATA, 0x098C, 0x270F},	/*Column Start (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x000},	/*      = 0*/
-	{WRITE_REG_DATA, 0x098C, 0x2711},	/*Row End (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x4BD},	/*      = 1213*/
-	{WRITE_REG_DATA, 0x098C, 0x2713},	/*Column End (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x64D},	/*      = 1613*/
-	{WRITE_REG_DATA, 0x098C, 0x2715},	/*Row Speed (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x0111},	/*      = 273*/
-	{WRITE_REG_DATA, 0x098C, 0x2717},	/*Read Mode (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x046C},	/*      = 1132*/
-	{WRITE_REG_DATA, 0x098C, 0x2719},	/*sensor_fine_correction (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x005A},	/*      = 90*/
-	{WRITE_REG_DATA, 0x098C, 0x271B},	/*sensor_fine_IT_min (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x01BE},	/*      = 446*/
-	{WRITE_REG_DATA, 0x098C, 0x271D},	/*sensor_fine_IT_max_margin(A)*/
-	{WRITE_REG_DATA, 0x0990, 0x0131},	/*      = 305*/
-	{WRITE_REG_DATA, 0x098C, 0x271F},	/*Frame Lines (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x02B3},	/*      = 691*/
-	{WRITE_REG_DATA, 0x098C, 0x2721},	/*Line Length (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x0853},	/*      = 2131*/
-	{WRITE_REG_DATA, 0x098C, 0x2723},	/*Row Start (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x004},	/*      = 4*/
-	{WRITE_REG_DATA, 0x098C, 0x2725},	/*Column Start (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x004},	/*      = 4*/
-	{WRITE_REG_DATA, 0x098C, 0x2727},	/*Row End (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x4BB},	/*      = 1211*/
-	{WRITE_REG_DATA, 0x098C, 0x2729},	/*Column End (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x64B},	/*      = 1611*/
-	{WRITE_REG_DATA, 0x098C, 0x272B},	/*Row Speed (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x0111},	/*      = 273*/
-	{WRITE_REG_DATA, 0x098C, 0x272D},	/*Read Mode (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x0024},	/*      = 36*/
-	{WRITE_REG_DATA, 0x098C, 0x272F},	/*sensor_fine_correction (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x003A},	/*      = 58*/
-	{WRITE_REG_DATA, 0x098C, 0x2731},	/*sensor_fine_IT_min (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x00F6},	/*      = 246*/
-	{WRITE_REG_DATA, 0x098C, 0x2733},	/*sensor_fine_IT_max_margin(B)*/
-	{WRITE_REG_DATA, 0x0990, 0x008B},	/*      = 139*/
-	{WRITE_REG_DATA, 0x098C, 0x2735},	/*Frame Lines (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x050D},	/*      = 1293*/
-	{WRITE_REG_DATA, 0x098C, 0x2737},	/*Line Length (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x085A},	/*      = 2138*/
-	{WRITE_REG_DATA, 0x098C, 0x2739},	/*Crop_X0 (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x0000},	/*      = 0*/
-	{WRITE_REG_DATA, 0x098C, 0x273B},	/*Crop_X1 (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x031F},	/*      = 799*/
-	{WRITE_REG_DATA, 0x098C, 0x273D},	/*Crop_Y0 (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x0000},	/*      = 0*/
-	{WRITE_REG_DATA, 0x098C, 0x273F},	/*Crop_Y1 (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x0257},	/*      = 599*/
-	{WRITE_REG_DATA, 0x098C, 0x2747},	/*Crop_X0 (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x0000},	/*      = 0*/
-	{WRITE_REG_DATA, 0x098C, 0x2749},	/*Crop_X1 (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x063F},	/*      = 1599*/
-	{WRITE_REG_DATA, 0x098C, 0x274B},	/*Crop_Y0 (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x0000},	/*      = 0*/
-	{WRITE_REG_DATA, 0x098C, 0x274D},	/*Crop_Y1 (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x04AF},	/*      = 1199*/
-	{WRITE_REG_DATA, 0x098C, 0x222D},	/*R9 Step*/
-	{WRITE_REG_DATA, 0x0990, 0x009E},	/*      = 158*/
-	{WRITE_REG_DATA, 0x098C, 0xA408},	/*search_f1_50*/
-	{WRITE_REG_DATA, 0x0990, 0x26},	/*      = 38*/
-	{WRITE_REG_DATA, 0x098C, 0xA409},	/*search_f2_50*/
-	{WRITE_REG_DATA, 0x0990, 0x28},	/*      = 40*/
-	{WRITE_REG_DATA, 0x098C, 0xA40A},	/*search_f1_60*/
-	{WRITE_REG_DATA, 0x0990, 0x2E},	/*      = 46*/
-	{WRITE_REG_DATA, 0x098C, 0xA40B},	/*search_f2_60*/
-	{WRITE_REG_DATA, 0x0990, 0x30},	/*      = 48*/
-	{WRITE_REG_DATA, 0x098C, 0x2411},	/*R9_Step_60 (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x009E},	/*      = 158*/
-	{WRITE_REG_DATA, 0x098C, 0x2413},	/*R9_Step_50 (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x00BE},	/*      = 190*/
-	{WRITE_REG_DATA, 0x098C, 0x2415},	/*R9_Step_60 (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x009E},	/*      = 158*/
-	{WRITE_REG_DATA, 0x098C, 0x2417},	/*R9_Step_50 (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x00BD},	/*      = 189*/
-	{WRITE_REG_DATA, 0x098C, 0xA404},	/*FD Mode*/
-	{WRITE_REG_DATA, 0x0990, 0x10},	/*      = 16*/
-	{WRITE_REG_DATA, 0x098C, 0xA40D},	/*Stat_min*/
-	{WRITE_REG_DATA, 0x0990, 0x02},	/*      = 2*/
-	{WRITE_REG_DATA, 0x098C, 0xA40E},	/*Stat_max*/
-	{WRITE_REG_DATA, 0x0990, 0x03},	/*      = 3*/
-	{WRITE_REG_DATA, 0x098C, 0xA410},	/*Min_amplitude*/
-	{WRITE_REG_DATA, 0x0990, 0x0A},	/*      = 10*/
+	{WRITE_REG_DATA, 0x98C, 0x2703},	/*Output Width (A)*/
+	{WRITE_REG_DATA, 0x990, 0x0320},	/*      = 800*/
+	{WRITE_REG_DATA, 0x98C, 0x2705},	/*Output Height (A)*/
+	{WRITE_REG_DATA, 0x990, 0x0258},	/*      = 600*/
+	{WRITE_REG_DATA, 0x98C, 0x2707},	/*Output Width (B)*/
+	{WRITE_REG_DATA, 0x990, 0x0640},	/*      = 1600*/
+	{WRITE_REG_DATA, 0x98C, 0x2709},	/*Output Height (B)*/
+	{WRITE_REG_DATA, 0x990, 0x04B0},	/*      = 1200*/
+	{WRITE_REG_DATA, 0x98C, 0x270D},	/*Row Start (A)*/
+	{WRITE_REG_DATA, 0x990, 0x0000},	/*      = 0*/
+	{WRITE_REG_DATA, 0x98C, 0x270F},	/*Column Start (A)*/
+	{WRITE_REG_DATA, 0x990, 0x0000},	/*      = 0*/
+	{WRITE_REG_DATA, 0x98C, 0x2711},	/*Row End (A)*/
+	{WRITE_REG_DATA, 0x990, 0x04BD},	/*      = 1213*/
+	{WRITE_REG_DATA, 0x98C, 0x2713},	/*Column End (A)*/
+	{WRITE_REG_DATA, 0x990, 0x064D},	/*      = 1613*/
+	{WRITE_REG_DATA, 0x98C, 0x2715},	/*Row Speed (A)*/
+	{WRITE_REG_DATA, 0x990, 0x0111},	/*      = 273*/
+	{WRITE_REG_DATA, 0x98C, 0x2717},	/*Read Mode (A)*/
+	{WRITE_REG_DATA, 0x990, 0x046C},	/*      = 1132*/
+	{WRITE_REG_DATA, 0x98C, 0x2719},	/*fine_corr (A)*/
+	{WRITE_REG_DATA, 0x990, 0x005A},	/*      = 90*/
+	{WRITE_REG_DATA, 0x98C, 0x271B},	/*sensor_fine_IT_min (A)*/
+	{WRITE_REG_DATA, 0x990, 0x01BE},	/*      = 446*/
+	{WRITE_REG_DATA, 0x98C, 0x271D},	/*fine_IT_max_mrgn (A)*/
+	{WRITE_REG_DATA, 0x990, 0x0131},	/*      = 305*/
+	{WRITE_REG_DATA, 0x98C, 0x271F},	/*Frame Lines (A)*/
+	{WRITE_REG_DATA, 0x990, 0x02B3},	/*      = 691*/
+	{WRITE_REG_DATA, 0x98C, 0x2721},	/*Line Length (A)*/
+	{WRITE_REG_DATA, 0x990, 0x07EA},	/*      = 2026*/
+	{WRITE_REG_DATA, 0x98C, 0x2723},	/*Row Start (B)*/
+	{WRITE_REG_DATA, 0x990, 0x0004},	/*      = 4*/
+	{WRITE_REG_DATA, 0x98C, 0x2725},	/*Column Start (B)*/
+	{WRITE_REG_DATA, 0x990, 0x0004},	/*      = 4*/
+	{WRITE_REG_DATA, 0x98C, 0x2727},	/*Row End (B)*/
+	{WRITE_REG_DATA, 0x990, 0x04BB},	/*      = 1211*/
+	{WRITE_REG_DATA, 0x98C, 0x2729},	/*Column End (B)*/
+	{WRITE_REG_DATA, 0x990, 0x064B},	/*      = 1611*/
+	{WRITE_REG_DATA, 0x98C, 0x272B},	/*Row Speed (B)*/
+	{WRITE_REG_DATA, 0x990, 0x0111},	/*      = 273*/
+	{WRITE_REG_DATA, 0x98C, 0x272D},	/*Read Mode (B)*/
+	{WRITE_REG_DATA, 0x990, 0x0024},	/*      = 36*/
+	{WRITE_REG_DATA, 0x98C, 0x272F},	/*sfine_corr (B)*/
+	{WRITE_REG_DATA, 0x990, 0x003A},	/*      = 58*/
+	{WRITE_REG_DATA, 0x98C, 0x2731},	/*fine_IT_min (B)*/
+	{WRITE_REG_DATA, 0x990, 0x00F6},	/*      = 246*/
+	{WRITE_REG_DATA, 0x98C, 0x2733},	/*fine_IT_max_mrgn (B)*/
+	{WRITE_REG_DATA, 0x990, 0x008B},	/*      = 139*/
+	{WRITE_REG_DATA, 0x98C, 0x2735},	/*Frame Lines (B)*/
+	{WRITE_REG_DATA, 0x990, 0x050D},	/*      = 1293*/
+	{WRITE_REG_DATA, 0x98C, 0x2737},	/*Line Length (B)*/
+	{WRITE_REG_DATA, 0x990, 0x08A9},	/*      = 2217*/
+	{WRITE_REG_DATA, 0x98C, 0x2739},	/*Crop_X0 (A)*/
+	{WRITE_REG_DATA, 0x990, 0x0000},	/*      = 0*/
+	{WRITE_REG_DATA, 0x98C, 0x273B},	/*Crop_X1 (A)*/
+	{WRITE_REG_DATA, 0x990, 0x031F},	/*      = 799*/
+	{WRITE_REG_DATA, 0x98C, 0x273D},	/*Crop_Y0 (A)*/
+	{WRITE_REG_DATA, 0x990, 0x0000},	/*      = 0*/
+	{WRITE_REG_DATA, 0x98C, 0x273F},	/*Crop_Y1 (A)*/
+	{WRITE_REG_DATA, 0x990, 0x0257},	/*      = 599*/
+	{WRITE_REG_DATA, 0x98C, 0x2747},	/*Crop_X0 (B)*/
+	{WRITE_REG_DATA, 0x990, 0x0000},	/*      = 0*/
+	{WRITE_REG_DATA, 0x98C, 0x2749},	/*Crop_X1 (B)*/
+	{WRITE_REG_DATA, 0x990, 0x063F},	/*      = 1599*/
+	{WRITE_REG_DATA, 0x98C, 0x274B},	/*Crop_Y0 (B)*/
+	{WRITE_REG_DATA, 0x990, 0x0000},	/*      = 0*/
+	{WRITE_REG_DATA, 0x98C, 0x274D},	/*Crop_Y1 (B)*/
+	{WRITE_REG_DATA, 0x990, 0x04AF},	/*      = 1199*/
+	{WRITE_REG_DATA, 0x98C, 0x222D},	/*R9 Step*/
+	{WRITE_REG_DATA, 0x990, 0x00AD},	/*      = 173*/
+	{WRITE_REG_DATA, 0x98C, 0xA408},	/*search_f1_50*/
+	{WRITE_REG_DATA, 0x990, 0x002A},	/*      = 42*/
+	{WRITE_REG_DATA, 0x98C, 0xA409},	/*search_f2_50*/
+	{WRITE_REG_DATA, 0x990, 0x002C},	/*      = 44*/
+	{WRITE_REG_DATA, 0x98C, 0xA40A},	/*search_f1_60*/
+	{WRITE_REG_DATA, 0x990, 0x0032},	/*      = 50*/
+	{WRITE_REG_DATA, 0x98C, 0xA40B},	/*search_f2_60*/
+	{WRITE_REG_DATA, 0x990, 0x0034},	/*      = 52*/
+	{WRITE_REG_DATA, 0x98C, 0x2411},	/*R9_Step_60 (A)*/
+	{WRITE_REG_DATA, 0x990, 0x00AD},	/*      = 173*/
+	{WRITE_REG_DATA, 0x98C, 0x2413},	/*R9_Step_50 (A)*/
+	{WRITE_REG_DATA, 0x990, 0x00CF},	/*      = 207*/
+	{WRITE_REG_DATA, 0x98C, 0x2415},	/*R9_Step_60 (B)*/
+	{WRITE_REG_DATA, 0x990, 0x009E},	/*      = 158*/
+	{WRITE_REG_DATA, 0x98C, 0x2417},	/*R9_Step_50 (B)*/
+	{WRITE_REG_DATA, 0x990, 0x00BD},	/*      = 189*/
+	{WRITE_REG_DATA, 0x98C, 0xA404},	/*FD Mode*/
+	{WRITE_REG_DATA, 0x990, 0x0010},	/*      = 16*/
+	{WRITE_REG_DATA, 0x98C, 0xA40D},	/*Stat_min*/
+	{WRITE_REG_DATA, 0x990, 0x0002},	/*      = 2*/
+	{WRITE_REG_DATA, 0x98C, 0xA40E},	/*Stat_max*/
+	{WRITE_REG_DATA, 0x990, 0x0003},	/*      = 3*/
+	{WRITE_REG_DATA, 0x98C, 0xA410},	/*Min_amplitude*/
+	{WRITE_REG_DATA, 0x990, 0x000A},	/*      = 10*/
+	{REG_TABLE_END, 0x0000, 0x0000}
+};
+
+/*
+ * Refresh Sequencer Mode
+ */
+static struct soc2030_regs refresh_mode[] = {
+	{WRITE_REG_DATA, 0x098C, 0xa103},	/* Refresh Mode */
+	{WRITE_REG_DATA, 0x0990, 0x0006},
+	{POLL_VAR_DATA, 0xa103, 0x0000},
+	{REG_TABLE_END, 0x0000, 0x0000}
+};
+
+/*
+ * Refresh Sequencer State
+ */
+static struct soc2030_regs refresh_state[] = {
+	{WRITE_REG_DATA, 0x098C, 0xa103},	/* Refresh Seq */
+	{WRITE_REG_DATA, 0x0990, 0x0005},
+	{POLL_VAR_DATA, 0xa103, 0x0000},
 	{REG_TABLE_END, 0x0000, 0x0000}
 };
 
@@ -137,15 +156,67 @@ static struct soc2030_regs base_mode[] = {
  * SetMode Sequence for context A (800X600, preview).
  * Phase 0. Sensor Dependent.
  * This is usually given by the FAE or the sensor vendor.
- * 800X600 15fps fixed
+ * 800X600 30fps fixed
  */
 static struct soc2030_regs mode_800x600[] = {
-	{WRITE_REG_DATA, 0x098C, 0xA115},
+	{WRITE_REG_DATA, 0x98C, 0x2703},	/*Output Width (A)*/
+	{WRITE_REG_DATA, 0x990, 0x0320},	/*      = 800*/
+	{WRITE_REG_DATA, 0x98C, 0x2705},	/*Output Height (A)*/
+	{WRITE_REG_DATA, 0x990, 0x0258},	/*      = 600*/
+	{WRITE_REG_DATA, 0x98C, 0x270D},	/*Row Start (A)*/
+	{WRITE_REG_DATA, 0x990, 0x0000},	/*      = 0*/
+	{WRITE_REG_DATA, 0x98C, 0x270F},	/*Column Start (A)*/
+	{WRITE_REG_DATA, 0x990, 0x0000},	/*      = 0*/
+	{WRITE_REG_DATA, 0x98C, 0x2711},	/*Row End (A)*/
+	{WRITE_REG_DATA, 0x990, 0x04BD},	/*      = 1213*/
+	{WRITE_REG_DATA, 0x98C, 0x2713},	/*Column End (A)*/
+	{WRITE_REG_DATA, 0x990, 0x064D},	/*     = 1613*/
+	{WRITE_REG_DATA, 0x98C, 0x2715},	/*Row Speed (A)*/
+	{WRITE_REG_DATA, 0x990, 0x0111},	/*      = 273*/
+	{WRITE_REG_DATA, 0x98C, 0x2717},	/*Read Mode (A)*/
+	{WRITE_REG_DATA, 0x990, 0x046C},	/*      = 1132*/
+	{WRITE_REG_DATA, 0x98C, 0x2719},	/*fine_corr (A)*/
+	{WRITE_REG_DATA, 0x990, 0x005A},	/*      = 90*/
+	{WRITE_REG_DATA, 0x98C, 0x271B},	/*_fine_IT_min (A)*/
+	{WRITE_REG_DATA, 0x990, 0x01BE},	/*      = 446*/
+	{WRITE_REG_DATA, 0x98C, 0x271D},	/*fine_IT_max_mrgn (A)*/
+	{WRITE_REG_DATA, 0x990, 0x0131},	/*      = 305*/
+	{WRITE_REG_DATA, 0x98C, 0x271F},	/*Frame Lines (A)*/
+	{WRITE_REG_DATA, 0x990, 0x02B3},	/*      = 691*/
+	{WRITE_REG_DATA, 0x98C, 0x2721},	/*Line Length (A)*/
+	{WRITE_REG_DATA, 0x990, 0x07EA},	/*      = 2026*/
+	{WRITE_REG_DATA, 0x98C, 0x2739},	/*Crop_X0 (A)*/
+	{WRITE_REG_DATA, 0x990, 0x0000},	/*      = 0*/
+	{WRITE_REG_DATA, 0x98C, 0x273B},	/*Crop_X1 (A)*/
+	{WRITE_REG_DATA, 0x990, 0x031F},	/*      = 799*/
+	{WRITE_REG_DATA, 0x98C, 0x273D},	/*Crop_Y0 (A)*/
+	{WRITE_REG_DATA, 0x990, 0x0000},	/*      = 0*/
+	{WRITE_REG_DATA, 0x98C, 0x273F},	/*Crop_Y1 (A)*/
+	{WRITE_REG_DATA, 0x990, 0x0257},	/*      = 599*/
+	{WRITE_REG_DATA, 0x98C, 0x222D},	/*R9 Step*/
+	{WRITE_REG_DATA, 0x990, 0x00AD},	/*      = 173*/
+	{WRITE_REG_DATA, 0x98C, 0xA408},	/*search_f1_50*/
+	{WRITE_REG_DATA, 0x990, 0x002A},	/*      = 42*/
+	{WRITE_REG_DATA, 0x98C, 0xA409},	/*search_f2_50*/
+	{WRITE_REG_DATA, 0x990, 0x002C},	/*      = 44*/
+	{WRITE_REG_DATA, 0x98C, 0xA40A},	/*search_f1_60*/
+	{WRITE_REG_DATA, 0x990, 0x0032},	/*      = 50*/
+	{WRITE_REG_DATA, 0x98C, 0xA40B},	/*search_f2_60*/
+	{WRITE_REG_DATA, 0x990, 0x0034},	/*      = 52*/
+	{WRITE_REG_DATA, 0x98C, 0x2411},	/*R9_Step_60 (A)*/
+	{WRITE_REG_DATA, 0x990, 0x00AD},	/*      = 173*/
+	{WRITE_REG_DATA, 0x98C, 0x2413},	/*R9_Step_50 (A)*/
+	{WRITE_REG_DATA, 0x990, 0x00CF},	/*      = 207*/
+	{WRITE_REG_BIT_L, 0x3040, 0x1000},	/* Disable Bin Sum */
+	{WRITE_REG_DATA, 0x098C, 0xA215},	/* Fix FPS */
+	{WRITE_REG_DATA, 0x0990, 0x0003},
+	{WRITE_REG_DATA, 0x098C, 0xA20C},	/* AE_MAX_INDEX */
+	{WRITE_REG_DATA, 0x0990, 0x0004},	/* 30 FPS fixed */
+	{WRITE_REG_DATA, 0x098C, 0xA115},	/* ISP off in cntx B */
 	{WRITE_REG_DATA, 0x0990, 0x0000},
-	{WRITE_REG_DATA, 0x098C, 0xA103},
-	{WRITE_REG_DATA, 0x0990, 0x0001},
-	{WRITE_REG_DATA, 0x098C, 0xA215},
+	{WRITE_REG_DATA, 0x098C, 0xA103},	/* Context A preview */
 	{WRITE_REG_DATA, 0x0990, 0x0001},
+	{POLL_VAR_DATA, 0xa104, 0x0003},
 	{REG_TABLE_END, 0x0000, 0x0000}
 };
 
@@ -156,10 +227,16 @@ static struct soc2030_regs mode_800x600[] = {
  * 1600X1200 15fps (Max)
  */
 static struct soc2030_regs mode_1600x1200[] = {
-	{WRITE_REG_DATA, 0x098C, 0xA115},
+	{WRITE_REG_DATA, 0x098C, 0xA215},	/* Fix FPS */
+	{WRITE_REG_DATA, 0x0990, 0x000F},
+	{WRITE_REG_DATA, 0x098C, 0xA20C},	/* AE_MAX_INDEX */
+	{WRITE_REG_DATA, 0x0990, 0x0010},	/* 7.5 FPS MIN */
+	{WRITE_REG_DATA, 0x098C, 0xA115},	/* ISP in Context B */
 	{WRITE_REG_DATA, 0x0990, 0x0072},
-	{WRITE_REG_DATA, 0x098C, 0xA103},
+	{WRITE_REG_DATA, 0x098C, 0xA103},	/* Context B full */
 	{WRITE_REG_DATA, 0x0990, 0x0002},
+	{POLL_VAR_DATA, 0xa104, 0x0007},
+	{POLL_VAR_DATA, 0xa103, 0x0000},
 	{REG_TABLE_END, 0x0000, 0x0000}
 };
 
@@ -170,115 +247,80 @@ static struct soc2030_regs mode_1600x1200[] = {
  * 1280X720 30fps (Fixed)
  */
 static struct soc2030_regs mode_1280x720[] = {
-	{WRITE_REG_DATA, 0x321C, 0x0000},	/*By Pass TxFIFO = 0*/
-	{WRITE_REG_DATA, 0x098C, 0x2703},	/*Output Width (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x0500},	/*      = 1280*/
-	{WRITE_REG_DATA, 0x098C, 0x2705},	/*Output Height (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x02D0},	/*      = 720*/
-	{WRITE_REG_DATA, 0x098C, 0x2707},	/*Output Width (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x0500},	/*      = 1280*/
-	{WRITE_REG_DATA, 0x098C, 0x2709},	/*Output Height (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x02D0},	/*      = 720*/
-	{WRITE_REG_DATA, 0x098C, 0x270D},	/*Row Start (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x0F6},	/*      = 246*/
-	{WRITE_REG_DATA, 0x098C, 0x270F},	/*Column Start (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x0A6},	/*      = 166*/
-	{WRITE_REG_DATA, 0x098C, 0x2711},	/*Row End (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x3CD},	/*      = 973*/
-	{WRITE_REG_DATA, 0x098C, 0x2713},	/*Column End (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x5AD},	/*      = 1453*/
-	{WRITE_REG_DATA, 0x098C, 0x2715},	/*Row Speed (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x0111},	/*      = 273*/
-	{WRITE_REG_DATA, 0x098C, 0x2717},	/*Read Mode (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x0024},	/*      = 36*/
-	{WRITE_REG_DATA, 0x098C, 0x2719},	/*sensor_fine_correction (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x003A},	/*      = 58*/
-	{WRITE_REG_DATA, 0x098C, 0x271B},	/*sensor_fine_IT_min (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x00F6},	/*      = 246*/
-	{WRITE_REG_DATA, 0x098C, 0x271D},	/*sensor_fine_IT_max_margin(A)*/
-	{WRITE_REG_DATA, 0x0990, 0x008B},	/*      = 139*/
-	{WRITE_REG_DATA, 0x098C, 0x271F},	/*Frame Lines (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x032D},	/*      = 813*/
-	{WRITE_REG_DATA, 0x098C, 0x2721},	/*Line Length (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x067C},	/*      = 1660*/
-	{WRITE_REG_DATA, 0x098C, 0x2723},	/*Row Start (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x0F6},	/*      = 246*/
-	{WRITE_REG_DATA, 0x098C, 0x2725},	/*Column Start (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x0A6},	/*      = 166*/
-	{WRITE_REG_DATA, 0x098C, 0x2727},	/*Row End (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x3CD},	/*      = 973*/
-	{WRITE_REG_DATA, 0x098C, 0x2729},	/*Column End (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x5AD},	/*      = 1453*/
-	{WRITE_REG_DATA, 0x098C, 0x272B},	/*Row Speed (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x0111},	/*      = 273*/
-	{WRITE_REG_DATA, 0x098C, 0x272D},	/*Read Mode (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x0024},	/*      = 36*/
-	{WRITE_REG_DATA, 0x098C, 0x272F},	/*sensor_fine_correction (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x003A},	/*      = 58*/
-	{WRITE_REG_DATA, 0x098C, 0x2731},	/*sensor_fine_IT_min (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x00F6},	/*      = 246*/
-	{WRITE_REG_DATA, 0x098C, 0x2733},	/*sensor_fine_IT_max_margin(B)*/
-	{WRITE_REG_DATA, 0x0990, 0x008B},	/*      = 139*/
-	{WRITE_REG_DATA, 0x098C, 0x2735},	/*Frame Lines (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x032D},	/*      = 813*/
-	{WRITE_REG_DATA, 0x098C, 0x2737},	/*Line Length (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x067C},	/*      = 1660*/
-	{WRITE_REG_DATA, 0x098C, 0x2739},	/*Crop_X0 (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x0000},	/*      = 0*/
-	{WRITE_REG_DATA, 0x098C, 0x273B},	/*Crop_X1 (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x04FF},	/*      = 1279*/
-	{WRITE_REG_DATA, 0x098C, 0x273D},	/*Crop_Y0 (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x0000},	/*      = 0*/
-	{WRITE_REG_DATA, 0x098C, 0x273F},	/*Crop_Y1 (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x02CF},	/*      = 719*/
-	{WRITE_REG_DATA, 0x098C, 0x2747},	/*Crop_X0 (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x0000},	/*      = 0*/
-	{WRITE_REG_DATA, 0x098C, 0x2749},	/*Crop_X1 (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x04FF},	/*      = 1279*/
-	{WRITE_REG_DATA, 0x098C, 0x274B},	/*Crop_Y0 (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x0000},	/*      = 0*/
-	{WRITE_REG_DATA, 0x098C, 0x274D},	/*Crop_Y1 (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x02CF},	/*      = 719*/
-	{WRITE_REG_DATA, 0x098C, 0x222D},	/*R9 Step*/
-	{WRITE_REG_DATA, 0x0990, 0x00CB},	/*      = 203*/
-	{WRITE_REG_DATA, 0x098C, 0xA408},	/*search_f1_50*/
-	{WRITE_REG_DATA, 0x0990, 0x31},	/*      = 49*/
-	{WRITE_REG_DATA, 0x098C, 0xA409},	/*search_f2_50*/
-	{WRITE_REG_DATA, 0x0990, 0x33},	/*      = 51*/
-	{WRITE_REG_DATA, 0x098C, 0xA40A},	/*search_f1_60*/
-	{WRITE_REG_DATA, 0x0990, 0x3C},	/*      = 60*/
-	{WRITE_REG_DATA, 0x098C, 0xA40B},	/*search_f2_60*/
-	{WRITE_REG_DATA, 0x0990, 0x3E},	/*      = 62*/
-	{WRITE_REG_DATA, 0x098C, 0x2411},	/*R9_Step_60 (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x00CB},	/*      = 203*/
-	{WRITE_REG_DATA, 0x098C, 0x2413},	/*R9_Step_50 (A)*/
-	{WRITE_REG_DATA, 0x0990, 0x00F4},	/*      = 244*/
-	{WRITE_REG_DATA, 0x098C, 0x2415},	/*R9_Step_60 (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x00CB},	/*      = 203*/
-	{WRITE_REG_DATA, 0x098C, 0x2417},	/*R9_Step_50 (B)*/
-	{WRITE_REG_DATA, 0x0990, 0x00F4},	/*      = 244*/
-	{WRITE_REG_DATA, 0x098C, 0xA404},	/*FD Mode*/
-	{WRITE_REG_DATA, 0x0990, 0x10},	/*      = 16*/
-	{WRITE_REG_DATA, 0x098C, 0xA40D},	/*Stat_min*/
-	{WRITE_REG_DATA, 0x0990, 0x02},	/*      = 2*/
-	{WRITE_REG_DATA, 0x098C, 0xA40E},	/*Stat_max*/
-	{WRITE_REG_DATA, 0x0990, 0x03},	/*      = 3*/
-	{WRITE_REG_DATA, 0x098C, 0xA410},	/*Min_amplitude*/
-	{WRITE_REG_DATA, 0x0990, 0x0A},	/*      = 10*/
-
-	{WRITE_REG_DATA, 0x098C, 0xa103},
-	{WRITE_REG_DATA, 0x0990, 0x0006},
-	{POLL_VAR_DATA, 0xa103, 0x0000},
-	{WRITE_REG_DATA, 0x098C, 0xa103},
-	{WRITE_REG_DATA, 0x0990, 0x0005},
-	{POLL_VAR_DATA, 0xa103, 0x0000},
-
-	{WRITE_REG_DATA, 0x098C, 0xA115},
+	{WRITE_REG_DATA, 0x98C, 0x2703},	/*Output Width (A)*/
+	{WRITE_REG_DATA, 0x990, 0x0500},	/*      = 1280*/
+	{WRITE_REG_DATA, 0x98C, 0x2705},	/*Output Height (A)*/
+	{WRITE_REG_DATA, 0x990, 0x02D0},	/*      = 720*/
+	{WRITE_REG_DATA, 0x98C, 0x270D},	/*Row Start (A)*/
+	{WRITE_REG_DATA, 0x990, 0x00F6},	/*      = 246*/
+	{WRITE_REG_DATA, 0x98C, 0x270F},	/*Column Start (A)*/
+	{WRITE_REG_DATA, 0x990, 0x00A6},	/*      = 166*/
+	{WRITE_REG_DATA, 0x98C, 0x2711},	/*Row End (A)*/
+	{WRITE_REG_DATA, 0x990, 0x03CD},	/*      = 973*/
+	{WRITE_REG_DATA, 0x98C, 0x2713},	/*Column End (A)*/
+	{WRITE_REG_DATA, 0x990, 0x05AD},	/*      = 1453*/
+	{WRITE_REG_DATA, 0x98C, 0x2715},	/*Row Speed (A)*/
+	{WRITE_REG_DATA, 0x990, 0x0111},	/*      = 273*/
+	{WRITE_REG_DATA, 0x98C, 0x2717},	/*Read Mode (A)*/
+	{WRITE_REG_DATA, 0x990, 0x0024},	/*      = 36*/
+	{WRITE_REG_DATA, 0x98C, 0x2719},	/*_fine_correction (A)*/
+	{WRITE_REG_DATA, 0x990, 0x003A},	/*      = 58*/
+	{WRITE_REG_DATA, 0x98C, 0x271B},	/*fine_IT_min (A)*/
+	{WRITE_REG_DATA, 0x990, 0x00F6},	/*      = 246*/
+	{WRITE_REG_DATA, 0x98C, 0x271D},	/*fine_IT_max_mrgn (A)*/
+	{WRITE_REG_DATA, 0x990, 0x008B},	/*      = 139*/
+	{WRITE_REG_DATA, 0x98C, 0x271F},	/*Frame Lines (A)*/
+	{WRITE_REG_DATA, 0x990, 0x032D},	/*      = 813*/
+	{WRITE_REG_DATA, 0x98C, 0x2721},	/*Line Length (A)*/
+	{WRITE_REG_DATA, 0x990, 0x06BA},	/*      = 1722*/
+	{WRITE_REG_DATA, 0x98C, 0x2739},	/*Crop_X0 (A)*/
+	{WRITE_REG_DATA, 0x990, 0x0000},	/*      = 0*/
+	{WRITE_REG_DATA, 0x98C, 0x273B},	/*Crop_X1 (A)*/
+	{WRITE_REG_DATA, 0x990, 0x04FF},	/*      = 1279*/
+	{WRITE_REG_DATA, 0x98C, 0x273D},	/*Crop_Y0 (A)*/
+	{WRITE_REG_DATA, 0x990, 0x0000},	/*      = 0*/
+	{WRITE_REG_DATA, 0x98C, 0x273F},	/*Crop_Y1 (A)*/
+	{WRITE_REG_DATA, 0x990, 0x02CF},	/*      = 719*/
+	{WRITE_REG_DATA, 0x98C, 0x2747},	/*Crop_X0 (B)*/
+	{WRITE_REG_DATA, 0x990, 0x0000},	/*      = 0*/
+	{WRITE_REG_DATA, 0x98C, 0x2749},	/*Crop_X1 (B)*/
+	{WRITE_REG_DATA, 0x990, 0x063F},	/*      = 1599*/
+	{WRITE_REG_DATA, 0x98C, 0x274B},	/*Crop_Y0 (B)*/
+	{WRITE_REG_DATA, 0x990, 0x0000},	/*      = 0*/
+	{WRITE_REG_DATA, 0x98C, 0x274D},	/*Crop_Y1 (B)*/
+	{WRITE_REG_DATA, 0x990, 0x04AF},	/*      = 1199*/
+	{WRITE_REG_DATA, 0x98C, 0x222D},	/*R9 Step*/
+	{WRITE_REG_DATA, 0x990, 0x00CB},	/*      = 203*/
+	{WRITE_REG_DATA, 0x98C, 0xA408},	/*search_f1_50*/
+	{WRITE_REG_DATA, 0x990, 0x0031},	/*      = 49*/
+	{WRITE_REG_DATA, 0x98C, 0xA409},	/*search_f2_50*/
+	{WRITE_REG_DATA, 0x990, 0x0033},	/*      = 51*/
+	{WRITE_REG_DATA, 0x98C, 0xA40A},	/*search_f1_60*/
+	{WRITE_REG_DATA, 0x990, 0x003C},	/*      = 60*/
+	{WRITE_REG_DATA, 0x98C, 0xA40B},	/*search_f2_60*/
+	{WRITE_REG_DATA, 0x990, 0x003E},	/*      = 62*/
+	{WRITE_REG_DATA, 0x98C, 0x2411},	/*R9_Step_60 (A)*/
+	{WRITE_REG_DATA, 0x990, 0x00CB},	/*      = 203*/
+	{WRITE_REG_DATA, 0x98C, 0x2413},	/*R9_Step_50 (A)*/
+	{WRITE_REG_DATA, 0x990, 0x00F4},	/*      = 244*/
+	{WRITE_REG_DATA, 0x98C, 0xA404},	/*FD Mode*/
+	{WRITE_REG_DATA, 0x990, 0x0010},	/*      = 16*/
+	{WRITE_REG_DATA, 0x98C, 0xA40D},	/*Stat_min*/
+	{WRITE_REG_DATA, 0x990, 0x0002},	/*      = 2*/
+	{WRITE_REG_DATA, 0x98C, 0xA40E},	/*Stat_max*/
+	{WRITE_REG_DATA, 0x990, 0x0003},	/*      = 3*/
+	{WRITE_REG_DATA, 0x98C, 0xA410},	/*Min_amplitude*/
+	{WRITE_REG_DATA, 0x990, 0x000A},	/*      = 10*/
+	{WRITE_REG_BIT_H, 0x3040, 0x1000},	/* Enable Bin Summing */
+	{WRITE_REG_DATA, 0x098C, 0xA215},	/* Fix FPS */
+	{WRITE_REG_DATA, 0x0990, 0x0003},
+	{WRITE_REG_DATA, 0x098C, 0xA20C},	/* AE_MAX_INDEX */
+	{WRITE_REG_DATA, 0x0990, 0x0004},	/* 30 FPS fixed */
+	{WRITE_REG_DATA, 0x098C, 0xA115},	/* ISP off in cntx B */
 	{WRITE_REG_DATA, 0x0990, 0x0000},
-	{WRITE_REG_DATA, 0x098C, 0xA103},
-	{WRITE_REG_DATA, 0x0990, 0x0001},
-	{WRITE_REG_DATA, 0x098C, 0xA215},
+	{WRITE_REG_DATA, 0x098C, 0xA103},	/* Context A preview */
 	{WRITE_REG_DATA, 0x0990, 0x0001},
+	{POLL_VAR_DATA, 0xa104, 0x0003},
 	{REG_TABLE_END, 0x0000, 0x0000}
 };
 
@@ -290,13 +332,34 @@ static struct soc2030_regs mode_1280x720[] = {
  */
 static struct soc2030_regs pll_table[] = {
 	{WRITE_REG_DATA, 0x001e, 0x0503},	/*Pad Slew rate*/
-	{WRITE_REG_DATA, 0x0014, 0x21F9},	/*PLL_CONTROL*/
-	{WRITE_REG_DATA, 0x0010, 0x011B},	/*PLL_DIVIDERS*/
+	{WRITE_REG_DATA, 0x0014, 0x2545},	/*PLL_CONTROL*/
+	{WRITE_REG_DATA, 0x0010, 0x011C},	/*PLL_DIVIDERS*/
 	{WRITE_REG_DATA, 0x0012, 0x10F7},	/*PLL_P_DIVIDERS*/
-	{WRITE_REG_DATA, 0x0014, 0x21FB},	/*PLL_CONTROL*/
-	{WRITE_REG_DATA, 0x0014, 0x20FB},	/*PLL_CONTROL*/
+	{WRITE_REG_DATA, 0x0014, 0x2547},	/*PLL_CONTROL*/
+	{WRITE_REG_DATA, 0x0014, 0x2447},	/*PLL_CONTROL*/
+	{DELAY_MS, 0x0000, 0x0010},		/*wait for pll lck*/
+	{WRITE_REG_DATA, 0x0014, 0x2047},	/*PLL_CONTROL*/
+	{WRITE_REG_BIT_L, 0x0014, 0x0001},	/*enable the pll*/
+	{WRITE_REG_BIT_H, 0x001a, 0x0200},	/*en parallel out*/
+	{WRITE_REG_BIT_L, 0x001a, 0x0004},	/*disable mipi*/
+	{WRITE_REG_BIT_H, 0x0018, 0x0004},	/*disable mcu*/
+	{WRITE_REG_BIT_L, 0x0018, 0x0001},	/*leave standby*/
+	{POLL_REG_BIT_L, 0x0018, 0x4000},	/*wait for !stdby*/
+	{WRITE_REG_DATA, 0x321C, 0x0000},	/*By Pass TxFIFO = 0*/
 	{REG_TABLE_END, 0x0000, 0x0000}
+};
 
+/*
+ * SetMode Sequence for errata. Phase 0. Sensor Dependent.
+ * This is usually given by the FAE or the sensor vendor.
+ */
+static struct soc2030_regs WakeMcuSequence[] = {
+	{WRITE_VAR_DATA, 0x2755, 0x0200},	/*Invert Pclk*/
+	{WRITE_VAR_DATA, 0x2757, 0x0200},	/*Invert Pclk*/
+	{WRITE_REG_BIT_L, 0x0018, 0x0004},	/*enable the MCU*/
+	{POLL_VAR_DATA, 0xa104, 0x0003},	/*wait for preview*/
+	{POLL_REG_BIT_L, 0x0018, 0x4000},	/*wait for !stdby*/
+	{REG_TABLE_END, 0x0000, 0x0000}
 };
 
 /*
@@ -554,6 +617,140 @@ static struct soc2030_regs SetRev3PatchSequence[] = {
 	{REG_TABLE_END, 0x0000, 0x0000}
 };
 
+/*
+ * Stock AWB CCM from Aptina Demo2 Dev kit.
+ */
+static struct soc2030_regs WbAutoSequence[] = {
+	{WRITE_REG_DATA, 0x098C, 0x2306},	/* [AWB_CCM_L_0] */
+	{WRITE_REG_DATA, 0x0990, 0x0180},	/* MCU_DATA_0 */
+	{WRITE_REG_DATA, 0x098C, 0x2308},	/* [AWB_CCM_L_1] */
+	{WRITE_REG_DATA, 0x0990, 0xFF00},	/* MCU_DATA_0 */
+	{WRITE_REG_DATA, 0x098C, 0x230A},	/* [AWB_CCM_L_2] */
+	{WRITE_REG_DATA, 0x0990, 0x0080},	/* MCU_DATA_0 */
+	{WRITE_REG_DATA, 0x098C, 0x230C},	/* [AWB_CCM_L_3] */
+	{WRITE_REG_DATA, 0x0990, 0xFF66},	/* MCU_DATA_0 */
+	{WRITE_REG_DATA, 0x098C, 0x230E},	/* [AWB_CCM_L_4] */
+	{WRITE_REG_DATA, 0x0990, 0x0180},	/* MCU_DATA_0 */
+	{WRITE_REG_DATA, 0x098C, 0x2310},	/* [AWB_CCM_L_5] */
+	{WRITE_REG_DATA, 0x0990, 0xFFEE},	/* MCU_DATA_0 */
+	{WRITE_REG_DATA, 0x098C, 0x2312},	/* [AWB_CCM_L_6] */
+	{WRITE_REG_DATA, 0x0990, 0xFFCD},	/* MCU_DATA_0 */
+	{WRITE_REG_DATA, 0x098C, 0x2314},	/* [AWB_CCM_L_7] */
+	{WRITE_REG_DATA, 0x0990, 0xFECD},	/* MCU_DATA_0 */
+	{WRITE_REG_DATA, 0x098C, 0x2316},	/* [AWB_CCM_L_8] */
+	{WRITE_REG_DATA, 0x0990, 0x019A},	/* MCU_DATA_0 */
+	{WRITE_REG_DATA, 0x098C, 0x2318},	/* [AWB_CCM_L_9] */
+	{WRITE_REG_DATA, 0x0990, 0x0020},	/* MCU_DATA_0 */
+	{WRITE_REG_DATA, 0x098C, 0x231A},	/* [AWB_CCM_L_10] */
+	{WRITE_REG_DATA, 0x0990, 0x0033},	/* MCU_DATA_0 */
+	{WRITE_REG_DATA, 0x098C, 0x231C},	/* [AWB_CCM_RL_0] */
+	{WRITE_REG_DATA, 0x0990, 0x0100},	/* MCU_DATA_0 */
+	{WRITE_REG_DATA, 0x098C, 0x231E},	/* [AWB_CCM_RL_1] */
+	{WRITE_REG_DATA, 0x0990, 0xFF9A},	/* MCU_DATA_0 */
+	{WRITE_REG_DATA, 0x098C, 0x2320},	/* [AWB_CCM_RL_2] */
+	{WRITE_REG_DATA, 0x0990, 0x0000},	/* MCU_DATA_0 */
+	{WRITE_REG_DATA, 0x098C, 0x2322},	/* [AWB_CCM_RL_3] */
+	{WRITE_REG_DATA, 0x0990, 0x004D},	/* MCU_DATA_0 */
+	{WRITE_REG_DATA, 0x098C, 0x2324},	/* [AWB_CCM_RL_4] */
+	{WRITE_REG_DATA, 0x0990, 0xFFCD},	/* MCU_DATA_0 */
+	{WRITE_REG_DATA, 0x098C, 0x2326},	/* [AWB_CCM_RL_5] */
+	{WRITE_REG_DATA, 0x0990, 0xFFB8},	/* MCU_DATA_0 */
+	{WRITE_REG_DATA, 0x098C, 0x2328},	/* [AWB_CCM_RL_6] */
+	{WRITE_REG_DATA, 0x0990, 0x004D},	/* MCU_DATA_0 */
+	{WRITE_REG_DATA, 0x098C, 0x232A},	/* [AWB_CCM_RL_7] */
+	{WRITE_REG_DATA, 0x0990, 0x0080},	/* MCU_DATA_0 */
+	{WRITE_REG_DATA, 0x098C, 0x232C},	/* [AWB_CCM_RL_8] */
+	{WRITE_REG_DATA, 0x0990, 0xFF66},	/* MCU_DATA_0 */
+	{WRITE_REG_DATA, 0x098C, 0x232E},	/* [AWB_CCM_RL_9] */
+	{WRITE_REG_DATA, 0x0990, 0x0008},	/* MCU_DATA_0 */
+	{WRITE_REG_DATA, 0x098C, 0x2330},	/* [AWB_CCM_RL_10] */
+	{WRITE_REG_DATA, 0x0990, 0xFFF7},	/* MCU_DATA_0 */
+	{REG_TABLE_END, 0x0000, 0x0000}
+};
+
+static struct soc2030_regs WbIncandescentSequence[] = {
+	{REG_TABLE_END, 0x0000, 0x0000}
+};
+
+static struct soc2030_regs WbFluorescentSequence[] = {
+	{REG_TABLE_END, 0x0000, 0x0000}
+};
+
+static struct soc2030_regs WbDaylightSequence[] = {
+	{REG_TABLE_END, 0x0000, 0x0000}
+};
+
+static struct soc2030_regs WbCloudydaylightSequence[] = {
+	{REG_TABLE_END, 0x0000, 0x0000}
+};
+
+static struct soc2030_regs WbNightSequence[] = {
+	{REG_TABLE_END, 0x0000, 0x0000}
+};
+
+static struct soc2030_regs *wb_table[] = {
+	[WB_AUTO] = WbAutoSequence,
+	[WB_INCANDESCENT] = WbIncandescentSequence,
+	[WB_FLUORESCENT] = WbFluorescentSequence,
+	[WB_DAYLIGHT] = WbDaylightSequence,
+	[WB_CLOUDYDAYLIGHT] = WbCloudydaylightSequence,
+	[WB_NIGHT] = WbNightSequence,
+};
+
+static struct soc2030_regs EffectNoneSequence[] = {
+	{WRITE_VAR_DATA, 0x2759, 0x6440},	/*EFFECTS_A*/
+	{WRITE_VAR_DATA, 0x275B, 0x6440},	/*EFFECTS_B*/
+	{REG_TABLE_END, 0x0000, 0x0000}
+};
+
+static struct soc2030_regs EffectBwSequence[] = {
+	{WRITE_VAR_DATA, 0x2759, 0x6441},	/*EFFECTS_A*/
+	{WRITE_VAR_DATA, 0x275B, 0x6441},	/*EFFECTS_B*/
+	{REG_TABLE_END, 0x0000, 0x0000}
+};
+
+static struct soc2030_regs EffectNegativeSequence[] = {
+	{WRITE_VAR_DATA, 0x2759, 0x6443},	/*EFFECTS_A*/
+	{WRITE_VAR_DATA, 0x275B, 0x6443},	/*EFFECTS_B*/
+	{REG_TABLE_END, 0x0000, 0x0000}
+};
+
+static struct soc2030_regs EffectPosterizeSequence[] = {
+	{WRITE_VAR_DATA, 0x2759, 0x2044},	/*EFFECTS_A*/
+	{WRITE_VAR_DATA, 0x275B, 0x2044},	/*EFFECTS_B*/
+	{REG_TABLE_END, 0x0000, 0x0000}
+};
+
+static struct soc2030_regs EffectSepiaSequence[] = {
+	{WRITE_VAR_DATA, 0x2759, 0x6442},	/*EFFECTS_A*/
+	{WRITE_VAR_DATA, 0x275B, 0x6442},	/*EFFECTS_B*/
+	{WRITE_VAR_DATA, 0x2763, 0xB023},
+	{REG_TABLE_END, 0x0000, 0x0000}
+};
+
+static struct soc2030_regs EffectSolarizeSequence[] = {
+	{WRITE_VAR_DATA, 0x2759, 0x4444},	/*EFFECTS_A*/
+	{WRITE_VAR_DATA, 0x275B, 0x4444},	/*EFFECTS_B*/
+	{REG_TABLE_END, 0x0000, 0x0000}
+};
+
+static struct soc2030_regs EffectAquaSequence[] = {
+	{WRITE_VAR_DATA, 0x2759, 0x6442},	/*EFFECTS_A*/
+	{WRITE_VAR_DATA, 0x275B, 0x6442},	/*EFFECTS_B*/
+	{WRITE_VAR_DATA, 0x2763, 0x1DE3},
+	{REG_TABLE_END, 0x0000, 0x0000}
+};
+
+static struct soc2030_regs *effect_table[] = {
+	[EFFECT_NONE] = EffectNoneSequence,
+	[EFFECT_BW] = EffectBwSequence,
+	[EFFECT_NEGATIVE] = EffectNegativeSequence,
+	[EFFECT_POSTERIZE] = EffectPosterizeSequence,
+	[EFFECT_SEPIA] = EffectSepiaSequence,
+	[EFFECT_SOLARIZE] = EffectSolarizeSequence,
+	[EFFECT_AQUA] = EffectAquaSequence,
+};
+
 static struct soc2030_mode modes[] = {
 	{800, 600, 30, mode_800x600},
 	{1600, 1200, 15, mode_1600x1200},
@@ -718,8 +915,11 @@ static int soc2030_poll_xdma_reg(struct i2c_client *client, u16 addr,
 		err = soc2030_read_xdma_reg(client, addr, &val);
 		if (err)
 			return err;
-		if (expected == val)
+		if (expected == val) {
+			pr_info("poll success %x: %x == %x\n", addr,
+				expected, val);
 			return 0;
+		}
 		msleep(SOC2030_POLL_WAITMS);
 	}
 	pr_err("soc2030: xdma poll for %x == ([%x]=%x) failed\n", expected,
@@ -784,6 +984,14 @@ static int soc2030_write_table(struct i2c_client *client,
 				return err;
 			break;
 		}
+		case WRITE_VAR_DATA:
+		{
+			err = soc2030_write_xdma_reg(client, next->addr,
+				next->val);
+			if (err)
+				return err;
+			break;
+		}
 		case POLL_VAR_DATA:
 		{
 			err = soc2030_poll_xdma_reg(client, next->addr,
@@ -798,6 +1006,8 @@ static int soc2030_write_table(struct i2c_client *client,
 			break;
 		}
 		default:
+			pr_err("%s: invalid operation 0x%x\n", __func__,
+				next->op);
 			return err;
 		}
 	}
@@ -825,96 +1035,74 @@ static int soc2030_set_mode(struct soc2030_info *info,
 	}
 	sensor_mode = index;
 
-	/* write the pll table */
-	soc2030_write_table(info->i2c_client, pll_table);
+	if (info->mode == -1) {
 
-	/* wait for pll lock */
-	err = soc2030_poll_bit_set(info->i2c_client, 0x0014, 0x8000);
-	if (err)
-		return err;
+		/* write the pll table */
+		soc2030_write_table(info->i2c_client, pll_table);
 
-	/* enable the pll */
-	soc2030_clear_bits(info->i2c_client, 0x0014, 0x0001);
-	/* enable parallel output */
-	soc2030_set_bits(info->i2c_client, 0x001a, 0x200);
-	/* disable mipi */
-	soc2030_clear_bits(info->i2c_client, 0x001a, 0x4);
-	/* disable mcu */
-	soc2030_set_bits(info->i2c_client, 0x0018, 0x4);
-	/* leave standby */
-	soc2030_clear_bits(info->i2c_client, 0x0018, 0x1);
-	/* wait to complete leave standby */
-	soc2030_poll_bit_clear(info->i2c_client, 0x0018, 0x4000);
-
-	err = soc2030_write_table(info->i2c_client, base_mode);
-	if (err)
-		return err;
+		err = soc2030_write_table(info->i2c_client, base_mode);
+		if (err)
+			return err;
 
-	/* load errata settings */
-	err = soc2030_write_table(info->i2c_client, SetRev2ErrataSequence);
-	if (err)
-		return err;
+		/* load errata settings */
+		err = soc2030_write_table(info->i2c_client,
+						SetRev2ErrataSequence);
+		if (err)
+			return err;
 
-	/* load lens correction */
-	err = soc2030_write_table(info->i2c_client, SetLensCorrectionSequence);
-	if (err)
-		return err;
+		/* load lens correction */
+		err = soc2030_write_table(info->i2c_client,
+						SetLensCorrectionSequence);
+		if (err)
+			return err;
 
-	/* low light optimization settings */
-	err = soc2030_write_table(info->i2c_client, SetLowLightSequence);
-	if (err)
-		return err;
+		/* low light optimization settings */
+		err = soc2030_write_table(info->i2c_client,
+						SetLowLightSequence);
+		if (err)
+			return err;
 
-	/* Base denoise settings (for all resolutions) */
-	err = soc2030_write_table(info->i2c_client, SetDenoiseSequence);
-	if (err)
-		return err;
+		/* Base denoise settings (for all resolutions) */
+		err = soc2030_write_table(info->i2c_client,
+						SetDenoiseSequence);
+		if (err)
+			return err;
 
-	/* white balance common settings */
-	err = soc2030_write_table(info->i2c_client, SetCCMCommonSequence);
-	if (err)
-		return err;
+		/* white balance common settings */
+		err = soc2030_write_table(info->i2c_client,
+						SetCCMCommonSequence);
+		if (err)
+			return err;
+
+		/* auto white balance settings */
+		err = soc2030_write_table(info->i2c_client,
+						SetCCMAutoSequence);
+		if (err)
+			return err;
 
-	/* auto white balance settings */
-	err = soc2030_write_table(info->i2c_client, SetCCMAutoSequence);
+		/* load patch */
+		err = soc2030_write_table(info->i2c_client,
+						SetRev3PatchSequence);
+		if (err)
+			return err;
+
+		/* Wake MCU */
+		err = soc2030_write_table(info->i2c_client,
+						WakeMcuSequence);
+		if (err)
+			return err;
+	}
+
+	/* set context */
+	err = soc2030_write_table(info->i2c_client, modes[sensor_mode].regset);
 	if (err)
 		return err;
 
-	/* load patch */
-	err = soc2030_write_table(info->i2c_client, SetRev3PatchSequence);
+	err = soc2030_write_table(info->i2c_client, refresh_mode);
 	if (err)
 		return err;
 
-	/* invert the pixel clock */
-	soc2030_write_xdma_reg(info->i2c_client, 0x2755, 0x0200);
-	soc2030_write_xdma_reg(info->i2c_client, 0x2757, 0x0200);
-
-	/* enable mcu */
-	soc2030_clear_bits(info->i2c_client, 0x0018, 0x4);
-
-	/* wait for preview state */
-	soc2030_poll_xdma_reg(info->i2c_client, 0xa104, 0x3);
-
-	/* refresh the sequencer mode */
-	soc2030_write_xdma_reg(info->i2c_client, 0xa103, 0x0006);
-
-	/* wait for cmd complete */
-	soc2030_poll_xdma_reg(info->i2c_client, 0xa103, 0x0);
-
-	/* refresh sequencer state */
-	soc2030_write_xdma_reg(info->i2c_client, 0xa103, 0x0005);
-
-	/* wait for cmd complete */
-	soc2030_poll_xdma_reg(info->i2c_client, 0xa103, 0x0);
-
-	/* wait to complete leave standby */
-	soc2030_poll_bit_clear(info->i2c_client, 0x0018, 0x4000);
-
-	/* enable bin summing for preview */
-	soc2030_set_bits(info->i2c_client, 0x3040, 0x1000);
-
-	/* set context */
-	err = soc2030_write_table(info->i2c_client, modes[sensor_mode].regset);
+	err = soc2030_write_table(info->i2c_client, refresh_state);
 	if (err)
 		return err;
 
@@ -922,6 +1110,7 @@ static int soc2030_set_mode(struct soc2030_info *info,
 	return 0;
 }
 
+
 static int soc2030_get_status(struct soc2030_info *info, u16 *status)
 {
 	int err;
@@ -1026,6 +1215,99 @@ static long soc2030_ioctl(struct file *file,
 		}
 		return 0;
 	}
+	case SOC2030_IOCTL_SET_EFFECT:
+	{
+		int err;
+
+		if ((unsigned int)arg >= EFFECT_MAX)
+			return -EINVAL;
+		err = soc2030_write_table(info->i2c_client,
+				effect_table[(unsigned int)arg]);
+		if (err)
+			return -EFAULT;
+		err = soc2030_write_table(info->i2c_client, refresh_state);
+		if (err)
+			return -EFAULT;
+		return 0;
+	}
+	case SOC2030_IOCTL_SET_WHITEBALANCE:
+	{
+		int err;
+
+		if ((unsigned int)arg >= WB_MAX)
+			return -EINVAL;
+
+		/* Re-set context, this insures MAX AE Index is set correctly */
+		/* As night mode may have been previously set */
+		err = soc2030_write_table(info->i2c_client,
+				modes[info->mode].regset);
+		if (err)
+			return -EFAULT;
+
+		err = soc2030_write_table(info->i2c_client,
+				SetCCMCommonSequence);
+		if (err)
+			return -EFAULT;
+		err = soc2030_write_table(info->i2c_client,
+				wb_table[(unsigned int)arg]);
+		if (err)
+			return -EFAULT;
+		return 0;
+	}
+
+	case SOC2030_IOCTL_SET_EXP_COMP:
+	{
+		int err;
+		int req_ev = (int)arg;
+		int step;
+		int step_size = 0;
+		int ev_step = 0;
+		int new_target = EXP_TARGET;
+
+		if ((req_ev > SOC_EV_MAX) || (req_ev < SOC_EV_MIN)) {
+			pr_err("%s: Invalid exposure parameter %i\n",
+				__func__, req_ev);
+			return -EINVAL;
+		}
+
+		if (req_ev < 0) {
+			ev_step = -EXP_TARGET;
+			/* step a little less than 1 f-stop */
+			step_size = 2;
+		} else if (req_ev > 0) {
+			ev_step = 0x100 - EXP_TARGET;
+			/* step 1/2  f-stop */
+			step_size = 4;
+		}
+
+		new_target = EXP_TARGET;
+
+		/* adjust exposure target by 1 f-stop for each requested step */
+		for (step = 1; step <= abs(req_ev); step++) {
+			ev_step /= step_size;
+			new_target += ev_step;
+		}
+		if (new_target < 0) {
+			pr_err("%s: Bad exposure target %i (0x%x)\n",
+				__func__, new_target,
+			       (u16)new_target);
+			return -EFAULT;
+		}
+
+		err = soc2030_write_xdma_reg(info->i2c_client,
+						0xA24F, (u16)new_target);
+		if (err) {
+			pr_err("%s: Failed to update EV parameter\n", __func__);
+			return -EFAULT;
+		}
+		err = soc2030_write_table(info->i2c_client, refresh_state);
+		if (err) {
+			pr_err("%s: Failed to update EV parameter\n", __func__);
+			return -EFAULT;
+		}
+		return 0;
+	}
+
 	default:
 		return -ENOTTY;
 	}
@@ -1036,6 +1318,7 @@ static struct soc2030_info *info;
 
 static int soc2030_open(struct inode *inode, struct file *file)
 {
+	info->mode = -1;
 	file->private_data = info;
 	if (info->pdata && info->pdata->power_on)
 		info->pdata->power_on();
@@ -1086,7 +1369,6 @@ static int soc2030_probe(struct i2c_client *client,
 
 	info->pdata = client->dev.platform_data;
 	info->i2c_client = client;
-
 	i2c_set_clientdata(client, info);
 	return 0;
 }
diff --git a/include/media/soc2030.h b/include/media/soc2030.h
index c7956952e1f0..5b54f87ce89c 100755
--- a/include/media/soc2030.h
+++ b/include/media/soc2030.h
@@ -26,12 +26,20 @@
 #define SOC2030_IOCTL_SET_PRIVATE	_IOWR('o', 3, struct soc2030_regs)
 #define SOC2030_IOCTL_GET_MODES		_IO('o', 4)
 #define SOC2030_IOCTL_GET_NUM_MODES	_IOR('o', 5, unsigned int)
+#define SOC2030_IOCTL_SET_EFFECT	_IOWR('o', 6, unsigned int)
+#define SOC2030_IOCTL_SET_WHITEBALANCE	_IOWR('o', 7, unsigned int)
+#define SOC2030_IOCTL_SET_EXP_COMP	_IOWR('o', 8, int)
 
 #define SOC2030_POLL_WAITMS 50
 #define SOC2030_MAX_RETRIES 3
 #define SOC2030_POLL_RETRIES 5
 
 #define SOC2030_MAX_PRIVATE_SIZE 1024
+#define SOC2030_MAX_NUM_MODES 6
+
+#define SOC_EV_MAX 2
+#define SOC_EV_MIN -2
+#define EXP_TARGET 0x32
 
 enum {
 	REG_TABLE_END,
@@ -41,10 +49,32 @@ enum {
 	POLL_REG_DATA,
 	POLL_REG_BIT_H,
 	POLL_REG_BIT_L,
+	WRITE_VAR_DATA,
 	POLL_VAR_DATA,
 	DELAY_MS,
 };
 
+enum {
+	EFFECT_NONE,
+	EFFECT_BW,
+	EFFECT_NEGATIVE,
+	EFFECT_POSTERIZE,
+	EFFECT_SEPIA,
+	EFFECT_SOLARIZE,
+	EFFECT_AQUA,
+	EFFECT_MAX,
+};
+
+enum {
+	WB_AUTO,
+	WB_INCANDESCENT,
+	WB_FLUORESCENT,
+	WB_DAYLIGHT,
+	WB_CLOUDYDAYLIGHT,
+	WB_NIGHT,
+	WB_MAX,
+};
+
 struct soc2030_regs {
 	__u8 op;
 	__u16 addr;