From 9370bb92b2d16684ee45cf24e879c93c509162da Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Thu, 19 Dec 2024 01:47:39 +0000
Subject: [PATCH] add wifi6 8852be driver

---
 kernel/drivers/media/i2c/nvp6188.c | 1680 +++++++++++++++++++++++++++++++++++------------------------
 1 files changed, 1,006 insertions(+), 674 deletions(-)

diff --git a/kernel/drivers/media/i2c/nvp6188.c b/kernel/drivers/media/i2c/nvp6188.c
index dc32e88..36cf018 100644
--- a/kernel/drivers/media/i2c/nvp6188.c
+++ b/kernel/drivers/media/i2c/nvp6188.c
@@ -10,9 +10,11 @@
  *  2. add get virtual channel hotplug status ioctl
  *  3. add virtual channel hotplug status event report to vicap
  *  4. fixup variables are reused when multiple devices use the same driver
- * V0.0X02.0x00 version.
- *  1,support auto detect format when plugging
- *  2,support quick stream when reset vicap
+ * V0.0X02.0X00 version.
+ *  1. update init registers setting
+ *  2. nvp6188 do not stream after writing registers setting
+ *  3. support detect fmt change when hotplug ahd camera
+ *  4. support 1600x1300 ahd camera input
  */
 
 //#define DEBUG
@@ -36,15 +38,14 @@
 #include <linux/rk-preisp.h>
 #include <linux/sched.h>
 #include <linux/kthread.h>
-
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include <sound/tlv.h>
-
 #include <linux/platform_device.h>
 #include <linux/input.h>
+#include "nvp6188.h"
 
 #define DRIVER_VERSION				KERNEL_VERSION(0, 0x02, 0x0)
 
@@ -80,21 +81,15 @@
 #endif
 
 #define NVP_RESO_960H_NSTC_VALUE	0x00
-#define NVP_RESO_960H_PAL_VALUE	0x10
+#define NVP_RESO_960H_PAL_VALUE		0x10
 #define NVP_RESO_720P_NSTC_VALUE	0x20
-#define NVP_RESO_720P_PAL_VALUE	0x21
+#define NVP_RESO_720P_PAL_VALUE		0x21
 #define NVP_RESO_1080P_NSTC_VALUE	0x30
 #define NVP_RESO_1080P_PAL_VALUE	0x31
 #define NVP_RESO_960P_NSTC_VALUE	0xa0
-#define NVP_RESO_960P_PAL_VALUE	0xa1
-
-enum nvp6188_max_pad {
-	PAD0,
-	PAD1,
-	PAD2,
-	PAD3,
-	PAD_MAX,
-};
+#define NVP_RESO_960P_PAL_VALUE		0xa1
+#define NVP_RESO_1300P_NSTC_VALUE	0x3A
+#define NVP_RESO_1300P_PAL_VALUE	0x3B
 
 enum nvp6188_support_reso {
 	NVP_RESO_UNKOWN = 0,
@@ -102,10 +97,12 @@
 	NVP_RESO_720P_PAL,
 	NVP_RESO_960P_PAL,
 	NVP_RESO_1080P_PAL,
+	NVP_RESO_1300P_PAL,
 	NVP_RESO_960H_NSTC,
 	NVP_RESO_720P_NSTC,
 	NVP_RESO_960P_NSTC,
 	NVP_RESO_1080P_NSTC,
+	NVP_RESO_1300P_NSTC,
 };
 
 /* Audio output port formats */
@@ -133,6 +130,7 @@
 	u32 hdr_mode;
 	u32 vc[PAD_MAX];
 	u32 channel_reso[PAD_MAX];
+	u32 unkown_reso_count[PAD_MAX];
 };
 
 struct nvp6188_audio {
@@ -146,11 +144,9 @@
 	struct gpio_desc	*reset_gpio;
 	struct gpio_desc	*power_gpio;
 	struct gpio_desc	*vi_gpio;
-
 	struct pinctrl		*pinctrl;
 	struct pinctrl_state	*pins_default;
 	struct pinctrl_state	*pins_sleep;
-
 	struct v4l2_subdev	subdev;
 	struct media_pad	pad;
 	struct v4l2_ctrl_handler ctrl_handler;
@@ -159,23 +155,20 @@
 	struct mutex		mutex;
 	bool			power_on;
 	struct nvp6188_mode cur_mode;
-
 	u32			module_index;
 	u32			cfg_num;
 	const char		*module_facing;
 	const char		*module_name;
 	const char		*len_name;
-
 	struct nvp6188_audio *audio_in;
 	struct nvp6188_audio *audio_out;
-
 	int streaming;
-
 	struct task_struct *detect_thread;
 	struct input_dev* input_dev;
 	unsigned char detect_status;
 	unsigned char last_detect_status;
 	u8 is_reset;
+	bool disable_dump_register;
 };
 
 #define to_nvp6188(sd) container_of(sd, struct nvp6188, subdev)
@@ -192,489 +185,619 @@
 	struct i2c_client *client = to_i2c_client(dev);
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
 	struct nvp6188 *nvp6188 = to_nvp6188(sd);
+
 	return sprintf(buf, "%d\n", nvp6188->detect_status);
 }
 
-static DEVICE_ATTR(hotplug_status, 0644, show_hotplug_status, NULL);
+static ssize_t nvp6188_debug_func(struct device *dev,
+				  struct device_attribute *attr,
+				  char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct nvp6188 *nvp6188 = to_nvp6188(sd);
+
+	nvp6188->disable_dump_register = (nvp6188->disable_dump_register) ? false : true;
+	return sprintf(buf, "switch disable_dump_register(%d)\n", nvp6188->disable_dump_register);
+}
+
+static DEVICE_ATTR(hotplug_status, S_IRUSR, show_hotplug_status, NULL);
+static DEVICE_ATTR(nvp6188_debug, S_IRUSR, nvp6188_debug_func, NULL);
 static struct attribute *dev_attrs[] = {
 	&dev_attr_hotplug_status.attr,
+	&dev_attr_nvp6188_debug.attr,
 	NULL,
 };
