From 534b6bc119e761da1aa2b1aabcb13f3b9878e7ec Mon Sep 17 00:00:00 2001
From: Lee Jackson <lee.jackson@arducam.com>
Date: Wed, 22 Mar 2023 16:19:13 +0800
Subject: [PATCH] media: i2c: Add PDAF support for IMX519

Add PDAF support for IMX519, and reduce the pixel rate to 426666667,
link freq to 408000000.

Signed-off-by: Lee Jackson <lee.jackson@arducam.com>
---
 drivers/media/i2c/imx519.c | 170 +++++++++++++++++++++++--------------
 1 file changed, 106 insertions(+), 64 deletions(-)

--- a/drivers/media/i2c/imx519.c
+++ b/drivers/media/i2c/imx519.c
@@ -36,10 +36,10 @@
 
 #define IMX519_XCLK_FREQ		24000000
 
-#define IMX519_DEFAULT_LINK_FREQ	493500000
+#define IMX519_DEFAULT_LINK_FREQ	408000000
 
-/* Pixel rate is fixed at 686MHz for all the modes */
-#define IMX519_PIXEL_RATE		686000000
+/* Pixel rate is fixed at 426MHz for all the modes */
+#define IMX519_PIXEL_RATE		426666667
 
 /* V_TIMING internal */
 #define IMX519_REG_FRAME_LENGTH		0x0340
@@ -52,7 +52,7 @@
 /* Exposure control */
 #define IMX519_REG_EXPOSURE		0x0202
 #define IMX519_EXPOSURE_OFFSET		32
-#define IMX519_EXPOSURE_MIN		1
+#define IMX519_EXPOSURE_MIN		20
 #define IMX519_EXPOSURE_STEP		1
 #define IMX519_EXPOSURE_DEFAULT		0x3e8
 #define IMX519_EXPOSURE_MAX		(IMX519_FRAME_LENGTH_MAX - \
@@ -94,7 +94,7 @@
 #define IMX519_TEST_PATTERN_GB_DEFAULT	0
 
 /* Embedded metadata stream structure */