+
 static struct attribute_group dev_attr_grp = {
 	.attrs = dev_attrs,
 };
 
 static __maybe_unused const struct regval common_setting_756M_regs[] = {
-	{ 0xff, 0x00 },
-	{ 0x80, 0x0f },
-	{ 0x00, 0x10 },
-	{ 0x01, 0x10 },
-	{ 0x02, 0x10 },
-	{ 0x03, 0x10 },
-	{ 0x22, 0x0b },
-	{ 0x23, 0x41 },
-	{ 0x26, 0x0b },
-	{ 0x27, 0x41 },
-	{ 0x2a, 0x0b },
-	{ 0x2b, 0x41 },
-	{ 0x2e, 0x0b },
-	{ 0x2f, 0x41 },
+	{0xff, 0x00},
+	{0x80, 0x0f},
+	{0x00, 0x10},
+	{0x01, 0x10},
+	{0x02, 0x10},
+	{0x03, 0x10},
+	{0x22, 0x0b},
+	{0x23, 0x41},
+	{0x26, 0x0b},
+	{0x27, 0x41},
+	{0x2a, 0x0b},
+	{0x2b, 0x41},
+	{0x2e, 0x0b},
+	{0x2f, 0x41},
 
-	{ 0xff, 0x01 },
-	{ 0x98, 0x30 },
-	{ 0xed, 0x00 },
+	{0xff, 0x01},
+	{0x98, 0x30},
+	{0xed, 0x00},
 
-	{ 0xff, 0x05+0 },
-	{ 0x00, 0xd0 },
-	{ 0x01, 0x22 },
-	{ 0x47, 0xee },
-	{ 0x50, 0xc6 },
-	{ 0x57, 0x00 },
-	{ 0x58, 0x77 },
-	{ 0x5b, 0x41 },
-	{ 0x5c, 0x78 },
-	{ 0xB8, 0xB8 },
+	{0xff, 0x05 + 0},
+	{0x00, 0xd0},
+	{0x01, 0x22},
+	{0x47, 0xee},
+	{0x50, 0xc6},
+	{0x57, 0x00},
+	{0x58, 0x77},
+	{0x5b, 0x41},
+	{0x5c, 0x78},
+	{0xB8, 0xB8},
 
-	{ 0xff, 0x05+1 },
-	{ 0x00, 0xd0 },
-	{ 0x01, 0x22 },
-	{ 0x47, 0xee },
-	{ 0x50, 0xc6 },
-	{ 0x57, 0x00 },
-	{ 0x58, 0x77 },
-	{ 0x5b, 0x41 },
-	{ 0x5c, 0x78 },
-	{ 0xB8, 0xB8 },
+	{0xff, 0x05 + 1},
+	{0x00, 0xd0},
+	{0x01, 0x22},
+	{0x47, 0xee},
+	{0x50, 0xc6},
+	{0x57, 0x00},
+	{0x58, 0x77},
+	{0x5b, 0x41},
+	{0x5c, 0x78},
+	{0xB8, 0xB8},
 
-	{ 0xff, 0x05+2 },
-	{ 0x00, 0xd0 },
-	{ 0x01, 0x22 },
-	{ 0x47, 0xee },
-	{ 0x50, 0xc6 },
-	{ 0x57, 0x00 },
-	{ 0x58, 0x77 },
-	{ 0x5b, 0x41 },
-	{ 0x5c, 0x78 },
-	{ 0xB8, 0xB8 },
+	{0xff, 0x05 + 2},
+	{0x00, 0xd0},
+	{0x01, 0x22},
+	{0x47, 0xee},
+	{0x50, 0xc6},
+	{0x57, 0x00},
+	{0x58, 0x77},
+	{0x5b, 0x41},
+	{0x5c, 0x78},
+	{0xB8, 0xB8},
 
-	{ 0xff, 0x05+3 },
-	{ 0x00, 0xd0 },
-	{ 0x01, 0x22 },
-	{ 0x47, 0xee },
-	{ 0x50, 0xc6 },
-	{ 0x57, 0x00 },
-	{ 0x58, 0x77 },
-	{ 0x5b, 0x41 },
-	{ 0x5c, 0x78 },
-	{ 0xB8, 0xB8 },
+	{0xff, 0x05 + 3},
+	{0x00, 0xd0},
+	{0x01, 0x22},
+	{0x47, 0xee},
+	{0x50, 0xc6},
+	{0x57, 0x00},
+	{0x58, 0x77},
+	{0x5b, 0x41},
+	{0x5c, 0x78},
+	{0xB8, 0xB8},
 
-	{ 0xff, 0x09 },
-	{ 0x50, 0x30 },
-	{ 0x51, 0x6f },
-	{ 0x52, 0x67 },
-	{ 0x53, 0x48 },
-	{ 0x54, 0x30 },
-	{ 0x55, 0x6f },
-	{ 0x56, 0x67 },
-	{ 0x57, 0x48 },
-	{ 0x58, 0x30 },
-	{ 0x59, 0x6f },
-	{ 0x5a, 0x67 },
-	{ 0x5b, 0x48 },
-	{ 0x5c, 0x30 },
-	{ 0x5d, 0x6f },
-	{ 0x5e, 0x67 },
-	{ 0x5f, 0x48 },
+	{0xff, 0x09},
+	{0x50, 0x30},
+	{0x51, 0x6f},
+	{0x52, 0x67},
+	{0x53, 0x48},
+	{0x54, 0x30},
+	{0x55, 0x6f},
+	{0x56, 0x67},
+	{0x57, 0x48},
+	{0x58, 0x30},
+	{0x59, 0x6f},
+	{0x5a, 0x67},
+	{0x5b, 0x48},
+	{0x5c, 0x30},
+	{0x5d, 0x6f},
+	{0x5e, 0x67},
+	{0x5f, 0x48},
 
-	{ 0xff, 0x0a },
-	{ 0x25, 0x10 },
-	{ 0x27, 0x1e },
-	{ 0x30, 0xac },
-	{ 0x31, 0x78 },
-	{ 0x32, 0x17 },
-	{ 0x33, 0xc1 },
-	{ 0x34, 0x40 },
-	{ 0x35, 0x00 },
-	{ 0x36, 0xc3 },
-	{ 0x37, 0x0a },
-	{ 0x38, 0x00 },
-	{ 0x39, 0x02 },
-	{ 0x3a, 0x00 },
-	{ 0x3b, 0xb2 },
-	{ 0xa5, 0x10 },
-	{ 0xa7, 0x1e },
-	{ 0xb0, 0xac },
-	{ 0xb1, 0x78 },
-	{ 0xb2, 0x17 },
-	{ 0xb3, 0xc1 },
-	{ 0xb4, 0x40 },
-	{ 0xb5, 0x00 },
-	{ 0xb6, 0xc3 },
-	{ 0xb7, 0x0a },
-	{ 0xb8, 0x00 },
-	{ 0xb9, 0x02 },
-	{ 0xba, 0x00 },
-	{ 0xbb, 0xb2 },
-	{ 0xff, 0x0b },
-	{ 0x25, 0x10 },
-	{ 0x27, 0x1e },
-	{ 0x30, 0xac },
-	{ 0x31, 0x78 },
-	{ 0x32, 0x17 },
-	{ 0x33, 0xc1 },
-	{ 0x34, 0x40 },
-	{ 0x35, 0x00 },
-	{ 0x36, 0xc3 },
-	{ 0x37, 0x0a },
-	{ 0x38, 0x00 },
-	{ 0x39, 0x02 },
-	{ 0x3a, 0x00 },
-	{ 0x3b, 0xb2 },
-	{ 0xa5, 0x10 },
-	{ 0xa7, 0x1e },
-	{ 0xb0, 0xac },
-	{ 0xb1, 0x78 },
-	{ 0xb2, 0x17 },
-	{ 0xb3, 0xc1 },
-	{ 0xb4, 0x40 },
-	{ 0xb5, 0x00 },
-	{ 0xb6, 0xc3 },
-	{ 0xb7, 0x0a },
-	{ 0xb8, 0x00 },
-	{ 0xb9, 0x02 },
-	{ 0xba, 0x00 },
-	{ 0xbb, 0xb2 },
+	{0xff, 0x0a},
+	{0x25, 0x10},
+	{0x27, 0x1e},
+	{0x30, 0xac},
+	{0x31, 0x78},
+	{0x32, 0x17},
+	{0x33, 0xc1},
+	{0x34, 0x40},
+	{0x35, 0x00},
+	{0x36, 0xc3},
+	{0x37, 0x0a},
+	{0x38, 0x00},
+	{0x39, 0x02},
+	{0x3a, 0x00},
+	{0x3b, 0xb2},
+	{0xa5, 0x10},
+	{0xa7, 0x1e},
+	{0xb0, 0xac},
+	{0xb1, 0x78},
+	{0xb2, 0x17},
+	{0xb3, 0xc1},
+	{0xb4, 0x40},
+	{0xb5, 0x00},
+	{0xb6, 0xc3},
+	{0xb7, 0x0a},
+	{0xb8, 0x00},
+	{0xb9, 0x02},
+	{0xba, 0x00},
+	{0xbb, 0xb2},
+	{0xff, 0x0b},
+	{0x25, 0x10},
+	{0x27, 0x1e},
+	{0x30, 0xac},
+	{0x31, 0x78},
+	{0x32, 0x17},
+	{0x33, 0xc1},
+	{0x34, 0x40},
+	{0x35, 0x00},
+	{0x36, 0xc3},
+	{0x37, 0x0a},
+	{0x38, 0x00},
+	{0x39, 0x02},
+	{0x3a, 0x00},
+	{0x3b, 0xb2},
+	{0xa5, 0x10},
+	{0xa7, 0x1e},
+	{0xb0, 0xac},
+	{0xb1, 0x78},
+	{0xb2, 0x17},
+	{0xb3, 0xc1},
+	{0xb4, 0x40},
+	{0xb5, 0x00},
+	{0xb6, 0xc3},
+	{0xb7, 0x0a},
+	{0xb8, 0x00},
+	{0xb9, 0x02},
+	{0xba, 0x00},
+	{0xbb, 0xb2},
 
-	{ 0xff, 0x13 },
-	{ 0x05, 0xa0 },
-	{ 0x31, 0xff },
-	{ 0x07, 0x47 },
-	{ 0x12, 0x04 },
-	{ 0x1e, 0x1f },
-	{ 0x1f, 0x27 },
-	{ 0x2e, 0x10 },
-	{ 0x2f, 0xc8 },
-	{ 0x31, 0xff },
-	{ 0x32, 0x00 },
-	{ 0x33, 0x00 },
-	{ 0x72, 0x05 },
-	{ 0x7a, 0xf0 },
-	{ 0xff, _MAR_BANK_ },
-	{ 0x10, 0xff },
-	{ 0x11, 0xff },
+	{0xff, 0x13},
+	{0x05, 0xa0},
+	{0x31, 0xff},
+	{0x07, 0x47},
+	{0x12, 0x04},
+	{0x1e, 0x1f},
+	{0x1f, 0x27},
+	{0x2e, 0x10},
+	{0x2f, 0xc8},
+	{0x31, 0xff},
+	{0x32, 0x00},
+	{0x33, 0x00},
+	{0x72, 0x05},
+	{0x7a, 0xf0},
+	{0xff, _MAR_BANK_},
+	{0x10, 0xff},
+	{0x11, 0xff},
 
-	{ 0x30, 0x0f },
-	{ 0x32, 0x92 },
-	{ 0x34, 0xcd },
-	{ 0x36, 0x04 },
-	{ 0x38, 0x58 },
+	{0x30, 0x0f},
+	{0x32, 0x92},
+	{0x34, 0xcd},
+	{0x36, 0x04},
+	{0x38, 0x58},
 
-	{ 0x3c, 0x01 },
-	{ 0x3d, 0x11 },
-	{ 0x3e, 0x11 },
-	{ 0x45, 0x60 },
-	{ 0x46, 0x49 },
+	{0x3c, 0x01},
+	{0x3d, 0x11},
+	{0x3e, 0x11},
+	{0x45, 0x60},
+	{0x46, 0x49},
 
-	{ 0xff, _MTX_BANK_ },
-	{ 0xe9, 0x03 },
-	{ 0x03, 0x02 },
-	{ 0x01, 0xe0 },
-	{ 0x00, 0x7d },
-	{ 0x01, 0xe0 },
-	{ 0x02, 0xa0 },
-	{ 0x20, 0x1e },
-	{ 0x20, 0x1f },
+	{0xff, _MTX_BANK_},
+	{0xe9, 0x03},
+	{0x03, 0x02},
+	{0x01, 0xe0},
+	{0x00, 0x7d},
+	{0x01, 0xe0},
+	{0x02, 0xa0},
+	{0x20, 0x1e},
+	{0x20, 0x1f},
 
-	{ 0x04, 0x38 },
-	{ 0x45, 0xc4 },
-	{ 0x46, 0x01 },
-	{ 0x47, 0x1b },
-	{ 0x48, 0x08 },
-	{ 0x65, 0xc4 },
-	{ 0x66, 0x01 },
-	{ 0x67, 0x1b },
-	{ 0x68, 0x08 },
-	{ 0x85, 0xc4 },
-	{ 0x86, 0x01 },
-	{ 0x87, 0x1b },
-	{ 0x88, 0x08 },
-	{ 0xa5, 0xc4 },
-	{ 0xa6, 0x01 },
-	{ 0xa7, 0x1b },
-	{ 0xa8, 0x08 },
-	{ 0xc5, 0xc4 },
-	{ 0xc6, 0x01 },	
-	{ 0xc7, 0x1b },	
-	{ 0xc8, 0x08 },
-	{ 0xeb, 0x8d },
+	{0x04, 0x38},
+	{0x45, 0xc4},
+	{0x46, 0x01},
+	{0x47, 0x1b},
+	{0x48, 0x08},
+	{0x65, 0xc4},
+	{0x66, 0x01},
+	{0x67, 0x1b},
+	{0x68, 0x08},
+	{0x85, 0xc4},
+	{0x86, 0x01},
+	{0x87, 0x1b},
+	{0x88, 0x08},
+	{0xa5, 0xc4},
+	{0xa6, 0x01},
+	{0xa7, 0x1b},
+	{0xa8, 0x08},
+	{0xc5, 0xc4},
+	{0xc6, 0x01},
+	{0xc7, 0x1b},
+	{0xc8, 0x08},
+	{0xeb, 0x8d},
 
-	{ 0xff, _MAR_BANK_ },
-	{ 0x00, 0xff },
-	{ 0x40, 0x01 },
-	{ 0x40, 0x00 },
-	{ 0xff, 0x01 },
-	{ 0x97, 0x00 },
-	{ 0x97, 0x0f },
+	{0xff, _MAR_BANK_},
+	{0x00, 0xff},
+	{0x40, 0x01},
+	{0x40, 0x00},
+	{0xff, 0x01},
+	{0x97, 0x00},
+	{0x97, 0x0f},
 
-	{ 0xff, 0x00 },  //test pattern
-	{ 0x78, 0xba },
-	{ 0x79, 0xac },
-	{ 0xff, 0x05 },
-	{ 0x2c, 0x08 },
-	{ 0x6a, 0x80 },
-	{ 0xff, 0x06 },
-	{ 0x2c, 0x08 },
-	{ 0x6a, 0x80 },
-	{ 0xff, 0x07 },
-	{ 0x2c, 0x08 },
-	{ 0x6a, 0x80 },
-	{ 0xff, 0x08 },
-	{ 0x2c, 0x08 },
-	{ 0x6a, 0x80 },
+	{0xff, 0x00},  //test pattern
+	{0x78, 0xba},
+	{0x79, 0xac},
+	{0xff, 0x05},
+	{0x2c, 0x08},
+	{0x6a, 0x80},
+	{0xff, 0x06},
+	{0x2c, 0x08},
+	{0x6a, 0x80},
+	{0xff, 0x07},
+	{0x2c, 0x08},
+	{0x6a, 0x80},
+	{0xff, 0x08},
+	{0x2c, 0x08},
+	{0x6a, 0x80},
 };
 
 static __maybe_unused const struct regval common_setting_1458M_regs[] = {
-	{ 0xff, 0x00 },
-	{ 0x80, 0x0f },
-	{ 0x00, 0x10 },
-	{ 0x01, 0x10 },
-	{ 0x02, 0x10 },
-	{ 0x03, 0x10 },
-	{ 0x22, 0x0b },
-	{ 0x23, 0x41 },
-	{ 0x26, 0x0b },
-	{ 0x27, 0x41 },
-	{ 0x2a, 0x0b },
-	{ 0x2b, 0x41 },
-	{ 0x2e, 0x0b },
-	{ 0x2f, 0x41 },
+	{0xff, 0x01},
+	{0x80, 0x40},
+	{0x98, 0x30},
+	{0x7a, 0x00},
+	{0xff, _MTX_BANK_},
+	{0xe9, 0x03},
+	{0x03, 0x02},
+	{0x04, 0x6c},
+	{0x08, 0x4f},
+	{0x01, 0xe4},
+	{0x00, 0x7d},
+	{0x01, 0xe0},
+	{0x20, 0x1e},
+	{0x20, 0x1f},
+	{0xeb, 0x8d},
+	{0x45, 0xcd},
+	{0x46, 0x42},
+	{0x47, 0x36},
+	{0x48, 0x0f},
+	{0x65, 0xcd},
+	{0x66, 0x42},
+	{0x67, 0x0e},
+	{0x68, 0x0f},
+	{0x85, 0xcd},
+	{0x86, 0x42},
+	{0x87, 0x0e},
+	{0x88, 0x0f},
+	{0xa5, 0xcd},
+	{0xa6, 0x42},
+	{0xa7, 0x0e},
+	{0xa8, 0x0f},
+	{0xc5, 0xcd},
+	{0xc6, 0x42},
+	{0xc7, 0x0e},
+	{0xc8, 0x0f},
 
-	{ 0xff, 0x01 },
-	{ 0x98, 0x30 },
-	{ 0xed, 0x00 },
+	{0xff, 0x05 + 0},
+	{0x01, 0x62},
+	{0x05, 0x04},
+	{0x08, 0x55},
+	{0x1b, 0x08},
+	{0x25, 0xdc},
+	{0x28, 0x80},
+	{0x2f, 0x00},
+	{0x30, 0xe0},
+	{0x31, 0x43},
+	{0x32, 0xa2},
+	{0x57, 0x00},
+	{0x58, 0x77},
+	{0x5b, 0x41},
+	{0x5c, 0x78},
+	{0x5f, 0x00},
+	{0x7b, 0x11},
+	{0x7c, 0x01},
+	{0x7d, 0x80},
+	{0x80, 0x00},
+	{0x90, 0x01},
+	{0xa9, 0x00},
+	{0xb5, 0x00},
+	{0xb9, 0x72},
+	{0xd1, 0x00},
+	{0xd5, 0x80},
 
-	{ 0xff, 0x05+0 },
-	{ 0x00, 0xd0 },
-	{ 0x01, 0x22 },
-	{ 0x47, 0xee },
-	{ 0x50, 0xc6 },
-	{ 0x57, 0x00 },
-	{ 0x58, 0x77 },
-	{ 0x5b, 0x41 },
-	{ 0x5c, 0x78 },
-	{ 0xB8, 0xB8 },
+	{0xff, 0x05 + 1},
+	{0x01, 0x62},
+	{0x05, 0x04},
+	{0x08, 0x55},
+	{0x1b, 0x08},
+	{0x25, 0xdc},
+	{0x28, 0x80},
+	{0x2f, 0x00},
+	{0x30, 0xe0},
+	{0x31, 0x43},
+	{0x32, 0xa2},
+	{0x57, 0x00},
+	{0x58, 0x77},
+	{0x5b, 0x41},
+	{0x5c, 0x78},
+	{0x5f, 0x00},
+	{0x7b, 0x11},
+	{0x7c, 0x01},
+	{0x7d, 0x80},
+	{0x80, 0x00},
+	{0x90, 0x01},
+	{0xa9, 0x00},
+	{0xb5, 0x00},
+	{0xb9, 0x72},
+	{0xd1, 0x00},
+	{0xd5, 0x80},
 
-	{ 0xff, 0x05+1 },
-	{ 0x00, 0xd0 },
-	{ 0x01, 0x22 },
-	{ 0x47, 0xee },
-	{ 0x50, 0xc6 },
-	{ 0x57, 0x00 },
-	{ 0x58, 0x77 },
-	{ 0x5b, 0x41 },
-	{ 0x5c, 0x78 },
-	{ 0xB8, 0xB8 },
+	{0xff, 0x05 + 2},
+	{0x01, 0x62},
+	{0x05, 0x04},
+	{0x08, 0x55},
+	{0x1b, 0x08},
+	{0x25, 0xdc},
+	{0x28, 0x80},
+	{0x2f, 0x00},
+	{0x30, 0xe0},
+	{0x31, 0x43},
+	{0x32, 0xa2},
+	{0x57, 0x00},
+	{0x58, 0x77},
+	{0x5b, 0x41},
+	{0x5c, 0x78},
+	{0x5f, 0x00},
+	{0x7b, 0x11},
+	{0x7c, 0x01},
+	{0x7d, 0x80},
+	{0x80, 0x00},
+	{0x90, 0x01},
+	{0xa9, 0x00},
+	{0xb5, 0x00},
+	{0xb9, 0x72},
+	{0xd1, 0x00},
+	{0xd5, 0x80},
 
-	{ 0xff, 0x05+2 },
-	{ 0x00, 0xd0 },
-	{ 0x01, 0x22 },
-	{ 0x47, 0xee },
-	{ 0x50, 0xc6 },
-	{ 0x57, 0x00 },
-	{ 0x58, 0x77 },
-	{ 0x5b, 0x41 },
-	{ 0x5c, 0x78 },
-	{ 0xB8, 0xB8 },
+	{0xff, 0x05 + 3},
+	{0x01, 0x62},
+	{0x05, 0x04},
+	{0x08, 0x55},
+	{0x1b, 0x08},
+	{0x25, 0xdc},
+	{0x28, 0x80},
+	{0x2f, 0x00},
+	{0x30, 0xe0},
+	{0x31, 0x43},
+	{0x32, 0xa2},
+	{0x57, 0x00},
+	{0x58, 0x77},
+	{0x5b, 0x41},
+	{0x5c, 0x78},
+	{0x5f, 0x00},
+	{0x7b, 0x11},
+	{0x7c, 0x01},
+	{0x7d, 0x80},
+	{0x80, 0x00},
+	{0x90, 0x01},
+	{0xa9, 0x00},
+	{0xb5, 0x00},
+	{0xb9, 0x72},
+	{0xd1, 0x00},
+	{0xd5, 0x80},
 
-	{ 0xff, 0x05+3 },
-	{ 0x00, 0xd0 },
-	{ 0x01, 0x22 },
-	{ 0x47, 0xee },
-	{ 0x50, 0xc6 },
-	{ 0x57, 0x00 },
-	{ 0x58, 0x77 },
-	{ 0x5b, 0x41 },
-	{ 0x5c, 0x78 },
-	{ 0xB8, 0xB8 },
+	{0xff, 0x09},
+	{0x50, 0x30},
+	{0x51, 0x6f},
+	{0x52, 0x67},
+	{0x53, 0x48},
+	{0x54, 0x30},
+	{0x55, 0x6f},
+	{0x56, 0x67},
+	{0x57, 0x48},
+	{0x58, 0x30},
+	{0x59, 0x6f},
+	{0x5a, 0x67},
+	{0x5b, 0x48},
+	{0x5c, 0x30},
+	{0x5d, 0x6f},
+	{0x5e, 0x67},
+	{0x5f, 0x48},
+	{0x96, 0x03},
+	{0xb6, 0x03},
+	{0xd6, 0x03},
+	{0xf6, 0x03},
 
-	{ 0xff, 0x09 },
-	{ 0x50, 0x30 },
-	{ 0x51, 0x6f },
-	{ 0x52, 0x67 },
-	{ 0x53, 0x48 },
-	{ 0x54, 0x30 },
-	{ 0x55, 0x6f },
-	{ 0x56, 0x67 },
-	{ 0x57, 0x48 },
-	{ 0x58, 0x30 },
-	{ 0x59, 0x6f },
-	{ 0x5a, 0x67 },
-	{ 0x5b, 0x48 },
-	{ 0x5c, 0x30 },
-	{ 0x5d, 0x6f },
-	{ 0x5e, 0x67 },
-	{ 0x5f, 0x48 },
+	{0xff, 0x0a},
+	{0x25, 0x10},
+	{0x27, 0x1e},
+	{0x30, 0xac},
+	{0x31, 0x78},
+	{0x32, 0x17},
+	{0x33, 0xc1},
+	{0x34, 0x40},
+	{0x35, 0x00},
+	{0x36, 0xc3},
+	{0x37, 0x0a},
+	{0x38, 0x00},
+	{0x39, 0x02},
+	{0x3a, 0x00},
+	{0x3b, 0xb2},
+	{0xa5, 0x10},
+	{0xa7, 0x1e},
+	{0xb0, 0xac},
+	{0xb1, 0x78},
+	{0xb2, 0x17},
+	{0xb3, 0xc1},
+	{0xb4, 0x40},
+	{0xb5, 0x00},
+	{0xb6, 0xc3},
+	{0xb7, 0x0a},
+	{0xb8, 0x00},
+	{0xb9, 0x02},
+	{0xba, 0x00},
+	{0xbb, 0xb2},
+	{0xff, 0x0b},
+	{0x25, 0x10},
+	{0x27, 0x1e},
+	{0x30, 0xac},
+	{0x31, 0x78},
+	{0x32, 0x17},
+	{0x33, 0xc1},
+	{0x34, 0x40},
+	{0x35, 0x00},
+	{0x36, 0xc3},
+	{0x37, 0x0a},
+	{0x38, 0x00},
+	{0x39, 0x02},
+	{0x3a, 0x00},
+	{0x3b, 0xb2},
+	{0xa5, 0x10},
+	{0xa7, 0x1e},
+	{0xb0, 0xac},
+	{0xb1, 0x78},
+	{0xb2, 0x17},
+	{0xb3, 0xc1},
+	{0xb4, 0x40},
+	{0xb5, 0x00},
+	{0xb6, 0xc3},
+	{0xb7, 0x0a},
+	{0xb8, 0x00},
+	{0xb9, 0x02},
+	{0xba, 0x00},
+	{0xbb, 0xb2},
 
-	{ 0xff, 0x0a },
-	{ 0x25, 0x10 },
-	{ 0x27, 0x1e },
-	{ 0x30, 0xac },
-	{ 0x31, 0x78 },
-	{ 0x32, 0x17 },
-	{ 0x33, 0xc1 },
-	{ 0x34, 0x40 },
-	{ 0x35, 0x00 },
-	{ 0x36, 0xc3 },
-	{ 0x37, 0x0a },
-	{ 0x38, 0x00 },
-	{ 0x39, 0x02 },
-	{ 0x3a, 0x00 },
-	{ 0x3b, 0xb2 },
-	{ 0xa5, 0x10 },
-	{ 0xa7, 0x1e },
-	{ 0xb0, 0xac },
-	{ 0xb1, 0x78 },
-	{ 0xb2, 0x17 },
-	{ 0xb3, 0xc1 },
-	{ 0xb4, 0x40 },
-	{ 0xb5, 0x00 },
-	{ 0xb6, 0xc3 },
-	{ 0xb7, 0x0a },
-	{ 0xb8, 0x00 },
-	{ 0xb9, 0x02 },
-	{ 0xba, 0x00 },
-	{ 0xbb, 0xb2 },
-	{ 0xff, 0x0b },
-	{ 0x25, 0x10 },
-	{ 0x27, 0x1e },
-	{ 0x30, 0xac },
-	{ 0x31, 0x78 },
-	{ 0x32, 0x17 },
-	{ 0x33, 0xc1 },
-	{ 0x34, 0x40 },
-	{ 0x35, 0x00 },
-	{ 0x36, 0xc3 },
-	{ 0x37, 0x0a },
-	{ 0x38, 0x00 },
-	{ 0x39, 0x02 },
-	{ 0x3a, 0x00 },
-	{ 0x3b, 0xb2 },
-	{ 0xa5, 0x10 },
-	{ 0xa7, 0x1e },
-	{ 0xb0, 0xac },
-	{ 0xb1, 0x78 },
-	{ 0xb2, 0x17 },
-	{ 0xb3, 0xc1 },
-	{ 0xb4, 0x40 },
-	{ 0xb5, 0x00 },
-	{ 0xb6, 0xc3 },
-	{ 0xb7, 0x0a },
-	{ 0xb8, 0x00 },
-	{ 0xb9, 0x02 },
-	{ 0xba, 0x00 },
-	{ 0xbb, 0xb2 },
+	{0xff, 0x00},
+	{0x00, 0x10},
+	{0x01, 0x10},
+	{0x02, 0x10},
+	{0x03, 0x10},
+	{0x22, 0x0b},
+	{0x23, 0x41},
+	{0x26, 0x0b},
+	{0x27, 0x41},
+	{0x2a, 0x0b},
+	{0x2b, 0x41},
+	{0x2e, 0x0b},
+	{0x2f, 0x41},
 
-	{ 0xff, 0x13 },
-	{ 0x05, 0xa0 },
-	{ 0x31, 0xff },
-	{ 0x07, 0x47 },
-	{ 0x12, 0x04 },
-	{ 0x1e, 0x1f },
-	{ 0x1f, 0x27 },
-	{ 0x2e, 0x10 },
-	{ 0x2f, 0xc8 },
-	{ 0x31, 0xff },
-	{ 0x32, 0x00 },
-	{ 0x33, 0x00 },
-	{ 0x72, 0x05 },
-	{ 0x7a, 0xf0 },
-	{ 0xff, _MAR_BANK_ },
-	{ 0x10, 0xff },
-	{ 0x11, 0xff },
+	{0xff, 0x13},
+	{0x05, 0xa0},
+	{0x07, 0x47},
+	{0x12, 0x04},
+	{0x1e, 0x1f},
+	{0x1f, 0x27},
+	{0x2e, 0x10},
+	{0x2f, 0xc8},
+	{0x30, 0x00},
+	{0x31, 0xff},
+	{0x32, 0x00},
+	{0x33, 0x00},
+	{0x3a, 0xff},
+	{0x3b, 0xff},
+	{0x3c, 0xff},
+	{0x3d, 0xff},
+	{0x3e, 0xff},
+	{0x3f, 0x0f},
+	{0x70, 0x00},
+	{0x72, 0x05},
+	{0x7A, 0xf0},
+	{0x74, 0x00},
+	{0x76, 0x00},
+	{0x78, 0x00},
+	{0x75, 0xff},
+	{0x77, 0xff},
+	{0x79, 0xff},
+	{0x01, 0x0c},
+	{0x73, 0x23},
+	{0xff, _MAR_BANK_},
+	{0x40, 0x01},
+	{0x10, 0xff},
+	{0x11, 0xff},
+	{0x46, 0x49},
+	{0x45, 0x60},
+	{0x30, 0x0f},
+	{0x32, 0xff},
+	{0x34, 0xcd},
+	{0x36, 0x04},
+	{0x38, 0xff},
+	{0x07, 0x00},
+	{0x2a, 0x0a},
+	{0x3d, 0x11},
+	{0x3e, 0x11},
+	{0x3c, 0x01},
+	{0x1a, 0x92},
+	{0x1b, 0x00},
+	{0x1c, 0x00},
+	{0x05, 0x00},
+	{0x06, 0x00},
+	{0x0d, 0x01},
+	{0x00, 0x00},//mipi not enabled first
+	{0x40, 0x00},
 
-	{ 0x30, 0x0f },
-	{ 0x32, 0xff },
-	{ 0x34, 0xcd },
-	{ 0x36, 0x04 },
-	{ 0x38, 0xff },
-	{ 0x3c, 0x01 },
-	{ 0x3d, 0x11 },
-	{ 0x3e, 0x11 },
-	{ 0x45, 0x60 },
-	{ 0x46, 0x49 },
+	{0xff, 0x01},
+	//{ 0x82, 0x12 },
+	{0x80, 0x61},
+	{0x80, 0x60},
+	{0xa0, 0x20},
+	{0xa1, 0x20},
+	{0xa2, 0x20},
+	{0xa3, 0x20},
+	{0xed, 0x00},
 
-	{ 0xff, _MTX_BANK_ },
-	{ 0xe9, 0x03 },
-	{ 0x03, 0x02 },
-	{ 0x04, 0x6c },
-	{ 0x01, 0xe4 },
-	{ 0x00, 0x7d },
-	{ 0x01, 0xe0 },
-	{ 0x02, 0xa0 },
-	{ 0x20, 0x1e },
-	{ 0x20, 0x1f },
-	{ 0x45, 0xcd },
-	{ 0x46, 0x42 },
-	{ 0x47, 0x36 },
-	{ 0x48, 0x0f },
-	{ 0x65, 0xcd },
-	{ 0x66, 0x42 },
-	{ 0x67, 0x0e },
-	{ 0x68, 0x0f },
-	{ 0x85, 0xcd },
-	{ 0x86, 0x42 },
-	{ 0x87, 0x0e },
-	{ 0x88, 0x0f },
-	{ 0xa5, 0xcd },
-	{ 0xa6, 0x42 },
-	{ 0xa7, 0x0e },
-	{ 0xa8, 0x0f },
-	{ 0xc5, 0xcd },
-	{ 0xc6, 0x42 },
-	{ 0xc7, 0x0e },
-	{ 0xc8, 0x0f },
-	{ 0xeb, 0x8d },
+	{0xff, 0x00},
+	{0x80, 0x0f},
+	{0x81, 0x02},
+	{0x82, 0x02},
+	{0x83, 0x02},
+	{0x84, 0x02},
+	{0x64, 0x01},
+	{0x65, 0x01},
+	{0x66, 0x01},
+	{0x67, 0x01},
+	{0x5c, 0x80},
+	{0x5d, 0x80},
+	{0x5e, 0x80},
+	{0x5f, 0x80},
+	{0xff, 0x01},
+	{0x84, 0x02},
+	{0x85, 0x02},
+	{0x86, 0x02},
+	{0x87, 0x02},
+	{0x8c, 0x40},
+	{0x8d, 0x40},
+	{0x8e, 0x40},
+	{0x8f, 0x40},
+	{0xff, 0x20},
+	{0x01, 0x00},
+	{0x12, 0xc0},
+	{0x13, 0x03},
+	{0x14, 0xc0},
+	{0x15, 0x03},
+	{0x16, 0xc0},
+	{0x17, 0x03},
+	{0x18, 0xc0},
+	{0x19, 0x03},
+	{0xff, 0x01},
+	{0x97, 0xf0},
+	{0x97, 0x0f},
 
-	{ 0xff, _MAR_BANK_ },
-	{ 0x00, 0x00 }, //close mipi
-	{ 0x40, 0x01 },
-	{ 0x40, 0x00 },
-	{ 0xff, 0x01 },
-	{ 0x97, 0x00 },
-	{ 0x97, 0x0f },
-
-	{ 0xff, 0x00 },  //test pattern
-	{ 0x78, 0x88 },
-	{ 0x79, 0x88 },
-	{ 0xff, 0x05 },
-	{ 0x2c, 0x08 },
-	{ 0x6a, 0x00 },
-	{ 0xff, 0x06 },
-	{ 0x2c, 0x08 },
-	{ 0x6a, 0x00 },
-	{ 0xff, 0x07 },
-	{ 0x2c, 0x08 },
-	{ 0x6a, 0x00 },
-	{ 0xff, 0x08 },
-	{ 0x2c, 0x08 },
-	{ 0x6a, 0x00 },
-};
-
-static __maybe_unused const struct regval auto_detect_regs[] = {
-	{ 0xFF, 0x13 },
-	{ 0x30, 0x7f },
-	{ 0x70, 0xf0 },
-
-	{ 0xFF, 0x00 },
-	{ 0x00, 0x18 },
-	{ 0x01, 0x18 },
-	{ 0x02, 0x18 },
-	{ 0x03, 0x18 },
-
-	{ 0x00, 0x10 },
-	{ 0x01, 0x10 },
-	{ 0x02, 0x10 },
-	{ 0x03, 0x10 },
+	{0xff, 0x00},  //test pattern
+	{0x78, 0x88},
+	{0x79, 0x88},
+	{0xff, 0x05},
+	{0x2c, 0x08},
+	{0x6a, 0x00},
+	{0xff, 0x06},
+	{0x2c, 0x08},
+	{0x6a, 0x00},
+	{0xff, 0x07},
+	{0x2c, 0x08},
+	{0x6a, 0x00},
+	{0xff, 0x08},
+	{0x2c, 0x08},
+	{0x6a, 0x00},
 };
 
 static struct nvp6188_mode supported_modes[] = {
@@ -808,51 +931,29 @@
 	return ret;
 }
 
+static int nv6188_read_htotal(struct nvp6188 *nvp6188, unsigned char ch)
+{
+	int ch_htotal = 0;
+	unsigned char val_5xf2 = 0, val_5xf3 = 0;
+	struct i2c_client *client = nvp6188->client;
+
+	nvp6188_write_reg(client, 0xff, 0x05 + ch);
+	nvp6188_read_reg(client, 0xf2, &val_5xf2);
+	nvp6188_read_reg(client, 0xf3, &val_5xf3);
+	ch_htotal = ((val_5xf3 << 8) | val_5xf2);
+
+	return ch_htotal;
+}
+
 static unsigned char nv6188_read_vfc(struct nvp6188 *nvp6188, unsigned char ch)
 {
 	unsigned char ch_vfc = 0xff;
 	struct i2c_client *client = nvp6188->client;
+
 	nvp6188_write_reg(client, 0xff, 0x05 + ch);
 	nvp6188_read_reg(client, 0xf0, &ch_vfc);
+
 	return ch_vfc;
-}
-
-static __maybe_unused int nvp6188_read_all_vfc(struct nvp6188 *nvp6188,
-					       u8 *ch_vfc)
-{
-	int ret = 0;
-	int check_cnt = 0, ch = 0;
-	struct i2c_client *client = nvp6188->client;
-
-	ret = nvp6188_write_array(client,
-		auto_detect_regs, ARRAY_SIZE(auto_detect_regs));
-	if (ret) {
-		dev_err(&client->dev, "write auto_detect_regs faild %d", ret);
-	}
-
-	while ((check_cnt++) < 50) {
-		for (ch = 0; ch < 4; ch++) {
-			ch_vfc[ch] = nv6188_read_vfc(nvp6188, ch);
-		}
-		if (ch_vfc[0] != 0xff || ch_vfc[1] != 0xff ||
-		    ch_vfc[2] != 0xff || ch_vfc[3] != 0xff) {
-			ret = 0;
-			if (ch == 3) {
-				dev_dbg(&client->dev, "try check cnt %d",check_cnt);
-				break;
-			}
-		} else {
-			usleep_range(20 * 1000, 40 * 1000);
-		}
-	}
-
-	if (ret) {
-		dev_err(&client->dev, "read vfc faild %d", ret);
-	} else {
-		dev_dbg(&client->dev, "read vfc 0x%2x 0x%2x 0x%2x 0x%2x",
-				ch_vfc[0], ch_vfc[1], ch_vfc[2], ch_vfc[3]);
-	}
-	return ret;
 }
 
 static __maybe_unused int nvp6188_auto_detect_hotplug(struct nvp6188 *nvp6188)