-#define IMX519_EMBEDDED_LINE_WIDTH 16384
+#define IMX519_EMBEDDED_LINE_WIDTH (5820 * 3)
 #define IMX519_NUM_EMBEDDED_LINES 1
 
 enum pad_types {
@@ -146,6 +146,7 @@ struct imx519_mode {
 };
 
 static const struct imx519_reg mode_common_regs[] = {
+	{0x0100, 0x00},
 	{0x0136, 0x18},
 	{0x0137, 0x00},
 	{0x3c7e, 0x01},
@@ -418,6 +419,7 @@ static const struct imx519_reg mode_comm
 	{0xae05, 0x03},
 	{0xbc1c, 0x08},
 	{0xbcf1, 0x02},
+	{0x38a3, 0x00},
 };
 
 /* 16 mpix 10fps */
@@ -426,8 +428,8 @@ static const struct imx519_reg mode_4656
 	{0x0112, 0x0a},
 	{0x0113, 0x0a},
 	{0x0114, 0x01},
-	{0x0342, 0x42},
-	{0x0343, 0x00},
+	{0x0342, 0x31},
+	{0x0343, 0x6a},
 	{0x0340, 0x0d},
 	{0x0341, 0xf4},
 	{0x0344, 0x00},
@@ -464,22 +466,30 @@ static const struct imx519_reg mode_4656
 	{0x034f, 0xa8},
 	{0x0301, 0x06},
 	{0x0303, 0x04},
-	{0x0305, 0x04},
+	{0x0305, 0x06},
 	{0x0306, 0x01},
-	{0x0307, 0x57},
+	{0x0307, 0x40},
 	{0x0309, 0x0a},
 	{0x030b, 0x02},
 	{0x030d, 0x04},
 	{0x030e, 0x01},
-	{0x030f, 0x49},
+	{0x030f, 0x10},
 	{0x0310, 0x01},
-	{0x0820, 0x07},
-	{0x0821, 0xb6},
+	{0x0820, 0x0a},
+	{0x0821, 0x20},
 	{0x0822, 0x00},
 	{0x0823, 0x00},
 	{0x3e20, 0x01},
-	{0x3e37, 0x00},
+	{0x3e37, 0x01},
 	{0x3e3b, 0x00},
+	{0x38a4, 0x00},
+	{0x38a5, 0x00},
+	{0x38a6, 0x00},
+	{0x38a7, 0x00},
+	{0x38a8, 0x01},
+	{0x38a9, 0x23},
+	{0x38aa, 0x01},
+	{0x38ab, 0x23},
 	{0x0106, 0x00},
 	{0x0b00, 0x00},
 	{0x3230, 0x00},
@@ -503,8 +513,8 @@ static const struct imx519_reg mode_3840
 	{0x0112, 0x0a},
 	{0x0113, 0x0a},
 	{0x0114, 0x01},
-	{0x0342, 0x38},
-	{0x0343, 0x70},
+	{0x0342, 0x28},
+	{0x0343, 0xf6},
 	{0x0340, 0x08},
 	{0x0341, 0xd4},
 	{0x0344, 0x01},
@@ -541,22 +551,30 @@ static const struct imx519_reg mode_3840
 	{0x034f, 0x70},
 	{0x0301, 0x06},
 	{0x0303, 0x04},
-	{0x0305, 0x04},
+	{0x0305, 0x06},
 	{0x0306, 0x01},
-	{0x0307, 0x57},
+	{0x0307, 0x40},
 	{0x0309, 0x0a},
 	{0x030b, 0x02},
 	{0x030d, 0x04},
 	{0x030e, 0x01},
-	{0x030f, 0x49},
+	{0x030f, 0x10},
 	{0x0310, 0x01},
-	{0x0820, 0x07},
-	{0x0821, 0xb6},
+	{0x0820, 0x0a},
+	{0x0821, 0x20},
 	{0x0822, 0x00},
 	{0x0823, 0x00},
 	{0x3e20, 0x01},
-	{0x3e37, 0x00},
+	{0x3e37, 0x01},
 	{0x3e3b, 0x00},
+	{0x38a4, 0x00},
+	{0x38a5, 0x00},
+	{0x38a6, 0x00},
+	{0x38a7, 0x00},
+	{0x38a8, 0x00},
+	{0x38a9, 0xf0},
+	{0x38aa, 0x00},
+	{0x38ab, 0xb4},
 	{0x0106, 0x00},
 	{0x0b00, 0x00},
 	{0x3230, 0x00},
@@ -580,10 +598,10 @@ static const struct imx519_reg mode_2328
 	{0x0112, 0x0a},
 	{0x0113, 0x0a},
 	{0x0114, 0x01},
-	{0x0342, 0x24},
-	{0x0343, 0x12},
-	{0x0340, 0x09},
-	{0x0341, 0xac},
+	{0x0342, 0x19},
+	{0x0343, 0x70},
+	{0x0340, 0x08},
+	{0x0341, 0x88},
 	{0x0344, 0x00},
 	{0x0345, 0x00},
 	{0x0346, 0x00},
@@ -598,8 +616,8 @@ static const struct imx519_reg mode_2328
 	{0x0900, 0x01},
 	{0x0901, 0x22},
 	{0x0902, 0x0a},
-	{0x3f4c, 0x01},
-	{0x3f4d, 0x01},
+	{0x3f4c, 0x05},
+	{0x3f4d, 0x03},
 	{0x4254, 0x7f},
 	{0x0401, 0x00},
 	{0x0404, 0x00},
@@ -618,22 +636,30 @@ static const struct imx519_reg mode_2328
 	{0x034f, 0xd4},
 	{0x0301, 0x06},
 	{0x0303, 0x04},
-	{0x0305, 0x04},
+	{0x0305, 0x06},
 	{0x0306, 0x01},
-	{0x0307, 0x57},
+	{0x0307, 0x40},
 	{0x0309, 0x0a},
 	{0x030b, 0x02},
 	{0x030d, 0x04},
 	{0x030e, 0x01},
-	{0x030f, 0x49},
+	{0x030f, 0x10},
 	{0x0310, 0x01},
-	{0x0820, 0x07},
-	{0x0821, 0xb6},
+	{0x0820, 0x0a},
+	{0x0821, 0x20},
 	{0x0822, 0x00},
 	{0x0823, 0x00},
 	{0x3e20, 0x01},
-	{0x3e37, 0x00},
+	{0x3e37, 0x01},
 	{0x3e3b, 0x00},
+	{0x38a4, 0x00},
+	{0x38a5, 0x00},
+	{0x38a6, 0x00},
+	{0x38a7, 0x00},
+	{0x38a8, 0x00},
+	{0x38a9, 0x91},
+	{0x38aa, 0x00},
+	{0x38ab, 0x91},
 	{0x0106, 0x00},
 	{0x0b00, 0x00},
 	{0x3230, 0x00},
@@ -657,8 +683,8 @@ static const struct imx519_reg mode_1920
 	{0x0112, 0x0a},
 	{0x0113, 0x0a},
 	{0x0114, 0x01},
-	{0x0342, 0x25},
-	{0x0343, 0xd9},
+	{0x0342, 0x17},
+	{0x0343, 0x8b},
 	{0x0340, 0x04},
 	{0x0341, 0x9c},
 	{0x0344, 0x01},
@@ -675,8 +701,8 @@ static const struct imx519_reg mode_1920
 	{0x0900, 0x01},
 	{0x0901, 0x22},
 	{0x0902, 0x0a},
-	{0x3f4c, 0x01},
-	{0x3f4d, 0x01},
+	{0x3f4c, 0x05},
+	{0x3f4d, 0x03},
 	{0x4254, 0x7f},
 	{0x0401, 0x00},
 	{0x0404, 0x00},
@@ -695,22 +721,30 @@ static const struct imx519_reg mode_1920
 	{0x034f, 0x38},
 	{0x0301, 0x06},
 	{0x0303, 0x04},
-	{0x0305, 0x04},
+	{0x0305, 0x06},
 	{0x0306, 0x01},
-	{0x0307, 0x57},
+	{0x0307, 0x40},
 	{0x0309, 0x0a},
 	{0x030b, 0x02},
 	{0x030d, 0x04},
 	{0x030e, 0x01},
-	{0x030f, 0x49},
+	{0x030f, 0x10},
 	{0x0310, 0x01},
-	{0x0820, 0x07},
-	{0x0821, 0xb6},
+	{0x0820, 0x0a},
+	{0x0821, 0x20},
 	{0x0822, 0x00},
 	{0x0823, 0x00},
 	{0x3e20, 0x01},
-	{0x3e37, 0x00},
+	{0x3e37, 0x01},
 	{0x3e3b, 0x00},
+	{0x38a4, 0x00},
+	{0x38a5, 0x00},
+	{0x38a6, 0x00},
+	{0x38a7, 0x00},
+	{0x38a8, 0x00},
+	{0x38a9, 0x78},
+	{0x38aa, 0x00},
+	{0x38ab, 0x5a},
 	{0x0106, 0x00},
 	{0x0b00, 0x00},
 	{0x3230, 0x00},
@@ -734,8 +768,8 @@ static const struct imx519_reg mode_1280
 	{0x0112, 0x0a},
 	{0x0113, 0x0a},
 	{0x0114, 0x01},
-	{0x0342, 0x1b},
-	{0x0343, 0x3b},
+	{0x0342, 0x18},
+	{0x0343, 0x00},
 	{0x0340, 0x03},
 	{0x0341, 0x34},
 	{0x0344, 0x04},
@@ -752,8 +786,8 @@ static const struct imx519_reg mode_1280
 	{0x0900, 0x01},
 	{0x0901, 0x22},
 	{0x0902, 0x0a},
-	{0x3f4c, 0x01},
-	{0x3f4d, 0x01},
+	{0x3f4c, 0x05},
+	{0x3f4d, 0x03},
 	{0x4254, 0x7f},
 	{0x0401, 0x00},
 	{0x0404, 0x00},
@@ -772,22 +806,30 @@ static const struct imx519_reg mode_1280
 	{0x034f, 0xd0},
 	{0x0301, 0x06},
 	{0x0303, 0x04},
-	{0x0305, 0x04},
+	{0x0305, 0x06},
 	{0x0306, 0x01},
-	{0x0307, 0x57},
+	{0x0307, 0x40},
 	{0x0309, 0x0a},
 	{0x030b, 0x02},
 	{0x030d, 0x04},
 	{0x030e, 0x01},
-	{0x030f, 0x49},
+	{0x030f, 0x10},
 	{0x0310, 0x01},
-	{0x0820, 0x07},
-	{0x0821, 0xb6},
+	{0x0820, 0x0a},
+	{0x0821, 0x20},
 	{0x0822, 0x00},
 	{0x0823, 0x00},
 	{0x3e20, 0x01},
-	{0x3e37, 0x00},
+	{0x3e37, 0x01},
 	{0x3e3b, 0x00},
+	{0x38a4, 0x00},
+	{0x38a5, 0x00},
+	{0x38a6, 0x00},
+	{0x38a7, 0x00},
+	{0x38a8, 0x00},
+	{0x38a9, 0x50},
+	{0x38aa, 0x00},
+	{0x38ab, 0x3c},
 	{0x0106, 0x00},
 	{0x0b00, 0x00},
 	{0x3230, 0x00},
@@ -810,7 +852,7 @@ static const struct imx519_mode supporte
 	{
 		.width = 4656,
 		.height = 3496,
-		.line_length_pix = 0x4200,
+		.line_length_pix = 0x316a,
 		.crop = {
 			.left = IMX519_PIXEL_ARRAY_LEFT,
 			.top = IMX519_PIXEL_ARRAY_TOP,
@@ -819,11 +861,11 @@ static const struct imx519_mode supporte
 		},
 		.timeperframe_min = {
 			.numerator = 100,
-			.denominator = 1000
+			.denominator = 900
 		},
 		.timeperframe_default = {
 			.numerator = 100,
-			.denominator = 1000
+			.denominator = 900
 		},
 		.reg_list = {
 			.num_of_regs = ARRAY_SIZE(mode_4656x3496_regs),
@@ -833,7 +875,7 @@ static const struct imx519_mode supporte
 	{
 		.width = 3840,
 		.height = 2160,
-		.line_length_pix = 0x3870,
+		.line_length_pix = 0x28f6,
 		.crop = {
 			.left = IMX519_PIXEL_ARRAY_LEFT + 408,
 			.top = IMX519_PIXEL_ARRAY_TOP + 672,
@@ -842,11 +884,11 @@ static const struct imx519_mode supporte
 		},
 		.timeperframe_min = {
 			.numerator = 100,
-			.denominator = 2100
+			.denominator = 1800
 		},
 		.timeperframe_default = {
 			.numerator = 100,
-			.denominator = 2100
+			.denominator = 1800
 		},
 		.reg_list = {
 			.num_of_regs = ARRAY_SIZE(mode_3840x2160_regs),
@@ -856,7 +898,7 @@ static const struct imx519_mode supporte
 	{
 		.width = 2328,
 		.height = 1748,
-		.line_length_pix = 0x2412,
+		.line_length_pix = 0x1970,
 		.crop = {
 			.left = IMX519_PIXEL_ARRAY_LEFT,
 			.top = IMX519_PIXEL_ARRAY_TOP,
@@ -879,7 +921,7 @@ static const struct imx519_mode supporte
 	{
 		.width = 1920,
 		.height = 1080,
-		.line_length_pix = 0x25D9,
+		.line_length_pix = 0x178b,
 		.crop = {
 			.left = IMX519_PIXEL_ARRAY_LEFT + 408,
 			.top = IMX519_PIXEL_ARRAY_TOP + 674,
@@ -902,7 +944,7 @@ static const struct imx519_mode supporte
 	{
 		.width = 1280,
 		.height = 720,
-		.line_length_pix = 0x1B3B,
+		.line_length_pix = 0x1800,
 		.crop = {
 			.left = IMX519_PIXEL_ARRAY_LEFT + 1048,
 			.top = IMX519_PIXEL_ARRAY_TOP + 1042,
@@ -911,11 +953,11 @@ static const struct imx519_mode supporte
 		},
 		.timeperframe_min = {
 			.numerator = 100,
-			.denominator = 12000
+			.denominator = 8000
 		},
 		.timeperframe_default = {
 			.numerator = 100,
-			.denominator = 12000
+			.denominator = 8000
 		},
 		.reg_list = {
 			.num_of_regs = ARRAY_SIZE(mode_1280x720_regs),