@@ -924,8 +1025,8 @@
 		__v4l2_ctrl_s_ctrl(nvp6188->link_freq, mode->mipi_freq_idx);
 		pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * NVP6188_LANES;
 		__v4l2_ctrl_s_ctrl_int64(nvp6188->pixel_rate, pixel_rate);
-		dev_err(&nvp6188->client->dev, "mipi_freq_idx %d\n", mode->mipi_freq_idx);
-		dev_err(&nvp6188->client->dev, "pixel_rate %lld\n", pixel_rate);
+		dev_info(&nvp6188->client->dev, "mipi_freq_idx %d\n", mode->mipi_freq_idx);
+		dev_info(&nvp6188->client->dev, "pixel_rate %lld\n", pixel_rate);
 	}
 
 	mutex_unlock(&nvp6188->mutex);
@@ -981,6 +1082,21 @@
 	return 0;
 }
 
+static int nvp6188_enum_frame_interval(struct v4l2_subdev *sd,
+				       struct v4l2_subdev_pad_config *cfg,
+				       struct v4l2_subdev_frame_interval_enum *fie)
+{
+	if (fie->index >= ARRAY_SIZE(supported_modes))
+		return -EINVAL;
+
+	fie->code = supported_modes[fie->index].bus_fmt;
+	fie->width = supported_modes[fie->index].width;
+	fie->height = supported_modes[fie->index].height;
+	fie->interval = supported_modes[fie->index].max_fps;
+
+	return 0;
+}
+
 static int nvp6188_enum_frame_sizes(struct v4l2_subdev *sd,
 				    struct v4l2_subdev_pad_config *cfg,
 				    struct v4l2_subdev_frame_size_enum *fse)
@@ -1003,12 +1119,25 @@
 	return 0;
 }
 
-static int nvp6188_g_mbus_config(struct v4l2_subdev *sd,
+static int nvp6188_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
 				 struct v4l2_mbus_config *cfg)
 {
-	cfg->type = V4L2_MBUS_CSI2;
+	cfg->type = V4L2_MBUS_CSI2_DPHY;
 	cfg->flags = V4L2_MBUS_CSI2_4_LANE |
 		     V4L2_MBUS_CSI2_CHANNELS;
+
+	return 0;
+}
+
+static int nvp6188_g_frame_interval(struct v4l2_subdev *sd,
+				    struct v4l2_subdev_frame_interval *fi)
+{
+	struct nvp6188 *nvp6188 = to_nvp6188(sd);
+	const struct nvp6188_mode *mode = &nvp6188->cur_mode;
+
+	mutex_lock(&nvp6188->mutex);
+	fi->interval = mode->max_fps;
+	mutex_unlock(&nvp6188->mutex);
 
 	return 0;
 }
@@ -1028,8 +1157,8 @@
 {
 	int ch = 0;
 	static u32 last_channel_reso[PAD_MAX] = {NVP_RESO_UNKOWN};
-
 	memset(inf, 0, sizeof(*inf));
+
 	for (ch = 0; ch < PAD_MAX; ch++) {
 		//Maintain last resolution modify by cairufan
 		if (nvp6188->cur_mode.channel_reso[ch] != NVP_RESO_UNKOWN)
@@ -1071,6 +1200,16 @@
 				inf->height[ch] = 1080;
 				inf->fps[ch] = 25;
 			break;
+		case NVP_RESO_1300P_NSTC:
+				inf->width[ch] = 1600;
+				inf->height[ch] = 1300;
+				inf->fps[ch] = 30;
+			break;
+		case NVP_RESO_1300P_PAL:
+				inf->width[ch] = 1600;
+				inf->height[ch] = 1300;
+				inf->fps[ch] = 25;
+			break;
 		case NVP_RESO_1080P_NSTC:
 			default:
 				inf->width[ch] = 1920;
@@ -1107,18 +1246,8 @@
 	struct i2c_client *client = nvp6188->client;
 
 	dev_info(&client->dev, "%s: on: %d\n", __func__, on);
-
-	mutex_lock(&nvp6188->mutex);
-
-	if (on) {
-		nvp6188_write_reg(client, 0xff, 0x20);
-		nvp6188_write_reg(client, 0xff, 0xff);
-	} else {
-		nvp6188_write_reg(client, 0xff, 0x20);
-		nvp6188_write_reg(client, 0xff, 0x00);
-	}
-
-	mutex_unlock(&nvp6188->mutex);
+	if (!on)
+		usleep_range(40 * 1000, 50 * 1000);
 }
 
 static long nvp6188_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
@@ -1292,6 +1421,7 @@
  */
 static __maybe_unused void nv6188_set_chn_960p(struct nvp6188 *nvp6188, u8 ch,
 							u8 ntpal)
+
 {
 	unsigned char val_0x54 = 0, val_20x01 = 0;
 	struct i2c_client *client = nvp6188->client;
@@ -1299,27 +1429,29 @@
 	dev_info(&client->dev, "%s: ch %d ntpal %d", __func__, ch, ntpal);
 
 	nvp6188_write_reg(client, 0xff, 0x00);
-	nvp6188_write_reg(client, 0x08+ch, 0x00);
-	nvp6188_write_reg(client, 0x18+ch, 0x0f);
-	nvp6188_write_reg(client, 0x30+ch, 0x12);
-	nvp6188_write_reg(client, 0x34+ch, 0x00);
+	nvp6188_write_reg(client, 0x00 + ch, 0x10);
+	nvp6188_write_reg(client, 0x08 + ch, 0x00);
+	nvp6188_write_reg(client, 0x18 + ch, 0x0f);
+	nvp6188_write_reg(client, 0x30 + ch, 0x12);
+	nvp6188_write_reg(client, 0x34 + ch, 0x00);
 	nvp6188_read_reg(client, 0x54, &val_0x54);
-	val_0x54 &= ~(0x10<<ch);
+	val_0x54 &= ~(0x10 << ch);
 	nvp6188_write_reg(client, 0x54, val_0x54);
-	nvp6188_write_reg(client, 0x58+ch, ntpal?0x40:0x48);
-	nvp6188_write_reg(client, 0x5c+ch, ntpal?0x80:0x80);
-	nvp6188_write_reg(client, 0x64+ch, ntpal?0x28:0x28);
-	nvp6188_write_reg(client, 0x81+ch, ntpal?0x07:0x06);
-	nvp6188_write_reg(client, 0x85+ch, 0x0b);
-	nvp6188_write_reg(client, 0x89+ch, 0x00);
-	nvp6188_write_reg(client, ch+0x8e, 0x00);
-	nvp6188_write_reg(client, 0xa0+ch, 0x05);
+	nvp6188_write_reg(client, 0x58 + ch, ntpal ? 0x40 : 0x48);
+	nvp6188_write_reg(client, 0x5c + ch, ntpal ? 0x80 : 0x80);
+	nvp6188_write_reg(client, 0x64 + ch, ntpal ? 0x28 : 0x28);
+	nvp6188_write_reg(client, 0x81 + ch, ntpal ? 0x07 : 0x06);
+	nvp6188_write_reg(client, 0x85 + ch, 0x0b);
+	nvp6188_write_reg(client, 0x89 + ch, 0x00);
+	nvp6188_write_reg(client, 0x8e + ch, 0x00);
+	nvp6188_write_reg(client, 0xa0 + ch, 0x05);
 	nvp6188_write_reg(client, 0xff, 0x01);
-	nvp6188_write_reg(client, 0x84+ch, 0x02);
-	nvp6188_write_reg(client, 0x88+ch, 0x00);
-	nvp6188_write_reg(client, 0x8c+ch, 0x40);
-	nvp6188_write_reg(client, 0xa0+ch, 0x20);
-	nvp6188_write_reg(client, 0xff, 0x05+ch);
+	nvp6188_write_reg(client, 0x84 + ch, 0x02);
+	nvp6188_write_reg(client, 0x88 + ch, 0x00);
+	nvp6188_write_reg(client, 0x8c + ch, 0x40);
+	nvp6188_write_reg(client, 0xa0 + ch, 0x20);
+	nvp6188_write_reg(client, 0xff, 0x05 + ch);
+	nvp6188_write_reg(client, 0x00, 0xd0);
 	nvp6188_write_reg(client, 0x01, 0x22);
 	nvp6188_write_reg(client, 0x05, 0x04);
 	nvp6188_write_reg(client, 0x08, 0x55);
@@ -1353,16 +1485,18 @@
 	nvp6188_write_reg(client, 0xd1, 0x00);
 	nvp6188_write_reg(client, 0xd5, 0x80);
 	nvp6188_write_reg(client, 0xff, 0x09);
-	nvp6188_write_reg(client, 0x96+ch*0x20, 0x00);
-	nvp6188_write_reg(client, 0x98+ch*0x20, 0x00);
-	nvp6188_write_reg(client, ch*0x20+0x9e, 0x00);
+	nvp6188_write_reg(client, 0x96 + (ch * 0x20), 0x00);
+	nvp6188_write_reg(client, 0x98 + (ch * 0x20), 0x00);
+	nvp6188_write_reg(client, 0x9e + (ch * 0x20), 0x00);
+	nvp6188_write_reg(client, 0xff, 0x11);
+	nvp6188_write_reg(client, 0x00 + (ch * 0x20), 0x00);
 	nvp6188_write_reg(client, 0xff, _MAR_BANK_);
 	nvp6188_read_reg(client, 0x01, &val_20x01);
-	val_20x01 &= (~(0x03<<(ch*2)));
+	val_20x01 &= (~(0x03 << (ch * 2)));
 	//val_20x01 |=(0x01<<(ch*2));
 	nvp6188_write_reg(client, 0x01, val_20x01);
-	nvp6188_write_reg(client, 0x12+ch*2, 0x80);
-	nvp6188_write_reg(client, 0x13+ch*2, 0x02);
+	nvp6188_write_reg(client, 0x12 + (ch * 2), 0x80);
+	nvp6188_write_reg(client, 0x13 + (ch * 2), 0x02);
 }
 
 //each channel setting
@@ -1377,9 +1511,9 @@
 	unsigned char val_0x54 = 0, val_20x01 = 0;
 	struct i2c_client *client = nvp6188->client;
 
-	dev_info(&client->dev, "%s: ch %d ntpal %d", __func__, ch, ntpal);
-
+	dev_err(&client->dev, "%s: ch %d ntpal %d", __func__, ch, ntpal);
 	nvp6188_write_reg(client, 0xff, 0x00);
+	nvp6188_write_reg(client, 0x00 + ch, 0x10);
 	nvp6188_write_reg(client, 0x08 + ch, ntpal ? 0xdd : 0xa0);
 	nvp6188_write_reg(client, 0x18 + ch, 0x08);
 	nvp6188_write_reg(client, 0x22 + ch * 4, 0x0b);
@@ -1398,17 +1532,16 @@
 	nvp6188_write_reg(client, 0x81 + ch, ntpal ? 0xf0 : 0xe0);
 	nvp6188_write_reg(client, 0x85 + ch, 0x00);
 	nvp6188_write_reg(client, 0x89 + ch, 0x00);
-	nvp6188_write_reg(client, ch + 0x8e, 0x00);
+	nvp6188_write_reg(client, 0x8e + ch, 0x00);
 	nvp6188_write_reg(client, 0xa0 + ch, 0x05);
-
 	nvp6188_write_reg(client, 0xff, 0x01);
 	nvp6188_write_reg(client, 0x84 + ch, 0x02);
 	nvp6188_write_reg(client, 0x88 + ch, 0x00);
 	nvp6188_write_reg(client, 0x8c + ch, 0x40);
 	nvp6188_write_reg(client, 0xa0 + ch, 0x20);
 	nvp6188_write_reg(client, 0xed, 0x00);
-
 	nvp6188_write_reg(client, 0xff, 0x05 + ch);
+	nvp6188_write_reg(client, 0x00, 0xd0);
 	nvp6188_write_reg(client, 0x01, 0x22);
 	nvp6188_write_reg(client, 0x05, 0x00);
 	nvp6188_write_reg(client, 0x08, 0x55);
@@ -1437,19 +1570,19 @@
 	nvp6188_write_reg(client, 0xb9, 0x72);
 	nvp6188_write_reg(client, 0xd1, 0x00);
 	nvp6188_write_reg(client, 0xd5, 0x80);
-
 	nvp6188_write_reg(client, 0xff, 0x09);
-	nvp6188_write_reg(client, 0x96 + ch * 0x20, 0x10);
-	nvp6188_write_reg(client, 0x98 + ch * 0x20, ntpal ? 0xc0 : 0xe0);
-	nvp6188_write_reg(client, ch * 0x20 + 0x9e, 0x00);
-
+	nvp6188_write_reg(client, 0x96 + (ch * 0x20), 0x10);
+	nvp6188_write_reg(client, 0x98 + (ch * 0x20), ntpal ? 0xc0 : 0xe0);
+	nvp6188_write_reg(client, 0x9e + (ch * 0x20), 0x00);
+	nvp6188_write_reg(client, 0xff, 0x11);
+	nvp6188_write_reg(client, 0x00 + (ch * 0x20), 0x00);
 	nvp6188_write_reg(client, 0xff, _MAR_BANK_);
 	nvp6188_read_reg(client, 0x01, &val_20x01);
 	val_20x01 &= (~(0x03 << (ch * 2)));
 	val_20x01 |= (0x02 << (ch * 2));
 	nvp6188_write_reg(client, 0x01, val_20x01);
-	nvp6188_write_reg(client, 0x12 + ch * 2, 0xe0);
-	nvp6188_write_reg(client, 0x13 + ch * 2, 0x01);
+	nvp6188_write_reg(client, 0x12 + (ch * 2), 0xe0);
+	nvp6188_write_reg(client, 0x13 + (ch * 2), 0x01);
 }
 
 //each channel setting
@@ -1465,10 +1598,10 @@
 	struct i2c_client *client = nvp6188->client;
 
 	dev_info(&client->dev, "%s: ch %d ntpal %d", __func__, ch, ntpal);
-
 	nvp6188_write_reg(client, 0xff, 0x00);
+	nvp6188_write_reg(client, 0x00 + ch, 0x00);
 	nvp6188_write_reg(client, 0x08 + ch, 0x00);
-	nvp6188_write_reg(client, 0x18 + ch, 0x3f);
+	nvp6188_write_reg(client, 0x18 + ch, 0x10);
 	nvp6188_write_reg(client, 0x30 + ch, 0x12);
 	nvp6188_write_reg(client, 0x34 + ch, 0x00);
 	nvp6188_read_reg(client, 0x54, &val_0x54);
@@ -1480,16 +1613,15 @@
 	nvp6188_write_reg(client, 0x81 + ch, ntpal ? 0x0d : 0x0c);
 	nvp6188_write_reg(client, 0x85 + ch, 0x00);
 	nvp6188_write_reg(client, 0x89 + ch, 0x00);
-	nvp6188_write_reg(client, ch + 0x8e, 0x00);
+	nvp6188_write_reg(client, 0x8e + ch, 0x00);
 	nvp6188_write_reg(client, 0xa0 + ch, 0x05);
-
 	nvp6188_write_reg(client, 0xff, 0x01);
 	nvp6188_write_reg(client, 0x84 + ch, 0x02);
 	nvp6188_write_reg(client, 0x88 + ch, 0x00);
 	nvp6188_write_reg(client, 0x8c + ch, 0x40);
 	nvp6188_write_reg(client, 0xa0 + ch, 0x20);
-
 	nvp6188_write_reg(client, 0xff, 0x05 + ch);
+	nvp6188_write_reg(client, 0x00, 0xf0);
 	nvp6188_write_reg(client, 0x01, 0x22);
 	nvp6188_write_reg(client, 0x05, 0x04);
 	nvp6188_write_reg(client, 0x08, 0x55);
@@ -1499,38 +1631,38 @@
 	nvp6188_write_reg(client, 0x30, 0xe0);
 	nvp6188_write_reg(client, 0x31, 0x43);
 	nvp6188_write_reg(client, 0x32, 0xa2);
-	nvp6188_write_reg(client, 0x47, 0xee);
-	nvp6188_write_reg(client, 0x50, 0xc6);
+	nvp6188_write_reg(client, 0x47, 0x04);
+	nvp6188_write_reg(client, 0x50, 0x84);
 	nvp6188_write_reg(client, 0x57, 0x00);
 	nvp6188_write_reg(client, 0x58, 0x77);
 	nvp6188_write_reg(client, 0x5b, 0x41);
-	nvp6188_write_reg(client, 0x5c, 0x7C);
+	nvp6188_write_reg(client, 0x5c, 0x78);
 	nvp6188_write_reg(client, 0x5f, 0x00);
-	nvp6188_write_reg(client, 0x62, 0x20);
+	nvp6188_write_reg(client, 0x62, 0x00);
 	nvp6188_write_reg(client, 0x7b, 0x11);
 	nvp6188_write_reg(client, 0x7c, 0x01);
 	nvp6188_write_reg(client, 0x7d, 0x80);
 	nvp6188_write_reg(client, 0x80, 0x00);
 	nvp6188_write_reg(client, 0x90, 0x01);
 	nvp6188_write_reg(client, 0xa9, 0x00);
-	nvp6188_write_reg(client, 0xb5, 0x40);
-	nvp6188_write_reg(client, 0xb8, 0x39);
+	nvp6188_write_reg(client, 0xb5, 0x00);
+	nvp6188_write_reg(client, 0xb8, 0xb9);
 	nvp6188_write_reg(client, 0xb9, 0x72);
 	nvp6188_write_reg(client, 0xd1, 0x00);
 	nvp6188_write_reg(client, 0xd5, 0x80);
-
 	nvp6188_write_reg(client, 0xff, 0x09);
-	nvp6188_write_reg(client, 0x96 + ch * 0x20, 0x00);
-	nvp6188_write_reg(client, 0x98 + ch * 0x20, 0x00);
-	nvp6188_write_reg(client, ch * 0x20 + 0x9e, 0x00);
-
+	nvp6188_write_reg(client, 0x96 + (ch * 0x20), 0x00);
+	nvp6188_write_reg(client, 0x98 + (ch * 0x20), 0x00);
+	nvp6188_write_reg(client, 0x9e + (ch * 0x20), 0x00);
+	nvp6188_write_reg(client, 0xff, 0x11);
+	nvp6188_write_reg(client, 0x00 + (ch * 0x20), 0x00);
 	nvp6188_write_reg(client, 0xff, _MAR_BANK_);
 	nvp6188_read_reg(client, 0x01, &val_20x01);
 	val_20x01 &= (~(0x03 << (ch * 2)));
 	val_20x01 |= (0x01 << (ch * 2));
 	nvp6188_write_reg(client, 0x01, val_20x01);
-	nvp6188_write_reg(client, 0x12 + ch * 2, 0x80);
-	nvp6188_write_reg(client, 0x13 + ch * 2, 0x02);
+	nvp6188_write_reg(client, 0x12 + (ch * 2), 0x80);
+	nvp6188_write_reg(client, 0x13 + (ch * 2), 0x02);
 }
 
 //each channel setting
@@ -1545,10 +1677,11 @@
 	unsigned char val_0x54 = 0, val_20x01 = 0;
 	struct i2c_client *client = nvp6188->client;
 
-	dev_info(&client->dev, "%s: ch %d ntpal %d", __func__, ch, ntpal);
+	dev_info(&client->dev, "%s ch %d ntpal %d", __func__, ch, ntpal);
 	nvp6188_write_reg(client, 0xff, 0x00);
+	nvp6188_write_reg(client, 0x00 + ch, 0x10);
 	nvp6188_write_reg(client, 0x08 + ch, 0x00);
-	nvp6188_write_reg(client, 0x18 + ch, 0x3f);
+	nvp6188_write_reg(client, 0x18 + ch, 0x10);
 	nvp6188_write_reg(client, 0x30 + ch, 0x12);
 	nvp6188_write_reg(client, 0x34 + ch, 0x00);
 	nvp6188_read_reg(client, 0x54, &val_0x54);
@@ -1560,16 +1693,15 @@
 	nvp6188_write_reg(client, 0x81 + ch, ntpal ? 0x03 : 0x02);
 	nvp6188_write_reg(client, 0x85 + ch, 0x00);
 	nvp6188_write_reg(client, 0x89 + ch, 0x10);
-	nvp6188_write_reg(client, ch + 0x8e, 0x00);
+	nvp6188_write_reg(client, 0x8e + ch, 0x00);
 	nvp6188_write_reg(client, 0xa0 + ch, 0x05);
-
 	nvp6188_write_reg(client, 0xff, 0x01);
 	nvp6188_write_reg(client, 0x84 + ch, 0x02);
 	nvp6188_write_reg(client, 0x88 + ch, 0x00);
 	nvp6188_write_reg(client, 0x8c + ch, 0x40);
 	nvp6188_write_reg(client, 0xa0 + ch, 0x20);
-
 	nvp6188_write_reg(client, 0xff, 0x05 + ch);
+	nvp6188_write_reg(client, 0x00, 0xd0);
 	nvp6188_write_reg(client, 0x01, 0x22);
 	nvp6188_write_reg(client, 0x05, 0x04);
 	nvp6188_write_reg(client, 0x08, 0x55);
@@ -1598,18 +1730,115 @@
 	nvp6188_write_reg(client, 0xb9, 0x72);
 	nvp6188_write_reg(client, 0xd1, 0x00);
 	nvp6188_write_reg(client, 0xd5, 0x80);
-
 	nvp6188_write_reg(client, 0xff, 0x09);
-	nvp6188_write_reg(client, 0x96 + ch * 0x20, 0x00);
-	nvp6188_write_reg(client, 0x98 + ch * 0x20, 0x00);
-	nvp6188_write_reg(client, ch * 0x20 + 0x9e, 0x00);
-
+	nvp6188_write_reg(client, 0x96 + (ch * 0x20), 0x00);
+	nvp6188_write_reg(client, 0x98 + (ch * 0x20), 0x00);
+	nvp6188_write_reg(client, 0x9e + (ch * 0x20), 0x00);
+	nvp6188_write_reg(client, 0xff, 0x11);
+	nvp6188_write_reg(client, 0x00 + (ch * 0x20), 0x00);
 	nvp6188_write_reg(client, 0xff, _MAR_BANK_);
 	nvp6188_read_reg(client, 0x01, &val_20x01);
 	val_20x01 &= (~(0x03 << (ch * 2)));
 	nvp6188_write_reg(client, 0x01, val_20x01);
-	nvp6188_write_reg(client, 0x12 + ch * 2, 0xc0);
-	nvp6188_write_reg(client, 0x13 + ch * 2, 0x03);
+	nvp6188_write_reg(client, 0x12 + (ch * 2), 0xc0);
+	nvp6188_write_reg(client, 0x13 + (ch * 2), 0x03);
+}
+
+//each channel setting
+/*
+ * 1600x1300p
+ * dev:0x60 / 0x62 / 0x64 / 0x66
+ * ch : 0 ~ 3
+ * ntpal: 1:25p, 0:30p
+ * detection: 5xf3<<8 | 5xf2 = 0x0708(30p) =0x0870(25p)
+ */
+static void nv6188_set_chn_1300p(struct nvp6188 *nvp6188, unsigned char ch, unsigned char ntpal)
+{
+	unsigned char val_0x54 = 0, val_20x01 = 0;
+	struct i2c_client *client = nvp6188->client;
+
+	dev_info(&client->dev, "%s ch %d ntpal %d", __func__, ch, ntpal);
+
+	nvp6188_write_reg(client, 0xff, 0x00);
+	nvp6188_write_reg(client, 0x00 + ch, 0x10);
+	nvp6188_write_reg(client, 0x08 + ch, 0x00);
+	nvp6188_write_reg(client, 0x18 + ch, 0x10);
+	nvp6188_write_reg(client, 0x30 + ch, 0x12);
+	nvp6188_write_reg(client, 0x34 + ch, 0x00);
+	nvp6188_read_reg(client, 0x54, &val_0x54);
+	val_0x54 &= ~(0x10 << ch);
+	nvp6188_write_reg(client, 0x54, val_0x54);
+	nvp6188_write_reg(client, 0x58 + ch, ntpal ? 0x80 : 0x80);
+	nvp6188_write_reg(client, 0x5c + ch, ntpal ? 0x80 : 0x80);
+	nvp6188_write_reg(client, 0x64 + ch, ntpal ? 0x00 : 0x01);
+	nvp6188_write_reg(client, 0x81 + ch, ntpal ? 0x03 : 0x02);
+	nvp6188_write_reg(client, 0x85 + ch, 0x00);
+	nvp6188_write_reg(client, 0x89 + ch, 0x10);
+	nvp6188_write_reg(client, 0x8e + ch, 0x00);
+	nvp6188_write_reg(client, 0xa0 + ch, 0x05);
+	nvp6188_write_reg(client, 0xff, 0x01);
+	nvp6188_write_reg(client, 0x84 + ch, 0x02);
+	nvp6188_write_reg(client, 0x88 + ch, 0x00);
+	nvp6188_write_reg(client, 0x8c + ch, 0x40);
+	nvp6188_write_reg(client, 0xa0 + ch, 0x20);
+	nvp6188_write_reg(client, 0xff, 0x05 + ch);
+	nvp6188_write_reg(client, 0x00, 0xd0);
+	nvp6188_write_reg(client, 0x01, 0x22);
+	nvp6188_write_reg(client, 0x05, 0x04);
+	nvp6188_write_reg(client, 0x08, 0x55);
+	nvp6188_write_reg(client, 0x25, 0xdc);
+	nvp6188_write_reg(client, 0x28, 0x80);
+	nvp6188_write_reg(client, 0x2f, 0x00);
+	nvp6188_write_reg(client, 0x30, 0xe0);
+	nvp6188_write_reg(client, 0x31, 0x41);
+	nvp6188_write_reg(client, 0x32, 0xa2);
+	nvp6188_write_reg(client, 0x47, 0xee);
+	nvp6188_write_reg(client, 0x50, 0xc6);
+	nvp6188_write_reg(client, 0x57, 0x00);
+	nvp6188_write_reg(client, 0x58, 0x77);
+	nvp6188_write_reg(client, 0x5b, 0x41);
+	nvp6188_write_reg(client, 0x5c, 0x78);
+	nvp6188_write_reg(client, 0x5f, 0x00);
+	nvp6188_write_reg(client, 0x62, 0x00);
+	nvp6188_write_reg(client, 0x6C, 0x00);
+	nvp6188_write_reg(client, 0x6d, 0x00);
+	nvp6188_write_reg(client, 0x6e, 0x00);
+	nvp6188_write_reg(client, 0x6f, 0x00);
+	nvp6188_write_reg(client, 0x7b, 0x11);
+	nvp6188_write_reg(client, 0x7c, 0x01);
+	nvp6188_write_reg(client, 0x7d, 0x80);
+	nvp6188_write_reg(client, 0x80, 0x00);
+	nvp6188_write_reg(client, 0x90, 0x01);
+	nvp6188_write_reg(client, 0xa9, 0x00);
+	nvp6188_write_reg(client, 0xb5, 0x00);
+	nvp6188_write_reg(client, 0xb8, 0xb9);
+	nvp6188_write_reg(client, 0xb9, 0x72);
+	nvp6188_write_reg(client, 0xd1, 0x00);
+	nvp6188_write_reg(client, 0xd5, 0x80);
+	nvp6188_write_reg(client, 0xff, 0x09);
+	nvp6188_write_reg(client, 0x96 + (ch * 0x20), 0x00);
+	nvp6188_write_reg(client, 0x98 + (ch * 0x20), 0x00);
+	nvp6188_write_reg(client, 0x9e + (ch * 0x20), 0x00);
+	nvp6188_write_reg(client, 0xff, 0x11);  //additional settings for 1300p
+	nvp6188_write_reg(client, 0x01 + (ch * 0x20), ntpal ? 0x01 : 0x00);
+	nvp6188_write_reg(client, 0x02 + (ch * 0x20), ntpal ? 0xb2 : 0x50);
+	nvp6188_write_reg(client, 0x03 + (ch * 0x20), 0x06);
+	nvp6188_write_reg(client, 0x04 + (ch * 0x20), 0x40);
+	nvp6188_write_reg(client, 0x05 + (ch * 0x20), ntpal ? 0x08 : 0x07);
+	nvp6188_write_reg(client, 0x06 + (ch * 0x20), ntpal ? 0x70 : 0x08);
+	nvp6188_write_reg(client, 0x07 + (ch * 0x20), 0x00);
+	nvp6188_write_reg(client, 0x08 + (ch * 0x20), 0x00);
+	nvp6188_write_reg(client, 0x0a + (ch * 0x20), 0x05);
+	nvp6188_write_reg(client, 0x0b + (ch * 0x20), 0x14);
+	nvp6188_write_reg(client, 0x0c + (ch * 0x20), 0x05);
+	nvp6188_write_reg(client, 0x0d + (ch * 0x20), 0x5f);
+	nvp6188_write_reg(client, 0x00 + (ch * 0x20), 0x03);
+	nvp6188_write_reg(client, 0xff, 0x20);
+	nvp6188_read_reg(client, 0x01, &val_20x01);
+	val_20x01 &= (~(0x03 << (ch * 2)));
+	nvp6188_write_reg(client, 0x01, val_20x01);
+	nvp6188_write_reg(client, 0x12 + (ch * 2), 0x20);
+	nvp6188_write_reg(client, 0x13 + (ch * 2), 0x03);
 }
 
 static __maybe_unused void nvp6188_manual_mode(struct nvp6188 *nvp6188, u8 ch, u32 fmt)
@@ -1617,14 +1846,15 @@
 	unsigned char val_13x70 = 0, val_13x71 = 0;
 	struct i2c_client *client = nvp6188->client;
 
-	nvp6188_write_reg(client, 0xFF, 0x13);
-	nvp6188_read_reg(client, 0x70, &val_13x70);
-	val_13x70 |= (0x01 << ch);
-	nvp6188_write_reg(client, 0x70, val_13x70);
-	nvp6188_read_reg(client, 0x71, &val_13x71);
-	val_13x71 |= (0x01 << ch);
-	nvp6188_write_reg(client, 0x71, val_13x71);
-
+	if (fmt != NVP_RESO_UNKOWN) {
+		nvp6188_write_reg(client, 0xFF, 0x13);
+		nvp6188_read_reg(client, 0x70, &val_13x70);
+		val_13x70 |= (0x01 << ch);
+		nvp6188_write_reg(client, 0x70, val_13x70);
+		nvp6188_read_reg(client, 0x71, &val_13x71);
+		val_13x71 |= (0x01 << ch);
+		nvp6188_write_reg(client, 0x71, val_13x71);
+	}
 	switch (fmt) {
 	case NVP_RESO_960H_PAL:
 		nv6188_set_chn_960h(nvp6188, ch, 1);
@@ -1638,6 +1868,9 @@
 	case NVP_RESO_1080P_PAL:
 		nv6188_set_chn_1080p(nvp6188, ch, 1);
 		break;
+	case NVP_RESO_1300P_PAL:
+		nv6188_set_chn_1300p(nvp6188, ch, 1);
+		break;
 	case NVP_RESO_960H_NSTC:
 		nv6188_set_chn_960h(nvp6188, ch, 0);
 		break;
@@ -1650,8 +1883,11 @@
 	case NVP_RESO_1080P_NSTC:
 		nv6188_set_chn_1080p(nvp6188, ch, 0);
 		break;
+	case NVP_RESO_1300P_NSTC:
+		nv6188_set_chn_1300p(nvp6188, ch, 0);
+		break;
 	default:
-		nv6188_set_chn_1080p(nvp6188, ch, 1);
+		nv6188_set_chn_1080p(nvp6188, ch, 0);
 
 		dev_err(&client->dev, "channel %d not detect\n", ch);
 		nvp6188_write_reg(client, 0xFF, 0x13);
@@ -1659,71 +1895,96 @@
 		val_13x70 &= ~(0x01 << ch);
 		nvp6188_write_reg(client, 0x70, val_13x70);
 		nvp6188_write_reg(client, 0xFF, 0x05 + ch);
+		nvp6188_write_reg(client, 0x58, 0x77);
 		nvp6188_write_reg(client, 0xb8, 0xb8);
 		break;
 	}
+
+	// clear unknown count status
+	nvp6188->cur_mode.unkown_reso_count[ch] = 0;
 }
 
 static __maybe_unused void nvp6188_auto_detect_fmt(struct nvp6188 *nvp6188)
 {
 	u8 ch = 0;
 	u32 reso = 0;
-	unsigned char ch_vfc = 0xff;
+	unsigned char ch_vfc = 0xff, val_13x70 = 0xf0;
+	int ch_htotal = 0;
 	struct i2c_client *client = nvp6188->client;
 
 	for (ch = 0; ch < PAD_MAX; ch++) {
 		ch_vfc = nv6188_read_vfc(nvp6188, ch);
-
+		if (ch_vfc == 0xFF) {
+			ch_htotal = nv6188_read_htotal(nvp6188, ch);
+			if (ch_htotal == 0x0708)
+				ch_vfc = NVP_RESO_1300P_NSTC_VALUE;
+			else if (ch_htotal == 0x0870)
+				ch_vfc = NVP_RESO_1300P_PAL_VALUE;
+		}
 		switch (ch_vfc) {
 		case NVP_RESO_960H_NSTC_VALUE:
-				dev_dbg(&client->dev, "channel %d det 960h nstc", ch);
-				reso = NVP_RESO_960H_NSTC;
+			dev_dbg(&client->dev, "channel %d det 960h nstc", ch);
+			reso = NVP_RESO_960H_NSTC;
 			break;
 		case NVP_RESO_960H_PAL_VALUE:
-				dev_dbg(&client->dev, "channel %d det 960h pal", ch);
-				reso = NVP_RESO_960H_PAL;
+			dev_dbg(&client->dev, "channel %d det 960h pal", ch);
+			reso = NVP_RESO_960H_PAL;
 			break;
 		case NVP_RESO_720P_NSTC_VALUE:
-				dev_dbg(&client->dev, "channel %d det 720p nstc", ch);
-				reso = NVP_RESO_720P_NSTC;
+			dev_dbg(&client->dev, "channel %d det 720p nstc", ch);
+			reso = NVP_RESO_720P_NSTC;
 			break;
 		case NVP_RESO_720P_PAL_VALUE:
-				dev_dbg(&client->dev, "channel %d det 720p pal", ch);
-				reso = NVP_RESO_720P_PAL;
+			dev_dbg(&client->dev, "channel %d det 720p pal", ch);
+			reso = NVP_RESO_720P_PAL;
 			break;
 		case NVP_RESO_1080P_NSTC_VALUE:
-				dev_dbg(&client->dev, "channel %d det 1080p nstc", ch);
-				reso = NVP_RESO_1080P_NSTC;
+			dev_dbg(&client->dev, "channel %d det 1080p nstc", ch);
+			reso = NVP_RESO_1080P_NSTC;
 			break;
 		case NVP_RESO_1080P_PAL_VALUE:
-				dev_dbg(&client->dev, "channel %d det 1080p pal", ch);
-				reso = NVP_RESO_1080P_PAL;
+			dev_dbg(&client->dev, "channel %d det 1080p pal", ch);
+			reso = NVP_RESO_1080P_PAL;
 			break;
 		case NVP_RESO_960P_NSTC_VALUE:
-				dev_dbg(&client->dev, "channel %d det 960p nstc", ch);
-				reso = NVP_RESO_960P_NSTC;
+			dev_dbg(&client->dev, "channel %d det 960p nstc", ch);
+			reso = NVP_RESO_960P_NSTC;
 			break;
 		case NVP_RESO_960P_PAL_VALUE:
-				dev_dbg(&client->dev, "channel %d det 960p pal", ch);
-				reso = NVP_RESO_960P_PAL;
+			dev_dbg(&client->dev, "channel %d det 960p pal", ch);
+			reso = NVP_RESO_960P_PAL;
+			break;
+		case NVP_RESO_1300P_NSTC_VALUE:
+			dev_dbg(&client->dev, "channel %d det 1300p nstc", ch);
+			reso = NVP_RESO_1300P_NSTC;
+			break;
+		case NVP_RESO_1300P_PAL_VALUE:
+			dev_dbg(&client->dev, "channel %d det 1300p pal", ch);
+			reso = NVP_RESO_1300P_PAL;
 			break;
 		default:
-				dev_dbg(&client->dev, "channel %d not detect\n", ch);
-				reso = NVP_RESO_UNKOWN;
+			dev_dbg(&client->dev, "channel %d not detect\n", ch);
+			reso = NVP_RESO_UNKOWN;
 			break;
 		}
 
 		if (reso != nvp6188->cur_mode.channel_reso[ch]) {
-			if ((nvp6188->cur_mode.channel_reso[ch] != NVP_RESO_UNKOWN) &&
-				(reso == NVP_RESO_UNKOWN) &&
-				((nvp6188->detect_status & (0x01 << ch)) == 0)) {
+			if (nvp6188->cur_mode.channel_reso[ch] != NVP_RESO_UNKOWN &&
+			    reso == NVP_RESO_UNKOWN &&
+			    (nvp6188->detect_status & (0x01 << ch)) == 0) {
 				dev_info(&client->dev, "channel(%d) fmt(%d) -> invalid(0x%x)",
-					ch, nvp6188->cur_mode.channel_reso[ch], ch_vfc);
-				return;
+					 ch, nvp6188->cur_mode.channel_reso[ch], ch_vfc);
+				if (nvp6188->cur_mode.unkown_reso_count[ch] < 5) {
+					nvp6188_write_reg(client, 0xFF, 0x13);
+					nvp6188_read_reg(client, 0x70, &val_13x70);
+					val_13x70 &= ~(0x01 << ch);
+					nvp6188_write_reg(client, 0x70, val_13x70);
+					nvp6188->cur_mode.unkown_reso_count[ch]++;
+					continue;
+				}
 			}
-
 			dev_info(&client->dev, "channel(%d) fmt(%d) -> cur(%d)",
-				ch, nvp6188->cur_mode.channel_reso[ch], reso);
+					 ch, nvp6188->cur_mode.channel_reso[ch], reso);
 			nvp6188_manual_mode(nvp6188, ch, reso);
 			nvp6188->cur_mode.channel_reso[ch] = reso;
 		}
@@ -1745,21 +2006,22 @@
 	struct nvp6188 *nvp6188 = (struct nvp6188 *) data;
 	struct i2c_client *client = nvp6188->client;
 	int need_reset_wait = -1;
-
+	nvp6188->disable_dump_register = true;
 	if (nvp6188->power_on) {
 		nvp6188_auto_detect_hotplug(nvp6188);
 		nvp6188->last_detect_status = nvp6188->detect_status;
 		nvp6188->is_reset = 0;
 	}
 	while (!kthread_should_stop()) {
-		if (nvp6188->power_on) {
+		if (nvp6188->disable_dump_register && nvp6188->power_on) {
 			mutex_lock(&nvp6188->mutex);
 			nvp6188_auto_detect_hotplug(nvp6188);
 			nvp6188_auto_detect_fmt(nvp6188);
+
 			mutex_unlock(&nvp6188->mutex);
 			if (nvp6188->last_detect_status != nvp6188->detect_status) {
 				dev_info(&client->dev, "last_detect_status(0x%x) -> detect_status(0x%x)",
-					nvp6188->last_detect_status, nvp6188->detect_status);
+					 nvp6188->last_detect_status, nvp6188->detect_status);
 				nvp6188->last_detect_status = nvp6188->detect_status;
 				input_event(nvp6188->input_dev, EV_MSC, MSC_RAW, nvp6188->detect_status);
 				input_sync(nvp6188->input_dev);
@@ -1770,7 +2032,7 @@
 			} else if (need_reset_wait == 0) {
 				need_reset_wait = -1;
 				nvp6188->is_reset = 1;
-				dev_err(&client->dev, "trigger reset time up\n");
+				dev_info(&client->dev, "trigger reset time up\n");
 			}
 		}
 		set_current_state(TASK_INTERRUPTIBLE);
@@ -1785,6 +2047,7 @@
 	struct i2c_client *client = nvp6188->client;
 	nvp6188->detect_thread = kthread_create(detect_thread_function,
                                    nvp6188, "nvp6188_kthread");
+
 	if (IS_ERR(nvp6188->detect_thread)) {
 		dev_err(&client->dev, "kthread_create nvp6188_kthread failed\n");
 		ret = PTR_ERR(nvp6188->detect_thread);
@@ -1800,19 +2063,21 @@
 	if (nvp6188->detect_thread)
 		kthread_stop(nvp6188->detect_thread);
 	nvp6188->detect_thread = NULL;
+
 	return 0;
 }
 
-static int nvp6188_reg_check(struct nvp6188 *nvp6188)
+static int __maybe_unused nvp6188_reg_check(struct nvp6188 *nvp6188)
 {
 	unsigned char val_20x52 = 0, val_20x53 = 0;
-	unsigned char val_20x52_bak = 0, val_20x53_bak = 0;
-	int check_value1, check_value2, check_cnt = 10;
+	int check_value1 = 0, check_value2 = 0, check_cnt = 10;
 	struct i2c_client *client = nvp6188->client;
 
-	dev_dbg(&client->dev, "[%s::%d]\n", __func__, __LINE__);
 	nvp6188_write_reg(client, 0xff, 0x20);
 	nvp6188_write_reg(client, 0x00, 0xff); // open mipi
+	usleep_range(100 * 1000, 100 * 1000);
+	//nvp6188_write_reg(client, 0x40, 0x01);
+	//nvp6188_write_reg(client, 0x40, 0x00);
 	while (check_cnt--) {
 		nvp6188_write_reg(client, 0xff, 0x20);
 		nvp6188_read_reg(client, 0x52, &val_20x52);
@@ -1820,25 +2085,48 @@
 		check_value1 = (val_20x52 << 8) | val_20x53;
 		usleep_range(80 * 1000, 100 * 1000);
 		nvp6188_write_reg(client, 0xff, 0x20);
-		nvp6188_read_reg(client, 0x52, &val_20x52_bak);
-		nvp6188_read_reg(client, 0x53, &val_20x53_bak);
-		check_value2 = (val_20x52_bak << 8) | val_20x53_bak;
-		if (check_value1 == check_value2) {
-			dev_info(&client->dev, "attention!!! check cnt = %d\n", check_cnt);
+		nvp6188_read_reg(client, 0x52, &val_20x52);
+		nvp6188_read_reg(client, 0x53, &val_20x53);
+		check_value2 = (val_20x52 << 8) | val_20x53;
+		if (check_value2 <= 2 || check_value1 == check_value2) {
+			dev_err(&client->dev, "attention!!! check cnt = %d\n", check_cnt);
 			nvp6188_write_reg(client, 0xff, 0x01);
 			nvp6188_write_reg(client, 0x97, 0xf0);
 			usleep_range(40 * 1000, 50 * 1000);
 			nvp6188_write_reg(client, 0x97, 0x0f);
 		} else {
 			dev_err(&client->dev, "check_value1=%x, check_value2=%x,check cnt = %d\n",
-				check_value1, check_value2, check_cnt);
+					check_value1, check_value2, check_cnt);
 			break;
 		}
 	}
-
 	return check_cnt;
 }
-static int __nvp6188_start_stream(struct nvp6188 *nvp6188)
+
+static int nvp6188_auto_det_set(struct nvp6188 *nvp6188)
+{
+	struct i2c_client *client = nvp6188->client;
+
+	dev_info(&client->dev, "[%s::%d]\n", __func__, __LINE__);
+
+	nvp6188_write_reg(client, 0xff, 0x13);
+	nvp6188_write_reg(client, 0x30, 0x7f);
+	nvp6188_write_reg(client, 0x70, 0xf0);
+	nvp6188_write_reg(client, 0xff, 0x00);
+	nvp6188_write_reg(client, 0x00, 0x18);
+	nvp6188_write_reg(client, 0x01, 0x18);
+	nvp6188_write_reg(client, 0x02, 0x18);
+	nvp6188_write_reg(client, 0x03, 0x18);
+	usleep_range(30 * 1000, 40 * 1000);
+	nvp6188_write_reg(client, 0x00, 0x10);
+	nvp6188_write_reg(client, 0x01, 0x10);
+	nvp6188_write_reg(client, 0x02, 0x10);
+	nvp6188_write_reg(client, 0x03, 0x10);
+
+	return 0;
+}
+
+static int nvp6188_video_init(struct nvp6188 *nvp6188)
 {
 	int ret;
 	int array_size = 0;
@@ -1855,20 +2143,28 @@
 	ret = nvp6188_write_array(nvp6188->client,
 		nvp6188->cur_mode.global_reg_list, array_size);
 	if (ret) {
-		dev_err(&client->dev, "%s: global_reg_list failed", __func__);
-		return ret;
-	}
-
-	ret = nvp6188_write_array(nvp6188->client,
-		auto_detect_regs, ARRAY_SIZE(auto_detect_regs));
-	if (ret) {
-		dev_err(&client->dev, "%s: auto_detect_regs failed", __func__);
+		dev_err(&client->dev, "__nvp6188_start_stream global_reg_list faild");
 		return ret;
 	}
 
 	nvp6188_init_default_fmt(nvp6188, NVP_RESO_UNKOWN);
-	usleep_range(500*1000, 1000*1000);
+	nvp6188_auto_det_set(nvp6188);
+	usleep_range(150*1000, 150*1000);
 	nvp6188_auto_detect_fmt(nvp6188);
+
+	return 0;
+}
+
+static int __nvp6188_start_stream(struct nvp6188 *nvp6188)
+{
+	struct i2c_client *client = nvp6188->client;
+
+	if (nvp6188->detect_thread) {
+		nvp6188_write_reg(client, 0xff, 0x20);
+		nvp6188_write_reg(client, 0x00, 0xff);
+		return 0;
+	}
+
 	nvp6188_audio_init(nvp6188);
 	nvp6188_reg_check(nvp6188);
 	detect_thread_start(nvp6188);
@@ -1878,11 +2174,14 @@
 static int __nvp6188_stop_stream(struct nvp6188 *nvp6188)
 {
 	struct i2c_client *client = nvp6188->client;
+
 	nvp6188_write_reg(client, 0xff, 0x20);
 	nvp6188_write_reg(client, 0x00, 0x00);
 	nvp6188_write_reg(client, 0x40, 0x01);
 	nvp6188_write_reg(client, 0x40, 0x00);
-	detect_thread_stop(nvp6188);
+	//detect_thread_stop(nvp6188);
+	usleep_range(100 * 1000, 150 * 1000);
+
 	return 0;
 }
 
@@ -1891,7 +2190,7 @@
 	struct nvp6188 *nvp6188 = to_nvp6188(sd);
 	struct i2c_client *client = nvp6188->client;
 
-	dev_err(&client->dev, "s_stream: %d. %dx%d\n", on,
+	dev_info(&client->dev, "s_stream: %d. %dx%d\n", on,
 			nvp6188->cur_mode.width,
 			nvp6188->cur_mode.height);
 
@@ -1925,8 +2224,6 @@
 	/* If the power state is not modified - no work to do. */
 	if (nvp6188->power_on == !!on)
 		goto exit;
-
-	dev_err(&client->dev, "%s: on %d\n", __func__, on);
 
 	if (on) {
 		ret = pm_runtime_get_sync(&client->dev);
@@ -1985,7 +2282,7 @@
 		gpiod_set_value_cansleep(nvp6188->reset_gpio, 0);
 		usleep_range(10 * 1000, 20 * 1000);
 		gpiod_set_value_cansleep(nvp6188->reset_gpio, 1);
-		usleep_range(10 * 1000, 20 * 1000);
+		usleep_range(100 * 1000, 110 * 1000);
 
 		//Resolve audio register reset caused by reset_gpio
 		nvp6188_audio_init(nvp6188);
@@ -2059,9 +2356,9 @@
 		goto err_free_handler;
 	}
 
-	dev_info(&nvp6188->client->dev, "mipi_freq_idx %d\n", mode->mipi_freq_idx);
-	dev_info(&nvp6188->client->dev, "pixel_rate %lld\n", pixel_rate);
-	dev_info(&nvp6188->client->dev, "link_freq %lld\n", link_freq_items[mode->mipi_freq_idx]);
+	dev_dbg(&nvp6188->client->dev, "mipi_freq_idx %d\n", mode->mipi_freq_idx);
+	dev_dbg(&nvp6188->client->dev, "pixel_rate %lld\n", pixel_rate);
+	dev_dbg(&nvp6188->client->dev, "link_freq %lld\n", link_freq_items[mode->mipi_freq_idx]);
 
 	nvp6188->subdev.ctrl_handler = handler;
 
@@ -2073,7 +2370,7 @@
 	return ret;
 }
 
-static int nvp6188_runtime_resume(struct device *dev)
+static int __maybe_unused nvp6188_runtime_resume(struct device *dev)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
@@ -2082,7 +2379,7 @@
 	return __nvp6188_power_on(nvp6188);
 }
 
-static int nvp6188_runtime_suspend(struct device *dev)
+static int __maybe_unused nvp6188_runtime_suspend(struct device *dev)
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct v4l2_subdev *sd = i2c_get_clientdata(client);
@@ -2125,14 +2422,16 @@
 
 static const struct v4l2_subdev_video_ops nvp6188_video_ops = {
 	.s_stream = nvp6188_stream,
-	.g_mbus_config = nvp6188_g_mbus_config,
+	.g_frame_interval = nvp6188_g_frame_interval,
 };
 
 static const struct v4l2_subdev_pad_ops nvp6188_subdev_pad_ops = {
 	.enum_mbus_code = nvp6188_enum_mbus_code,
 	.enum_frame_size = nvp6188_enum_frame_sizes,
+	.enum_frame_interval = nvp6188_enum_frame_interval,
 	.get_fmt = nvp6188_get_fmt,
 	.set_fmt = nvp6188_set_fmt,
+	.get_mbus_config = nvp6188_g_mbus_config,
 };
 
 static const struct v4l2_subdev_core_ops nvp6188_core_ops = {
@@ -2161,12 +2460,15 @@
 	int ret;
 	u8 val;
 
+	mutex_lock(&nvp6188->mutex);
 	ret = nvp6188_read_reg(client, reg, &val);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s failed: (%d)\n", __func__, ret);
+		mutex_unlock(&nvp6188->mutex);
 		return ret;
 	}
 
+	mutex_unlock(&nvp6188->mutex);
 	return val;
 }
 
@@ -2178,12 +2480,15 @@
 	struct i2c_client *client = nvp6188->client;
 	int ret;
 
+	mutex_lock(&nvp6188->mutex);
 	ret = nvp6188_write_reg(client, reg, val);
 	if (ret < 0) {
 		dev_err(&client->dev, "%s failed: (%d)\n", __func__, ret);
+		mutex_unlock(&nvp6188->mutex);
 		return ret;
 	}
 
+	mutex_unlock(&nvp6188->mutex);
 	return 0;
 }
 
@@ -2204,7 +2509,9 @@
 	struct nvp6188 *nvp6188 = to_nvp6188(sd);
 	struct i2c_client *client = nvp6188->client;
 	u8 val_rm = 0, val_pb = 0;
+	int ret = 0;
 
+	mutex_lock(&nvp6188->mutex);
 	nvp6188_write_reg(client, 0xff, 0x01); /* Switch to bank1 for audio */
 	nvp6188_read_reg(client, 0x07, &val_rm);
 	nvp6188_read_reg(client, 0x13, &val_pb);
@@ -2219,7 +2526,8 @@
 		val_pb &= (~0x80);
 		break;
 	default:
-		return -EINVAL;
+		ret = -EINVAL;
+		goto unlock;
 	}
 
 	/* interface format */
@@ -2237,7 +2545,8 @@
 		val_pb |= 0x03;
 		break;
 	default:
-		return -EINVAL;
+		ret = -EINVAL;
+		goto unlock;
 	}
 
 	/* clock inversion */
@@ -2251,13 +2560,17 @@
 		val_pb |= 0x40;
 		break;
 	default:
-		return -EINVAL;
+		ret = -EINVAL;
+		goto unlock;
 	}
 
 	nvp6188_write_reg(client, 0x07, val_rm);
 	nvp6188_write_reg(client, 0x13, val_pb);
 
-	return 0;
+unlock:
+	mutex_unlock(&nvp6188->mutex);
+
+	return ret;
 }
 
 static int nvp6188_pcm_hw_params(struct snd_pcm_substream *substream,
@@ -2268,7 +2581,9 @@
 	struct nvp6188 *nvp6188 = to_nvp6188(sd);
 	struct i2c_client *client = nvp6188->client;
 	u8 val = 0;
+	int ret = 0;
 
+	mutex_lock(&nvp6188->mutex);
 	nvp6188_write_reg(client, 0xff, 0x01); /* Switch to bank1 for audio */
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -2282,7 +2597,8 @@
 			val &= (~0x04);
 			break;
 		default:
-			return -EINVAL;
+			ret = -EINVAL;
+			goto unlock;
 		}
 
 		switch (params_rate(params)) {
@@ -2296,7 +2612,8 @@
 			/* TODO */
 			break;
 		default:
-			return -EINVAL;
+			ret = -EINVAL;
+			goto unlock;
 		}
 
 		if (nvp6188->audio_out) {
@@ -2313,7 +2630,8 @@
 			default:
 				dev_err(&client->dev, "Invalid audio_out mclk_fs: %d\n",
 					nvp6188->audio_out->mclk_fs);
-				return -EINVAL;
+				ret = -EINVAL;
+				goto unlock;
 			}
 		}
 
@@ -2329,7 +2647,8 @@
 			val &= (~0x04);
 			break;
 		default:
-			return -EINVAL;
+			ret = -EINVAL;
+			goto unlock;
 		}
 
 		switch (params_rate(params)) {
@@ -2343,7 +2662,8 @@
 			/* TODO */
 			break;
 		default:
-			return -EINVAL;
+			ret = -EINVAL;
+			goto unlock;
 		}
 
 		if (nvp6188->audio_in) {
@@ -2360,7 +2680,8 @@
 			default:
 				dev_err(&client->dev, "Invalid audio_in mclk_fs: %d\n",
 					nvp6188->audio_in->mclk_fs);
-				return -EINVAL;
+				ret = -EINVAL;
+				goto unlock;
 			}
 		}
 		nvp6188_write_reg(client, 0x07, val);
@@ -2376,12 +2697,16 @@
 		default:
 			dev_err(&client->dev, "Not supported channels: %d\n",
 				params_channels(params));
-			return -EINVAL;
+			ret = -EINVAL;
+			goto unlock;
 		}
 		nvp6188_write_reg(client, 0x08, val);
 	}
 
-	return 0;
+unlock:
+	mutex_unlock(&nvp6188->mutex);
+
+	return ret;
 }
 
 static int nvp6188_pcm_mute(struct snd_soc_dai *dai, int mute, int stream)
@@ -2440,7 +2765,9 @@
 	struct nvp6188 *nvp6188 = to_nvp6188(sd);
 	struct i2c_client *client = nvp6188->client;
 
+	mutex_lock(&nvp6188->mutex);
 	nvp6188_write_reg(client, 0xff, 0x01); /* Switch to bank1 for audio */
+	mutex_unlock(&nvp6188->mutex);
 	return snd_soc_get_volsw(kcontrol, ucontrol);
 }
 
@@ -2826,6 +3153,8 @@
 	pm_runtime_enable(dev);
 	pm_runtime_idle(dev);
 
+	nvp6188_video_init(nvp6188);
+
 	return 0;
 
 err_clean_entity:
@@ -2862,7 +3191,7 @@
 	return 0;
 }
 
-static const struct dev_pm_ops nvp6188_pm_ops = {
+static const struct dev_pm_ops __maybe_unused nvp6188_pm_ops = {
 	SET_RUNTIME_PM_OPS(nvp6188_runtime_suspend,
 			   nvp6188_runtime_resume, NULL)
 };
@@ -2883,7 +3212,7 @@
 static struct i2c_driver nvp6188_i2c_driver = {
 	.driver = {
 		.name = NVP6188_NAME,
-		.pm = &nvp6188_pm_ops,
+		//.pm = &nvp6188_pm_ops,
 		.of_match_table = of_match_ptr(nvp6188_of_match),
 	},
 	.probe		= &nvp6188_probe,
@@ -2891,17 +3220,20 @@
 	.id_table	= nvp6188_match_id,
 };
 
-static int __init sensor_mod_init(void)
+int nvp6188_sensor_mod_init(void)
 {
 	return i2c_add_driver(&nvp6188_i2c_driver);
 }
+
+#ifndef CONFIG_VIDEO_REVERSE_IMAGE
+device_initcall_sync(nvp6188_sensor_mod_init);
+#endif
 
 static void __exit sensor_mod_exit(void)
 {
 	i2c_del_driver(&nvp6188_i2c_driver);
 }
 
-device_initcall_sync(sensor_mod_init);
 module_exit(sensor_mod_exit);
 
 MODULE_AUTHOR("Vicent Chi <vicent.chi@rock-chips.com>");

--
Gitblit v1.6.2