* [PATCH 01/13] media: imx355: Remove duplicated registers from the mode tables
2026-05-06 18:23 [PATCH 00/13] media/imx355: General code cleanups, and adding support for 2 lane operation Dave Stevenson
@ 2026-05-06 18:23 ` Dave Stevenson
2026-05-07 13:41 ` Jacopo Mondi
2026-05-06 18:23 ` [PATCH 02/13] media: imx355: Remove setting FRM_LENGTH_LINES in the mode regs Dave Stevenson
` (11 subsequent siblings)
12 siblings, 1 reply; 29+ messages in thread
From: Dave Stevenson @ 2026-05-06 18:23 UTC (permalink / raw)
To: Tianshu Qiu, Sakari Ailus, Mauro Carvalho Chehab
Cc: linux-media, linux-kernel, David Heidelberg,
20260414-imx355-24mhz-v1-1-9ae77bc6e7ec, Dave Stevenson
A large number of registers are identical within all the modes.
Move those to imx355_global_regs.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/media/i2c/imx355.c | 314 +++------------------------------------------
1 file changed, 20 insertions(+), 294 deletions(-)
diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
index f9ec13bb27d1..a694d4d742ae 100644
--- a/drivers/media/i2c/imx355.c
+++ b/drivers/media/i2c/imx355.c
@@ -226,6 +226,26 @@ static const struct imx355_reg imx355_global_regs[] = {
{ 0x68b0, 0x00 },
{ 0x3058, 0x00 },
{ 0x305a, 0x00 },
+ { 0x0112, 0x0a },
+ { 0x0113, 0x0a },
+ { 0x0114, 0x03 },
+ { 0x0301, 0x05 },
+ { 0x0303, 0x01 },
+ { 0x0305, 0x02 },
+ { 0x030d, 0x02 },
+ { 0x0310, 0x00 },
+ { 0x0220, 0x00 },
+ { 0x0222, 0x01 },
+ { 0x0820, 0x0b },
+ { 0x0821, 0x40 },
+ { 0x3088, 0x04 },
+ { 0x6813, 0x02 },
+ { 0x6835, 0x07 },
+ { 0x6836, 0x01 },
+ { 0x6837, 0x04 },
+ { 0x684d, 0x07 },
+ { 0x684e, 0x01 },
+ { 0x684f, 0x04 },
};
static const struct imx355_reg_list imx355_global_setting = {
@@ -234,9 +254,6 @@ static const struct imx355_reg_list imx355_global_setting = {
};
static const struct imx355_reg mode_3268x2448_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
{ 0x0342, 0x0e },
{ 0x0343, 0x58 },
{ 0x0340, 0x0a },
@@ -249,8 +266,6 @@ static const struct imx355_reg mode_3268x2448_regs[] = {
{ 0x0349, 0xcb },
{ 0x034a, 0x09 },
{ 0x034b, 0x97 },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
{ 0x0900, 0x00 },
{ 0x0901, 0x11 },
{ 0x0902, 0x00 },
@@ -258,30 +273,11 @@ static const struct imx355_reg mode_3268x2448_regs[] = {
{ 0x034d, 0xc4 },
{ 0x034e, 0x09 },
{ 0x034f, 0x90 },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x0310, 0x00 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
};
static const struct imx355_reg mode_3264x2448_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
{ 0x0342, 0x0e },
{ 0x0343, 0x58 },
{ 0x0340, 0x0a },
@@ -294,8 +290,6 @@ static const struct imx355_reg mode_3264x2448_regs[] = {
{ 0x0349, 0xc7 },
{ 0x034a, 0x09 },
{ 0x034b, 0x97 },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
{ 0x0900, 0x00 },
{ 0x0901, 0x11 },
{ 0x0902, 0x00 },
@@ -303,30 +297,11 @@ static const struct imx355_reg mode_3264x2448_regs[] = {
{ 0x034d, 0xc0 },
{ 0x034e, 0x09 },
{ 0x034f, 0x90 },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x0310, 0x00 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
};
static const struct imx355_reg mode_3280x2464_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
{ 0x0342, 0x0e },
{ 0x0343, 0x58 },
{ 0x0340, 0x0a },
@@ -339,8 +314,6 @@ static const struct imx355_reg mode_3280x2464_regs[] = {
{ 0x0349, 0xcf },
{ 0x034a, 0x09 },
{ 0x034b, 0x9f },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
{ 0x0900, 0x00 },
{ 0x0901, 0x11 },
{ 0x0902, 0x00 },
@@ -348,30 +321,11 @@ static const struct imx355_reg mode_3280x2464_regs[] = {
{ 0x034d, 0xd0 },
{ 0x034e, 0x09 },
{ 0x034f, 0xa0 },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x0310, 0x00 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
};
static const struct imx355_reg mode_1940x1096_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
{ 0x0342, 0x0e },
{ 0x0343, 0x58 },
{ 0x0340, 0x05 },
@@ -384,8 +338,6 @@ static const struct imx355_reg mode_1940x1096_regs[] = {
{ 0x0349, 0x33 },
{ 0x034a, 0x06 },
{ 0x034b, 0xf3 },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
{ 0x0900, 0x00 },
{ 0x0901, 0x11 },
{ 0x0902, 0x00 },
@@ -393,30 +345,11 @@ static const struct imx355_reg mode_1940x1096_regs[] = {
{ 0x034d, 0x94 },
{ 0x034e, 0x04 },
{ 0x034f, 0x48 },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x0310, 0x00 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
};
static const struct imx355_reg mode_1936x1096_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
{ 0x0342, 0x0e },
{ 0x0343, 0x58 },
{ 0x0340, 0x05 },
@@ -429,8 +362,6 @@ static const struct imx355_reg mode_1936x1096_regs[] = {
{ 0x0349, 0x2f },
{ 0x034a, 0x06 },
{ 0x034b, 0xf3 },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
{ 0x0900, 0x00 },
{ 0x0901, 0x11 },
{ 0x0902, 0x00 },
@@ -438,30 +369,11 @@ static const struct imx355_reg mode_1936x1096_regs[] = {
{ 0x034d, 0x90 },
{ 0x034e, 0x04 },
{ 0x034f, 0x48 },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x0310, 0x00 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
};
static const struct imx355_reg mode_1924x1080_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
{ 0x0342, 0x0e },
{ 0x0343, 0x58 },
{ 0x0340, 0x05 },
@@ -474,8 +386,6 @@ static const struct imx355_reg mode_1924x1080_regs[] = {
{ 0x0349, 0x2b },
{ 0x034a, 0x06 },
{ 0x034b, 0xeb },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
{ 0x0900, 0x00 },
{ 0x0901, 0x11 },
{ 0x0902, 0x00 },
@@ -483,30 +393,11 @@ static const struct imx355_reg mode_1924x1080_regs[] = {
{ 0x034d, 0x84 },
{ 0x034e, 0x04 },
{ 0x034f, 0x38 },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x0310, 0x00 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
};
static const struct imx355_reg mode_1920x1080_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
{ 0x0342, 0x0e },
{ 0x0343, 0x58 },
{ 0x0340, 0x05 },
@@ -519,8 +410,6 @@ static const struct imx355_reg mode_1920x1080_regs[] = {
{ 0x0349, 0x27 },
{ 0x034a, 0x06 },
{ 0x034b, 0xeb },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
{ 0x0900, 0x00 },
{ 0x0901, 0x11 },
{ 0x0902, 0x00 },
@@ -528,30 +417,11 @@ static const struct imx355_reg mode_1920x1080_regs[] = {
{ 0x034d, 0x80 },
{ 0x034e, 0x04 },
{ 0x034f, 0x38 },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x0310, 0x00 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
};
static const struct imx355_reg mode_1640x1232_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
{ 0x0342, 0x07 },
{ 0x0343, 0x2c },
{ 0x0340, 0x05 },
@@ -564,8 +434,6 @@ static const struct imx355_reg mode_1640x1232_regs[] = {
{ 0x0349, 0xcf },
{ 0x034a, 0x09 },
{ 0x034b, 0x9f },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
{ 0x0900, 0x01 },
{ 0x0901, 0x22 },
{ 0x0902, 0x00 },
@@ -573,30 +441,11 @@ static const struct imx355_reg mode_1640x1232_regs[] = {
{ 0x034d, 0x68 },
{ 0x034e, 0x04 },
{ 0x034f, 0xd0 },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x0310, 0x00 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
};
static const struct imx355_reg mode_1640x922_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
{ 0x0342, 0x07 },
{ 0x0343, 0x2c },
{ 0x0340, 0x05 },
@@ -609,8 +458,6 @@ static const struct imx355_reg mode_1640x922_regs[] = {
{ 0x0349, 0xcf },
{ 0x034a, 0x08 },
{ 0x034b, 0x63 },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
{ 0x0900, 0x01 },
{ 0x0901, 0x22 },
{ 0x0902, 0x00 },
@@ -618,30 +465,11 @@ static const struct imx355_reg mode_1640x922_regs[] = {
{ 0x034d, 0x68 },
{ 0x034e, 0x03 },
{ 0x034f, 0x9a },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x0310, 0x00 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
};
static const struct imx355_reg mode_1300x736_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
{ 0x0342, 0x07 },
{ 0x0343, 0x2c },
{ 0x0340, 0x05 },
@@ -654,8 +482,6 @@ static const struct imx355_reg mode_1300x736_regs[] = {
{ 0x0349, 0x7f },
{ 0x034a, 0x07 },
{ 0x034b, 0xaf },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
{ 0x0900, 0x01 },
{ 0x0901, 0x22 },
{ 0x0902, 0x00 },
@@ -663,30 +489,11 @@ static const struct imx355_reg mode_1300x736_regs[] = {
{ 0x034d, 0x14 },
{ 0x034e, 0x02 },
{ 0x034f, 0xe0 },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x0310, 0x00 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
};
static const struct imx355_reg mode_1296x736_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
{ 0x0342, 0x07 },
{ 0x0343, 0x2c },
{ 0x0340, 0x05 },
@@ -699,8 +506,6 @@ static const struct imx355_reg mode_1296x736_regs[] = {
{ 0x0349, 0x77 },
{ 0x034a, 0x07 },
{ 0x034b, 0xaf },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
{ 0x0900, 0x01 },
{ 0x0901, 0x22 },
{ 0x0902, 0x00 },
@@ -708,30 +513,11 @@ static const struct imx355_reg mode_1296x736_regs[] = {
{ 0x034d, 0x10 },
{ 0x034e, 0x02 },
{ 0x034f, 0xe0 },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x0310, 0x00 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
};
static const struct imx355_reg mode_1284x720_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
{ 0x0342, 0x07 },
{ 0x0343, 0x2c },
{ 0x0340, 0x05 },
@@ -744,8 +530,6 @@ static const struct imx355_reg mode_1284x720_regs[] = {
{ 0x0349, 0x6f },
{ 0x034a, 0x07 },
{ 0x034b, 0x9f },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
{ 0x0900, 0x01 },
{ 0x0901, 0x22 },
{ 0x0902, 0x00 },
@@ -753,30 +537,11 @@ static const struct imx355_reg mode_1284x720_regs[] = {
{ 0x034d, 0x04 },
{ 0x034e, 0x02 },
{ 0x034f, 0xd0 },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x0310, 0x00 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
};
static const struct imx355_reg mode_1280x720_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
{ 0x0342, 0x07 },
{ 0x0343, 0x2c },
{ 0x0340, 0x05 },
@@ -789,8 +554,6 @@ static const struct imx355_reg mode_1280x720_regs[] = {
{ 0x0349, 0x67 },
{ 0x034a, 0x07 },
{ 0x034b, 0x9f },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
{ 0x0900, 0x01 },
{ 0x0901, 0x22 },
{ 0x0902, 0x00 },
@@ -798,30 +561,11 @@ static const struct imx355_reg mode_1280x720_regs[] = {
{ 0x034d, 0x00 },
{ 0x034e, 0x02 },
{ 0x034f, 0xd0 },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x0310, 0x00 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
};
static const struct imx355_reg mode_820x616_regs[] = {
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
{ 0x0342, 0x0e },
{ 0x0343, 0x58 },
{ 0x0340, 0x02 },
@@ -834,8 +578,6 @@ static const struct imx355_reg mode_820x616_regs[] = {
{ 0x0349, 0xcf },
{ 0x034a, 0x09 },
{ 0x034b, 0x9f },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
{ 0x0900, 0x01 },
{ 0x0901, 0x44 },
{ 0x0902, 0x00 },
@@ -843,24 +585,8 @@ static const struct imx355_reg mode_820x616_regs[] = {
{ 0x034d, 0x34 },
{ 0x034e, 0x02 },
{ 0x034f, 0x68 },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x030b, 0x01 },
- { 0x030d, 0x02 },
- { 0x0310, 0x00 },
{ 0x0700, 0x02 },
{ 0x0701, 0x78 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
};
static const char * const imx355_test_pattern_menu[] = {
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread* Re: [PATCH 01/13] media: imx355: Remove duplicated registers from the mode tables
2026-05-06 18:23 ` [PATCH 01/13] media: imx355: Remove duplicated registers from the mode tables Dave Stevenson
@ 2026-05-07 13:41 ` Jacopo Mondi
0 siblings, 0 replies; 29+ messages in thread
From: Jacopo Mondi @ 2026-05-07 13:41 UTC (permalink / raw)
To: Dave Stevenson
Cc: Tianshu Qiu, Sakari Ailus, Mauro Carvalho Chehab, linux-media,
linux-kernel, David Heidelberg,
20260414-imx355-24mhz-v1-1-9ae77bc6e7ec
Hi Dave,
On Wed, May 06, 2026 at 07:23:39PM +0100, Dave Stevenson wrote:
> A large number of registers are identical within all the modes.
> Move those to imx355_global_regs.
>
> Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Indeed all the factored-out registers have the same value in all modes
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Thanks
j
> ---
> drivers/media/i2c/imx355.c | 314 +++------------------------------------------
> 1 file changed, 20 insertions(+), 294 deletions(-)
>
> diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
> index f9ec13bb27d1..a694d4d742ae 100644
> --- a/drivers/media/i2c/imx355.c
> +++ b/drivers/media/i2c/imx355.c
> @@ -226,6 +226,26 @@ static const struct imx355_reg imx355_global_regs[] = {
> { 0x68b0, 0x00 },
> { 0x3058, 0x00 },
> { 0x305a, 0x00 },
> + { 0x0112, 0x0a },
> + { 0x0113, 0x0a },
> + { 0x0114, 0x03 },
> + { 0x0301, 0x05 },
> + { 0x0303, 0x01 },
> + { 0x0305, 0x02 },
> + { 0x030d, 0x02 },
> + { 0x0310, 0x00 },
> + { 0x0220, 0x00 },
> + { 0x0222, 0x01 },
> + { 0x0820, 0x0b },
> + { 0x0821, 0x40 },
> + { 0x3088, 0x04 },
> + { 0x6813, 0x02 },
> + { 0x6835, 0x07 },
> + { 0x6836, 0x01 },
> + { 0x6837, 0x04 },
> + { 0x684d, 0x07 },
> + { 0x684e, 0x01 },
> + { 0x684f, 0x04 },
> };
>
> static const struct imx355_reg_list imx355_global_setting = {
> @@ -234,9 +254,6 @@ static const struct imx355_reg_list imx355_global_setting = {
> };
>
> static const struct imx355_reg mode_3268x2448_regs[] = {
> - { 0x0112, 0x0a },
> - { 0x0113, 0x0a },
> - { 0x0114, 0x03 },
> { 0x0342, 0x0e },
> { 0x0343, 0x58 },
> { 0x0340, 0x0a },
> @@ -249,8 +266,6 @@ static const struct imx355_reg mode_3268x2448_regs[] = {
> { 0x0349, 0xcb },
> { 0x034a, 0x09 },
> { 0x034b, 0x97 },
> - { 0x0220, 0x00 },
> - { 0x0222, 0x01 },
> { 0x0900, 0x00 },
> { 0x0901, 0x11 },
> { 0x0902, 0x00 },
> @@ -258,30 +273,11 @@ static const struct imx355_reg mode_3268x2448_regs[] = {
> { 0x034d, 0xc4 },
> { 0x034e, 0x09 },
> { 0x034f, 0x90 },
> - { 0x0301, 0x05 },
> - { 0x0303, 0x01 },
> - { 0x0305, 0x02 },
> - { 0x030b, 0x01 },
> - { 0x030d, 0x02 },
> - { 0x0310, 0x00 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> - { 0x0820, 0x0b },
> - { 0x0821, 0x40 },
> - { 0x3088, 0x04 },
> - { 0x6813, 0x02 },
> - { 0x6835, 0x07 },
> - { 0x6836, 0x01 },
> - { 0x6837, 0x04 },
> - { 0x684d, 0x07 },
> - { 0x684e, 0x01 },
> - { 0x684f, 0x04 },
> };
>
> static const struct imx355_reg mode_3264x2448_regs[] = {
> - { 0x0112, 0x0a },
> - { 0x0113, 0x0a },
> - { 0x0114, 0x03 },
> { 0x0342, 0x0e },
> { 0x0343, 0x58 },
> { 0x0340, 0x0a },
> @@ -294,8 +290,6 @@ static const struct imx355_reg mode_3264x2448_regs[] = {
> { 0x0349, 0xc7 },
> { 0x034a, 0x09 },
> { 0x034b, 0x97 },
> - { 0x0220, 0x00 },
> - { 0x0222, 0x01 },
> { 0x0900, 0x00 },
> { 0x0901, 0x11 },
> { 0x0902, 0x00 },
> @@ -303,30 +297,11 @@ static const struct imx355_reg mode_3264x2448_regs[] = {
> { 0x034d, 0xc0 },
> { 0x034e, 0x09 },
> { 0x034f, 0x90 },
> - { 0x0301, 0x05 },
> - { 0x0303, 0x01 },
> - { 0x0305, 0x02 },
> - { 0x030b, 0x01 },
> - { 0x030d, 0x02 },
> - { 0x0310, 0x00 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> - { 0x0820, 0x0b },
> - { 0x0821, 0x40 },
> - { 0x3088, 0x04 },
> - { 0x6813, 0x02 },
> - { 0x6835, 0x07 },
> - { 0x6836, 0x01 },
> - { 0x6837, 0x04 },
> - { 0x684d, 0x07 },
> - { 0x684e, 0x01 },
> - { 0x684f, 0x04 },
> };
>
> static const struct imx355_reg mode_3280x2464_regs[] = {
> - { 0x0112, 0x0a },
> - { 0x0113, 0x0a },
> - { 0x0114, 0x03 },
> { 0x0342, 0x0e },
> { 0x0343, 0x58 },
> { 0x0340, 0x0a },
> @@ -339,8 +314,6 @@ static const struct imx355_reg mode_3280x2464_regs[] = {
> { 0x0349, 0xcf },
> { 0x034a, 0x09 },
> { 0x034b, 0x9f },
> - { 0x0220, 0x00 },
> - { 0x0222, 0x01 },
> { 0x0900, 0x00 },
> { 0x0901, 0x11 },
> { 0x0902, 0x00 },
> @@ -348,30 +321,11 @@ static const struct imx355_reg mode_3280x2464_regs[] = {
> { 0x034d, 0xd0 },
> { 0x034e, 0x09 },
> { 0x034f, 0xa0 },
> - { 0x0301, 0x05 },
> - { 0x0303, 0x01 },
> - { 0x0305, 0x02 },
> - { 0x030b, 0x01 },
> - { 0x030d, 0x02 },
> - { 0x0310, 0x00 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> - { 0x0820, 0x0b },
> - { 0x0821, 0x40 },
> - { 0x3088, 0x04 },
> - { 0x6813, 0x02 },
> - { 0x6835, 0x07 },
> - { 0x6836, 0x01 },
> - { 0x6837, 0x04 },
> - { 0x684d, 0x07 },
> - { 0x684e, 0x01 },
> - { 0x684f, 0x04 },
> };
>
> static const struct imx355_reg mode_1940x1096_regs[] = {
> - { 0x0112, 0x0a },
> - { 0x0113, 0x0a },
> - { 0x0114, 0x03 },
> { 0x0342, 0x0e },
> { 0x0343, 0x58 },
> { 0x0340, 0x05 },
> @@ -384,8 +338,6 @@ static const struct imx355_reg mode_1940x1096_regs[] = {
> { 0x0349, 0x33 },
> { 0x034a, 0x06 },
> { 0x034b, 0xf3 },
> - { 0x0220, 0x00 },
> - { 0x0222, 0x01 },
> { 0x0900, 0x00 },
> { 0x0901, 0x11 },
> { 0x0902, 0x00 },
> @@ -393,30 +345,11 @@ static const struct imx355_reg mode_1940x1096_regs[] = {
> { 0x034d, 0x94 },
> { 0x034e, 0x04 },
> { 0x034f, 0x48 },
> - { 0x0301, 0x05 },
> - { 0x0303, 0x01 },
> - { 0x0305, 0x02 },
> - { 0x030b, 0x01 },
> - { 0x030d, 0x02 },
> - { 0x0310, 0x00 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> - { 0x0820, 0x0b },
> - { 0x0821, 0x40 },
> - { 0x3088, 0x04 },
> - { 0x6813, 0x02 },
> - { 0x6835, 0x07 },
> - { 0x6836, 0x01 },
> - { 0x6837, 0x04 },
> - { 0x684d, 0x07 },
> - { 0x684e, 0x01 },
> - { 0x684f, 0x04 },
> };
>
> static const struct imx355_reg mode_1936x1096_regs[] = {
> - { 0x0112, 0x0a },
> - { 0x0113, 0x0a },
> - { 0x0114, 0x03 },
> { 0x0342, 0x0e },
> { 0x0343, 0x58 },
> { 0x0340, 0x05 },
> @@ -429,8 +362,6 @@ static const struct imx355_reg mode_1936x1096_regs[] = {
> { 0x0349, 0x2f },
> { 0x034a, 0x06 },
> { 0x034b, 0xf3 },
> - { 0x0220, 0x00 },
> - { 0x0222, 0x01 },
> { 0x0900, 0x00 },
> { 0x0901, 0x11 },
> { 0x0902, 0x00 },
> @@ -438,30 +369,11 @@ static const struct imx355_reg mode_1936x1096_regs[] = {
> { 0x034d, 0x90 },
> { 0x034e, 0x04 },
> { 0x034f, 0x48 },
> - { 0x0301, 0x05 },
> - { 0x0303, 0x01 },
> - { 0x0305, 0x02 },
> - { 0x030b, 0x01 },
> - { 0x030d, 0x02 },
> - { 0x0310, 0x00 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> - { 0x0820, 0x0b },
> - { 0x0821, 0x40 },
> - { 0x3088, 0x04 },
> - { 0x6813, 0x02 },
> - { 0x6835, 0x07 },
> - { 0x6836, 0x01 },
> - { 0x6837, 0x04 },
> - { 0x684d, 0x07 },
> - { 0x684e, 0x01 },
> - { 0x684f, 0x04 },
> };
>
> static const struct imx355_reg mode_1924x1080_regs[] = {
> - { 0x0112, 0x0a },
> - { 0x0113, 0x0a },
> - { 0x0114, 0x03 },
> { 0x0342, 0x0e },
> { 0x0343, 0x58 },
> { 0x0340, 0x05 },
> @@ -474,8 +386,6 @@ static const struct imx355_reg mode_1924x1080_regs[] = {
> { 0x0349, 0x2b },
> { 0x034a, 0x06 },
> { 0x034b, 0xeb },
> - { 0x0220, 0x00 },
> - { 0x0222, 0x01 },
> { 0x0900, 0x00 },
> { 0x0901, 0x11 },
> { 0x0902, 0x00 },
> @@ -483,30 +393,11 @@ static const struct imx355_reg mode_1924x1080_regs[] = {
> { 0x034d, 0x84 },
> { 0x034e, 0x04 },
> { 0x034f, 0x38 },
> - { 0x0301, 0x05 },
> - { 0x0303, 0x01 },
> - { 0x0305, 0x02 },
> - { 0x030b, 0x01 },
> - { 0x030d, 0x02 },
> - { 0x0310, 0x00 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> - { 0x0820, 0x0b },
> - { 0x0821, 0x40 },
> - { 0x3088, 0x04 },
> - { 0x6813, 0x02 },
> - { 0x6835, 0x07 },
> - { 0x6836, 0x01 },
> - { 0x6837, 0x04 },
> - { 0x684d, 0x07 },
> - { 0x684e, 0x01 },
> - { 0x684f, 0x04 },
> };
>
> static const struct imx355_reg mode_1920x1080_regs[] = {
> - { 0x0112, 0x0a },
> - { 0x0113, 0x0a },
> - { 0x0114, 0x03 },
> { 0x0342, 0x0e },
> { 0x0343, 0x58 },
> { 0x0340, 0x05 },
> @@ -519,8 +410,6 @@ static const struct imx355_reg mode_1920x1080_regs[] = {
> { 0x0349, 0x27 },
> { 0x034a, 0x06 },
> { 0x034b, 0xeb },
> - { 0x0220, 0x00 },
> - { 0x0222, 0x01 },
> { 0x0900, 0x00 },
> { 0x0901, 0x11 },
> { 0x0902, 0x00 },
> @@ -528,30 +417,11 @@ static const struct imx355_reg mode_1920x1080_regs[] = {
> { 0x034d, 0x80 },
> { 0x034e, 0x04 },
> { 0x034f, 0x38 },
> - { 0x0301, 0x05 },
> - { 0x0303, 0x01 },
> - { 0x0305, 0x02 },
> - { 0x030b, 0x01 },
> - { 0x030d, 0x02 },
> - { 0x0310, 0x00 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> - { 0x0820, 0x0b },
> - { 0x0821, 0x40 },
> - { 0x3088, 0x04 },
> - { 0x6813, 0x02 },
> - { 0x6835, 0x07 },
> - { 0x6836, 0x01 },
> - { 0x6837, 0x04 },
> - { 0x684d, 0x07 },
> - { 0x684e, 0x01 },
> - { 0x684f, 0x04 },
> };
>
> static const struct imx355_reg mode_1640x1232_regs[] = {
> - { 0x0112, 0x0a },
> - { 0x0113, 0x0a },
> - { 0x0114, 0x03 },
> { 0x0342, 0x07 },
> { 0x0343, 0x2c },
> { 0x0340, 0x05 },
> @@ -564,8 +434,6 @@ static const struct imx355_reg mode_1640x1232_regs[] = {
> { 0x0349, 0xcf },
> { 0x034a, 0x09 },
> { 0x034b, 0x9f },
> - { 0x0220, 0x00 },
> - { 0x0222, 0x01 },
> { 0x0900, 0x01 },
> { 0x0901, 0x22 },
> { 0x0902, 0x00 },
> @@ -573,30 +441,11 @@ static const struct imx355_reg mode_1640x1232_regs[] = {
> { 0x034d, 0x68 },
> { 0x034e, 0x04 },
> { 0x034f, 0xd0 },
> - { 0x0301, 0x05 },
> - { 0x0303, 0x01 },
> - { 0x0305, 0x02 },
> - { 0x030b, 0x01 },
> - { 0x030d, 0x02 },
> - { 0x0310, 0x00 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> - { 0x0820, 0x0b },
> - { 0x0821, 0x40 },
> - { 0x3088, 0x04 },
> - { 0x6813, 0x02 },
> - { 0x6835, 0x07 },
> - { 0x6836, 0x01 },
> - { 0x6837, 0x04 },
> - { 0x684d, 0x07 },
> - { 0x684e, 0x01 },
> - { 0x684f, 0x04 },
> };
>
> static const struct imx355_reg mode_1640x922_regs[] = {
> - { 0x0112, 0x0a },
> - { 0x0113, 0x0a },
> - { 0x0114, 0x03 },
> { 0x0342, 0x07 },
> { 0x0343, 0x2c },
> { 0x0340, 0x05 },
> @@ -609,8 +458,6 @@ static const struct imx355_reg mode_1640x922_regs[] = {
> { 0x0349, 0xcf },
> { 0x034a, 0x08 },
> { 0x034b, 0x63 },
> - { 0x0220, 0x00 },
> - { 0x0222, 0x01 },
> { 0x0900, 0x01 },
> { 0x0901, 0x22 },
> { 0x0902, 0x00 },
> @@ -618,30 +465,11 @@ static const struct imx355_reg mode_1640x922_regs[] = {
> { 0x034d, 0x68 },
> { 0x034e, 0x03 },
> { 0x034f, 0x9a },
> - { 0x0301, 0x05 },
> - { 0x0303, 0x01 },
> - { 0x0305, 0x02 },
> - { 0x030b, 0x01 },
> - { 0x030d, 0x02 },
> - { 0x0310, 0x00 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> - { 0x0820, 0x0b },
> - { 0x0821, 0x40 },
> - { 0x3088, 0x04 },
> - { 0x6813, 0x02 },
> - { 0x6835, 0x07 },
> - { 0x6836, 0x01 },
> - { 0x6837, 0x04 },
> - { 0x684d, 0x07 },
> - { 0x684e, 0x01 },
> - { 0x684f, 0x04 },
> };
>
> static const struct imx355_reg mode_1300x736_regs[] = {
> - { 0x0112, 0x0a },
> - { 0x0113, 0x0a },
> - { 0x0114, 0x03 },
> { 0x0342, 0x07 },
> { 0x0343, 0x2c },
> { 0x0340, 0x05 },
> @@ -654,8 +482,6 @@ static const struct imx355_reg mode_1300x736_regs[] = {
> { 0x0349, 0x7f },
> { 0x034a, 0x07 },
> { 0x034b, 0xaf },
> - { 0x0220, 0x00 },
> - { 0x0222, 0x01 },
> { 0x0900, 0x01 },
> { 0x0901, 0x22 },
> { 0x0902, 0x00 },
> @@ -663,30 +489,11 @@ static const struct imx355_reg mode_1300x736_regs[] = {
> { 0x034d, 0x14 },
> { 0x034e, 0x02 },
> { 0x034f, 0xe0 },
> - { 0x0301, 0x05 },
> - { 0x0303, 0x01 },
> - { 0x0305, 0x02 },
> - { 0x030b, 0x01 },
> - { 0x030d, 0x02 },
> - { 0x0310, 0x00 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> - { 0x0820, 0x0b },
> - { 0x0821, 0x40 },
> - { 0x3088, 0x04 },
> - { 0x6813, 0x02 },
> - { 0x6835, 0x07 },
> - { 0x6836, 0x01 },
> - { 0x6837, 0x04 },
> - { 0x684d, 0x07 },
> - { 0x684e, 0x01 },
> - { 0x684f, 0x04 },
> };
>
> static const struct imx355_reg mode_1296x736_regs[] = {
> - { 0x0112, 0x0a },
> - { 0x0113, 0x0a },
> - { 0x0114, 0x03 },
> { 0x0342, 0x07 },
> { 0x0343, 0x2c },
> { 0x0340, 0x05 },
> @@ -699,8 +506,6 @@ static const struct imx355_reg mode_1296x736_regs[] = {
> { 0x0349, 0x77 },
> { 0x034a, 0x07 },
> { 0x034b, 0xaf },
> - { 0x0220, 0x00 },
> - { 0x0222, 0x01 },
> { 0x0900, 0x01 },
> { 0x0901, 0x22 },
> { 0x0902, 0x00 },
> @@ -708,30 +513,11 @@ static const struct imx355_reg mode_1296x736_regs[] = {
> { 0x034d, 0x10 },
> { 0x034e, 0x02 },
> { 0x034f, 0xe0 },
> - { 0x0301, 0x05 },
> - { 0x0303, 0x01 },
> - { 0x0305, 0x02 },
> - { 0x030b, 0x01 },
> - { 0x030d, 0x02 },
> - { 0x0310, 0x00 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> - { 0x0820, 0x0b },
> - { 0x0821, 0x40 },
> - { 0x3088, 0x04 },
> - { 0x6813, 0x02 },
> - { 0x6835, 0x07 },
> - { 0x6836, 0x01 },
> - { 0x6837, 0x04 },
> - { 0x684d, 0x07 },
> - { 0x684e, 0x01 },
> - { 0x684f, 0x04 },
> };
>
> static const struct imx355_reg mode_1284x720_regs[] = {
> - { 0x0112, 0x0a },
> - { 0x0113, 0x0a },
> - { 0x0114, 0x03 },
> { 0x0342, 0x07 },
> { 0x0343, 0x2c },
> { 0x0340, 0x05 },
> @@ -744,8 +530,6 @@ static const struct imx355_reg mode_1284x720_regs[] = {
> { 0x0349, 0x6f },
> { 0x034a, 0x07 },
> { 0x034b, 0x9f },
> - { 0x0220, 0x00 },
> - { 0x0222, 0x01 },
> { 0x0900, 0x01 },
> { 0x0901, 0x22 },
> { 0x0902, 0x00 },
> @@ -753,30 +537,11 @@ static const struct imx355_reg mode_1284x720_regs[] = {
> { 0x034d, 0x04 },
> { 0x034e, 0x02 },
> { 0x034f, 0xd0 },
> - { 0x0301, 0x05 },
> - { 0x0303, 0x01 },
> - { 0x0305, 0x02 },
> - { 0x030b, 0x01 },
> - { 0x030d, 0x02 },
> - { 0x0310, 0x00 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> - { 0x0820, 0x0b },
> - { 0x0821, 0x40 },
> - { 0x3088, 0x04 },
> - { 0x6813, 0x02 },
> - { 0x6835, 0x07 },
> - { 0x6836, 0x01 },
> - { 0x6837, 0x04 },
> - { 0x684d, 0x07 },
> - { 0x684e, 0x01 },
> - { 0x684f, 0x04 },
> };
>
> static const struct imx355_reg mode_1280x720_regs[] = {
> - { 0x0112, 0x0a },
> - { 0x0113, 0x0a },
> - { 0x0114, 0x03 },
> { 0x0342, 0x07 },
> { 0x0343, 0x2c },
> { 0x0340, 0x05 },
> @@ -789,8 +554,6 @@ static const struct imx355_reg mode_1280x720_regs[] = {
> { 0x0349, 0x67 },
> { 0x034a, 0x07 },
> { 0x034b, 0x9f },
> - { 0x0220, 0x00 },
> - { 0x0222, 0x01 },
> { 0x0900, 0x01 },
> { 0x0901, 0x22 },
> { 0x0902, 0x00 },
> @@ -798,30 +561,11 @@ static const struct imx355_reg mode_1280x720_regs[] = {
> { 0x034d, 0x00 },
> { 0x034e, 0x02 },
> { 0x034f, 0xd0 },
> - { 0x0301, 0x05 },
> - { 0x0303, 0x01 },
> - { 0x0305, 0x02 },
> - { 0x030b, 0x01 },
> - { 0x030d, 0x02 },
> - { 0x0310, 0x00 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> - { 0x0820, 0x0b },
> - { 0x0821, 0x40 },
> - { 0x3088, 0x04 },
> - { 0x6813, 0x02 },
> - { 0x6835, 0x07 },
> - { 0x6836, 0x01 },
> - { 0x6837, 0x04 },
> - { 0x684d, 0x07 },
> - { 0x684e, 0x01 },
> - { 0x684f, 0x04 },
> };
>
> static const struct imx355_reg mode_820x616_regs[] = {
> - { 0x0112, 0x0a },
> - { 0x0113, 0x0a },
> - { 0x0114, 0x03 },
> { 0x0342, 0x0e },
> { 0x0343, 0x58 },
> { 0x0340, 0x02 },
> @@ -834,8 +578,6 @@ static const struct imx355_reg mode_820x616_regs[] = {
> { 0x0349, 0xcf },
> { 0x034a, 0x09 },
> { 0x034b, 0x9f },
> - { 0x0220, 0x00 },
> - { 0x0222, 0x01 },
> { 0x0900, 0x01 },
> { 0x0901, 0x44 },
> { 0x0902, 0x00 },
> @@ -843,24 +585,8 @@ static const struct imx355_reg mode_820x616_regs[] = {
> { 0x034d, 0x34 },
> { 0x034e, 0x02 },
> { 0x034f, 0x68 },
> - { 0x0301, 0x05 },
> - { 0x0303, 0x01 },
> - { 0x0305, 0x02 },
> - { 0x030b, 0x01 },
> - { 0x030d, 0x02 },
> - { 0x0310, 0x00 },
> { 0x0700, 0x02 },
> { 0x0701, 0x78 },
> - { 0x0820, 0x0b },
> - { 0x0821, 0x40 },
> - { 0x3088, 0x04 },
> - { 0x6813, 0x02 },
> - { 0x6835, 0x07 },
> - { 0x6836, 0x01 },
> - { 0x6837, 0x04 },
> - { 0x684d, 0x07 },
> - { 0x684e, 0x01 },
> - { 0x684f, 0x04 },
> };
>
> static const char * const imx355_test_pattern_menu[] = {
>
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH 02/13] media: imx355: Remove setting FRM_LENGTH_LINES in the mode regs
2026-05-06 18:23 [PATCH 00/13] media/imx355: General code cleanups, and adding support for 2 lane operation Dave Stevenson
2026-05-06 18:23 ` [PATCH 01/13] media: imx355: Remove duplicated registers from the mode tables Dave Stevenson
@ 2026-05-06 18:23 ` Dave Stevenson
2026-05-07 13:50 ` Jacopo Mondi
2026-05-06 18:23 ` [PATCH 03/13] media: imx355: Programmatically set the crop parameters for each mode Dave Stevenson
` (10 subsequent siblings)
12 siblings, 1 reply; 29+ messages in thread
From: Dave Stevenson @ 2026-05-06 18:23 UTC (permalink / raw)
To: Tianshu Qiu, Sakari Ailus, Mauro Carvalho Chehab
Cc: linux-media, linux-kernel, David Heidelberg,
20260414-imx355-24mhz-v1-1-9ae77bc6e7ec, Dave Stevenson
Registers 0x0340 and 0x0341 (FRM_LENGTH_LINES) are already written
from the set_ctrl(V4L2_CID_VBLANK) handler, so don't write them
from the mode register list.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/media/i2c/imx355.c | 28 ----------------------------
1 file changed, 28 deletions(-)
diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
index a694d4d742ae..8ea510218c7c 100644
--- a/drivers/media/i2c/imx355.c
+++ b/drivers/media/i2c/imx355.c
@@ -256,8 +256,6 @@ static const struct imx355_reg_list imx355_global_setting = {
static const struct imx355_reg mode_3268x2448_regs[] = {
{ 0x0342, 0x0e },
{ 0x0343, 0x58 },
- { 0x0340, 0x0a },
- { 0x0341, 0x37 },
{ 0x0344, 0x00 },
{ 0x0345, 0x08 },
{ 0x0346, 0x00 },
@@ -280,8 +278,6 @@ static const struct imx355_reg mode_3268x2448_regs[] = {
static const struct imx355_reg mode_3264x2448_regs[] = {
{ 0x0342, 0x0e },
{ 0x0343, 0x58 },
- { 0x0340, 0x0a },
- { 0x0341, 0x37 },
{ 0x0344, 0x00 },
{ 0x0345, 0x08 },
{ 0x0346, 0x00 },
@@ -304,8 +300,6 @@ static const struct imx355_reg mode_3264x2448_regs[] = {
static const struct imx355_reg mode_3280x2464_regs[] = {
{ 0x0342, 0x0e },
{ 0x0343, 0x58 },
- { 0x0340, 0x0a },
- { 0x0341, 0x37 },
{ 0x0344, 0x00 },
{ 0x0345, 0x00 },
{ 0x0346, 0x00 },
@@ -328,8 +322,6 @@ static const struct imx355_reg mode_3280x2464_regs[] = {
static const struct imx355_reg mode_1940x1096_regs[] = {
{ 0x0342, 0x0e },
{ 0x0343, 0x58 },
- { 0x0340, 0x05 },
- { 0x0341, 0x1a },
{ 0x0344, 0x02 },
{ 0x0345, 0xa0 },
{ 0x0346, 0x02 },
@@ -352,8 +344,6 @@ static const struct imx355_reg mode_1940x1096_regs[] = {
static const struct imx355_reg mode_1936x1096_regs[] = {
{ 0x0342, 0x0e },
{ 0x0343, 0x58 },
- { 0x0340, 0x05 },
- { 0x0341, 0x1a },
{ 0x0344, 0x02 },
{ 0x0345, 0xa0 },
{ 0x0346, 0x02 },
@@ -376,8 +366,6 @@ static const struct imx355_reg mode_1936x1096_regs[] = {
static const struct imx355_reg mode_1924x1080_regs[] = {
{ 0x0342, 0x0e },
{ 0x0343, 0x58 },
- { 0x0340, 0x05 },
- { 0x0341, 0x1a },
{ 0x0344, 0x02 },
{ 0x0345, 0xa8 },
{ 0x0346, 0x02 },
@@ -400,8 +388,6 @@ static const struct imx355_reg mode_1924x1080_regs[] = {
static const struct imx355_reg mode_1920x1080_regs[] = {
{ 0x0342, 0x0e },
{ 0x0343, 0x58 },
- { 0x0340, 0x05 },
- { 0x0341, 0x1a },
{ 0x0344, 0x02 },
{ 0x0345, 0xa8 },
{ 0x0346, 0x02 },
@@ -424,8 +410,6 @@ static const struct imx355_reg mode_1920x1080_regs[] = {
static const struct imx355_reg mode_1640x1232_regs[] = {
{ 0x0342, 0x07 },
{ 0x0343, 0x2c },
- { 0x0340, 0x05 },
- { 0x0341, 0x1a },
{ 0x0344, 0x00 },
{ 0x0345, 0x00 },
{ 0x0346, 0x00 },
@@ -448,8 +432,6 @@ static const struct imx355_reg mode_1640x1232_regs[] = {
static const struct imx355_reg mode_1640x922_regs[] = {
{ 0x0342, 0x07 },
{ 0x0343, 0x2c },
- { 0x0340, 0x05 },
- { 0x0341, 0x1a },
{ 0x0344, 0x00 },
{ 0x0345, 0x00 },
{ 0x0346, 0x01 },
@@ -472,8 +454,6 @@ static const struct imx355_reg mode_1640x922_regs[] = {
static const struct imx355_reg mode_1300x736_regs[] = {
{ 0x0342, 0x07 },
{ 0x0343, 0x2c },
- { 0x0340, 0x05 },
- { 0x0341, 0x1a },
{ 0x0344, 0x01 },
{ 0x0345, 0x58 },
{ 0x0346, 0x01 },
@@ -496,8 +476,6 @@ static const struct imx355_reg mode_1300x736_regs[] = {
static const struct imx355_reg mode_1296x736_regs[] = {
{ 0x0342, 0x07 },
{ 0x0343, 0x2c },
- { 0x0340, 0x05 },
- { 0x0341, 0x1a },
{ 0x0344, 0x01 },
{ 0x0345, 0x58 },
{ 0x0346, 0x01 },
@@ -520,8 +498,6 @@ static const struct imx355_reg mode_1296x736_regs[] = {
static const struct imx355_reg mode_1284x720_regs[] = {
{ 0x0342, 0x07 },
{ 0x0343, 0x2c },
- { 0x0340, 0x05 },
- { 0x0341, 0x1a },
{ 0x0344, 0x01 },
{ 0x0345, 0x68 },
{ 0x0346, 0x02 },
@@ -544,8 +520,6 @@ static const struct imx355_reg mode_1284x720_regs[] = {
static const struct imx355_reg mode_1280x720_regs[] = {
{ 0x0342, 0x07 },
{ 0x0343, 0x2c },
- { 0x0340, 0x05 },
- { 0x0341, 0x1a },
{ 0x0344, 0x01 },
{ 0x0345, 0x68 },
{ 0x0346, 0x02 },
@@ -568,8 +542,6 @@ static const struct imx355_reg mode_1280x720_regs[] = {
static const struct imx355_reg mode_820x616_regs[] = {
{ 0x0342, 0x0e },
{ 0x0343, 0x58 },
- { 0x0340, 0x02 },
- { 0x0341, 0x8c },
{ 0x0344, 0x00 },
{ 0x0345, 0x00 },
{ 0x0346, 0x00 },
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread* Re: [PATCH 02/13] media: imx355: Remove setting FRM_LENGTH_LINES in the mode regs
2026-05-06 18:23 ` [PATCH 02/13] media: imx355: Remove setting FRM_LENGTH_LINES in the mode regs Dave Stevenson
@ 2026-05-07 13:50 ` Jacopo Mondi
0 siblings, 0 replies; 29+ messages in thread
From: Jacopo Mondi @ 2026-05-07 13:50 UTC (permalink / raw)
To: Dave Stevenson
Cc: Tianshu Qiu, Sakari Ailus, Mauro Carvalho Chehab, linux-media,
linux-kernel, David Heidelberg,
20260414-imx355-24mhz-v1-1-9ae77bc6e7ec
Hi Dave
On Wed, May 06, 2026 at 07:23:40PM +0100, Dave Stevenson wrote:
> Registers 0x0340 and 0x0341 (FRM_LENGTH_LINES) are already written
> from the set_ctrl(V4L2_CID_VBLANK) handler, so don't write them
> from the mode register list.
>
> Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
> ---
> drivers/media/i2c/imx355.c | 28 ----------------------------
> 1 file changed, 28 deletions(-)
>
> diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
> index a694d4d742ae..8ea510218c7c 100644
> --- a/drivers/media/i2c/imx355.c
> +++ b/drivers/media/i2c/imx355.c
> @@ -256,8 +256,6 @@ static const struct imx355_reg_list imx355_global_setting = {
> static const struct imx355_reg mode_3268x2448_regs[] = {
> { 0x0342, 0x0e },
> { 0x0343, 0x58 },
> - { 0x0340, 0x0a },
> - { 0x0341, 0x37 },
> { 0x0344, 0x00 },
> { 0x0345, 0x08 },
> { 0x0346, 0x00 },
> @@ -280,8 +278,6 @@ static const struct imx355_reg mode_3268x2448_regs[] = {
> static const struct imx355_reg mode_3264x2448_regs[] = {
> { 0x0342, 0x0e },
> { 0x0343, 0x58 },
> - { 0x0340, 0x0a },
> - { 0x0341, 0x37 },
> { 0x0344, 0x00 },
> { 0x0345, 0x08 },
> { 0x0346, 0x00 },
> @@ -304,8 +300,6 @@ static const struct imx355_reg mode_3264x2448_regs[] = {
> static const struct imx355_reg mode_3280x2464_regs[] = {
> { 0x0342, 0x0e },
> { 0x0343, 0x58 },
> - { 0x0340, 0x0a },
> - { 0x0341, 0x37 },
> { 0x0344, 0x00 },
> { 0x0345, 0x00 },
> { 0x0346, 0x00 },
> @@ -328,8 +322,6 @@ static const struct imx355_reg mode_3280x2464_regs[] = {
> static const struct imx355_reg mode_1940x1096_regs[] = {
> { 0x0342, 0x0e },
> { 0x0343, 0x58 },
> - { 0x0340, 0x05 },
> - { 0x0341, 0x1a },
> { 0x0344, 0x02 },
> { 0x0345, 0xa0 },
> { 0x0346, 0x02 },
> @@ -352,8 +344,6 @@ static const struct imx355_reg mode_1940x1096_regs[] = {
> static const struct imx355_reg mode_1936x1096_regs[] = {
> { 0x0342, 0x0e },
> { 0x0343, 0x58 },
> - { 0x0340, 0x05 },
> - { 0x0341, 0x1a },
> { 0x0344, 0x02 },
> { 0x0345, 0xa0 },
> { 0x0346, 0x02 },
> @@ -376,8 +366,6 @@ static const struct imx355_reg mode_1936x1096_regs[] = {
> static const struct imx355_reg mode_1924x1080_regs[] = {
> { 0x0342, 0x0e },
> { 0x0343, 0x58 },
> - { 0x0340, 0x05 },
> - { 0x0341, 0x1a },
> { 0x0344, 0x02 },
> { 0x0345, 0xa8 },
> { 0x0346, 0x02 },
> @@ -400,8 +388,6 @@ static const struct imx355_reg mode_1924x1080_regs[] = {
> static const struct imx355_reg mode_1920x1080_regs[] = {
> { 0x0342, 0x0e },
> { 0x0343, 0x58 },
> - { 0x0340, 0x05 },
> - { 0x0341, 0x1a },
> { 0x0344, 0x02 },
> { 0x0345, 0xa8 },
> { 0x0346, 0x02 },
> @@ -424,8 +410,6 @@ static const struct imx355_reg mode_1920x1080_regs[] = {
> static const struct imx355_reg mode_1640x1232_regs[] = {
> { 0x0342, 0x07 },
> { 0x0343, 0x2c },
> - { 0x0340, 0x05 },
> - { 0x0341, 0x1a },
> { 0x0344, 0x00 },
> { 0x0345, 0x00 },
> { 0x0346, 0x00 },
> @@ -448,8 +432,6 @@ static const struct imx355_reg mode_1640x1232_regs[] = {
> static const struct imx355_reg mode_1640x922_regs[] = {
> { 0x0342, 0x07 },
> { 0x0343, 0x2c },
> - { 0x0340, 0x05 },
> - { 0x0341, 0x1a },
> { 0x0344, 0x00 },
> { 0x0345, 0x00 },
> { 0x0346, 0x01 },
> @@ -472,8 +454,6 @@ static const struct imx355_reg mode_1640x922_regs[] = {
> static const struct imx355_reg mode_1300x736_regs[] = {
> { 0x0342, 0x07 },
> { 0x0343, 0x2c },
> - { 0x0340, 0x05 },
> - { 0x0341, 0x1a },
> { 0x0344, 0x01 },
> { 0x0345, 0x58 },
> { 0x0346, 0x01 },
> @@ -496,8 +476,6 @@ static const struct imx355_reg mode_1300x736_regs[] = {
> static const struct imx355_reg mode_1296x736_regs[] = {
> { 0x0342, 0x07 },
> { 0x0343, 0x2c },
> - { 0x0340, 0x05 },
> - { 0x0341, 0x1a },
> { 0x0344, 0x01 },
> { 0x0345, 0x58 },
> { 0x0346, 0x01 },
> @@ -520,8 +498,6 @@ static const struct imx355_reg mode_1296x736_regs[] = {
> static const struct imx355_reg mode_1284x720_regs[] = {
> { 0x0342, 0x07 },
> { 0x0343, 0x2c },
> - { 0x0340, 0x05 },
> - { 0x0341, 0x1a },
> { 0x0344, 0x01 },
> { 0x0345, 0x68 },
> { 0x0346, 0x02 },
> @@ -544,8 +520,6 @@ static const struct imx355_reg mode_1284x720_regs[] = {
> static const struct imx355_reg mode_1280x720_regs[] = {
> { 0x0342, 0x07 },
> { 0x0343, 0x2c },
> - { 0x0340, 0x05 },
> - { 0x0341, 0x1a },
> { 0x0344, 0x01 },
> { 0x0345, 0x68 },
> { 0x0346, 0x02 },
> @@ -568,8 +542,6 @@ static const struct imx355_reg mode_1280x720_regs[] = {
> static const struct imx355_reg mode_820x616_regs[] = {
> { 0x0342, 0x0e },
> { 0x0343, 0x58 },
> - { 0x0340, 0x02 },
> - { 0x0341, 0x8c },
> { 0x0344, 0x00 },
> { 0x0345, 0x00 },
> { 0x0346, 0x00 },
>
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH 03/13] media: imx355: Programmatically set the crop parameters for each mode
2026-05-06 18:23 [PATCH 00/13] media/imx355: General code cleanups, and adding support for 2 lane operation Dave Stevenson
2026-05-06 18:23 ` [PATCH 01/13] media: imx355: Remove duplicated registers from the mode tables Dave Stevenson
2026-05-06 18:23 ` [PATCH 02/13] media: imx355: Remove setting FRM_LENGTH_LINES in the mode regs Dave Stevenson
@ 2026-05-06 18:23 ` Dave Stevenson
2026-05-07 14:00 ` Jacopo Mondi
2026-05-06 18:23 ` [PATCH 04/13] media: imx355: Remove the duplication between width/height and x/y_out_size Dave Stevenson
` (9 subsequent siblings)
12 siblings, 1 reply; 29+ messages in thread
From: Dave Stevenson @ 2026-05-06 18:23 UTC (permalink / raw)
To: Tianshu Qiu, Sakari Ailus, Mauro Carvalho Chehab
Cc: linux-media, linux-kernel, David Heidelberg,
20260414-imx355-24mhz-v1-1-9ae77bc6e7ec, Dave Stevenson
Currently the cropping is set via register entries in the per mode
register lists. Move those into the mode structure and set them
programmatically.
x_out_size and y_out_size are duplicates of width and height, but
are retained in this patch for ease of review.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/media/i2c/imx355.c | 296 +++++++++++++++++++--------------------------
1 file changed, 127 insertions(+), 169 deletions(-)
diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
index 8ea510218c7c..6179fe74c897 100644
--- a/drivers/media/i2c/imx355.c
+++ b/drivers/media/i2c/imx355.c
@@ -34,6 +34,13 @@
#define IMX355_REG_FLL 0x0340
#define IMX355_FLL_MAX 0xffff
+#define IMX355_REG_X_ADD_START 0x0344
+#define IMX355_REG_Y_ADD_START 0x0346
+#define IMX355_REG_X_ADD_END 0x0348
+#define IMX355_REG_Y_ADD_END 0x034a
+#define IMX355_REG_X_OUT_SIZE 0x034c
+#define IMX355_REG_Y_OUT_SIZE 0x034e
+
/* Exposure control */
#define IMX355_REG_EXPOSURE 0x0202
#define IMX355_EXPOSURE_MIN 1
@@ -102,6 +109,13 @@ struct imx355_mode {
/* Default register values */
struct imx355_reg_list reg_list;
+
+ u16 x_add_start;
+ u16 y_add_start;
+ u16 x_add_end;
+ u16 y_add_end;
+ u16 x_out_size;
+ u16 y_out_size;
};
struct imx355_clk_params {
@@ -256,21 +270,9 @@ static const struct imx355_reg_list imx355_global_setting = {
static const struct imx355_reg mode_3268x2448_regs[] = {
{ 0x0342, 0x0e },
{ 0x0343, 0x58 },
- { 0x0344, 0x00 },
- { 0x0345, 0x08 },
- { 0x0346, 0x00 },
- { 0x0347, 0x08 },
- { 0x0348, 0x0c },
- { 0x0349, 0xcb },
- { 0x034a, 0x09 },
- { 0x034b, 0x97 },
{ 0x0900, 0x00 },
{ 0x0901, 0x11 },
{ 0x0902, 0x00 },
- { 0x034c, 0x0c },
- { 0x034d, 0xc4 },
- { 0x034e, 0x09 },
- { 0x034f, 0x90 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
};
@@ -278,21 +280,9 @@ static const struct imx355_reg mode_3268x2448_regs[] = {
static const struct imx355_reg mode_3264x2448_regs[] = {
{ 0x0342, 0x0e },
{ 0x0343, 0x58 },
- { 0x0344, 0x00 },
- { 0x0345, 0x08 },
- { 0x0346, 0x00 },
- { 0x0347, 0x08 },
- { 0x0348, 0x0c },
- { 0x0349, 0xc7 },
- { 0x034a, 0x09 },
- { 0x034b, 0x97 },
{ 0x0900, 0x00 },
{ 0x0901, 0x11 },
{ 0x0902, 0x00 },
- { 0x034c, 0x0c },
- { 0x034d, 0xc0 },
- { 0x034e, 0x09 },
- { 0x034f, 0x90 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
};
@@ -300,21 +290,9 @@ static const struct imx355_reg mode_3264x2448_regs[] = {
static const struct imx355_reg mode_3280x2464_regs[] = {
{ 0x0342, 0x0e },
{ 0x0343, 0x58 },
- { 0x0344, 0x00 },
- { 0x0345, 0x00 },
- { 0x0346, 0x00 },
- { 0x0347, 0x00 },
- { 0x0348, 0x0c },
- { 0x0349, 0xcf },
- { 0x034a, 0x09 },
- { 0x034b, 0x9f },
{ 0x0900, 0x00 },
{ 0x0901, 0x11 },
{ 0x0902, 0x00 },
- { 0x034c, 0x0c },
- { 0x034d, 0xd0 },
- { 0x034e, 0x09 },
- { 0x034f, 0xa0 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
};
@@ -322,21 +300,9 @@ static const struct imx355_reg mode_3280x2464_regs[] = {
static const struct imx355_reg mode_1940x1096_regs[] = {
{ 0x0342, 0x0e },
{ 0x0343, 0x58 },
- { 0x0344, 0x02 },
- { 0x0345, 0xa0 },
- { 0x0346, 0x02 },
- { 0x0347, 0xac },
- { 0x0348, 0x0a },
- { 0x0349, 0x33 },
- { 0x034a, 0x06 },
- { 0x034b, 0xf3 },
{ 0x0900, 0x00 },
{ 0x0901, 0x11 },
{ 0x0902, 0x00 },
- { 0x034c, 0x07 },
- { 0x034d, 0x94 },
- { 0x034e, 0x04 },
- { 0x034f, 0x48 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
};
@@ -344,21 +310,9 @@ static const struct imx355_reg mode_1940x1096_regs[] = {
static const struct imx355_reg mode_1936x1096_regs[] = {
{ 0x0342, 0x0e },
{ 0x0343, 0x58 },
- { 0x0344, 0x02 },
- { 0x0345, 0xa0 },
- { 0x0346, 0x02 },
- { 0x0347, 0xac },
- { 0x0348, 0x0a },
- { 0x0349, 0x2f },
- { 0x034a, 0x06 },
- { 0x034b, 0xf3 },
{ 0x0900, 0x00 },
{ 0x0901, 0x11 },
{ 0x0902, 0x00 },
- { 0x034c, 0x07 },
- { 0x034d, 0x90 },
- { 0x034e, 0x04 },
- { 0x034f, 0x48 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
};
@@ -366,21 +320,9 @@ static const struct imx355_reg mode_1936x1096_regs[] = {
static const struct imx355_reg mode_1924x1080_regs[] = {
{ 0x0342, 0x0e },
{ 0x0343, 0x58 },
- { 0x0344, 0x02 },
- { 0x0345, 0xa8 },
- { 0x0346, 0x02 },
- { 0x0347, 0xb4 },
- { 0x0348, 0x0a },
- { 0x0349, 0x2b },
- { 0x034a, 0x06 },
- { 0x034b, 0xeb },
{ 0x0900, 0x00 },
{ 0x0901, 0x11 },
{ 0x0902, 0x00 },
- { 0x034c, 0x07 },
- { 0x034d, 0x84 },
- { 0x034e, 0x04 },
- { 0x034f, 0x38 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
};
@@ -388,21 +330,9 @@ static const struct imx355_reg mode_1924x1080_regs[] = {
static const struct imx355_reg mode_1920x1080_regs[] = {
{ 0x0342, 0x0e },
{ 0x0343, 0x58 },
- { 0x0344, 0x02 },
- { 0x0345, 0xa8 },
- { 0x0346, 0x02 },
- { 0x0347, 0xb4 },
- { 0x0348, 0x0a },
- { 0x0349, 0x27 },
- { 0x034a, 0x06 },
- { 0x034b, 0xeb },
{ 0x0900, 0x00 },
{ 0x0901, 0x11 },
{ 0x0902, 0x00 },
- { 0x034c, 0x07 },
- { 0x034d, 0x80 },
- { 0x034e, 0x04 },
- { 0x034f, 0x38 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
};
@@ -410,21 +340,9 @@ static const struct imx355_reg mode_1920x1080_regs[] = {
static const struct imx355_reg mode_1640x1232_regs[] = {
{ 0x0342, 0x07 },
{ 0x0343, 0x2c },
- { 0x0344, 0x00 },
- { 0x0345, 0x00 },
- { 0x0346, 0x00 },
- { 0x0347, 0x00 },
- { 0x0348, 0x0c },
- { 0x0349, 0xcf },
- { 0x034a, 0x09 },
- { 0x034b, 0x9f },
{ 0x0900, 0x01 },
{ 0x0901, 0x22 },
{ 0x0902, 0x00 },
- { 0x034c, 0x06 },
- { 0x034d, 0x68 },
- { 0x034e, 0x04 },
- { 0x034f, 0xd0 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
};
@@ -432,21 +350,9 @@ static const struct imx355_reg mode_1640x1232_regs[] = {
static const struct imx355_reg mode_1640x922_regs[] = {
{ 0x0342, 0x07 },
{ 0x0343, 0x2c },
- { 0x0344, 0x00 },
- { 0x0345, 0x00 },
- { 0x0346, 0x01 },
- { 0x0347, 0x30 },
- { 0x0348, 0x0c },
- { 0x0349, 0xcf },
- { 0x034a, 0x08 },
- { 0x034b, 0x63 },
{ 0x0900, 0x01 },
{ 0x0901, 0x22 },
{ 0x0902, 0x00 },
- { 0x034c, 0x06 },
- { 0x034d, 0x68 },
- { 0x034e, 0x03 },
- { 0x034f, 0x9a },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
};
@@ -454,21 +360,9 @@ static const struct imx355_reg mode_1640x922_regs[] = {
static const struct imx355_reg mode_1300x736_regs[] = {
{ 0x0342, 0x07 },
{ 0x0343, 0x2c },
- { 0x0344, 0x01 },
- { 0x0345, 0x58 },
- { 0x0346, 0x01 },
- { 0x0347, 0xf0 },
- { 0x0348, 0x0b },
- { 0x0349, 0x7f },
- { 0x034a, 0x07 },
- { 0x034b, 0xaf },
{ 0x0900, 0x01 },
{ 0x0901, 0x22 },
{ 0x0902, 0x00 },
- { 0x034c, 0x05 },
- { 0x034d, 0x14 },
- { 0x034e, 0x02 },
- { 0x034f, 0xe0 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
};
@@ -476,21 +370,9 @@ static const struct imx355_reg mode_1300x736_regs[] = {
static const struct imx355_reg mode_1296x736_regs[] = {
{ 0x0342, 0x07 },
{ 0x0343, 0x2c },
- { 0x0344, 0x01 },
- { 0x0345, 0x58 },
- { 0x0346, 0x01 },
- { 0x0347, 0xf0 },
- { 0x0348, 0x0b },
- { 0x0349, 0x77 },
- { 0x034a, 0x07 },
- { 0x034b, 0xaf },
{ 0x0900, 0x01 },
{ 0x0901, 0x22 },
{ 0x0902, 0x00 },
- { 0x034c, 0x05 },
- { 0x034d, 0x10 },
- { 0x034e, 0x02 },
- { 0x034f, 0xe0 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
};
@@ -498,21 +380,9 @@ static const struct imx355_reg mode_1296x736_regs[] = {
static const struct imx355_reg mode_1284x720_regs[] = {
{ 0x0342, 0x07 },
{ 0x0343, 0x2c },
- { 0x0344, 0x01 },
- { 0x0345, 0x68 },
- { 0x0346, 0x02 },
- { 0x0347, 0x00 },
- { 0x0348, 0x0b },
- { 0x0349, 0x6f },
- { 0x034a, 0x07 },
- { 0x034b, 0x9f },
{ 0x0900, 0x01 },
{ 0x0901, 0x22 },
{ 0x0902, 0x00 },
- { 0x034c, 0x05 },
- { 0x034d, 0x04 },
- { 0x034e, 0x02 },
- { 0x034f, 0xd0 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
};
@@ -520,21 +390,9 @@ static const struct imx355_reg mode_1284x720_regs[] = {
static const struct imx355_reg mode_1280x720_regs[] = {
{ 0x0342, 0x07 },
{ 0x0343, 0x2c },
- { 0x0344, 0x01 },
- { 0x0345, 0x68 },
- { 0x0346, 0x02 },
- { 0x0347, 0x00 },
- { 0x0348, 0x0b },
- { 0x0349, 0x67 },
- { 0x034a, 0x07 },
- { 0x034b, 0x9f },
{ 0x0900, 0x01 },
{ 0x0901, 0x22 },
{ 0x0902, 0x00 },
- { 0x034c, 0x05 },
- { 0x034d, 0x00 },
- { 0x034e, 0x02 },
- { 0x034f, 0xd0 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
};
@@ -542,21 +400,9 @@ static const struct imx355_reg mode_1280x720_regs[] = {
static const struct imx355_reg mode_820x616_regs[] = {
{ 0x0342, 0x0e },
{ 0x0343, 0x58 },
- { 0x0344, 0x00 },
- { 0x0345, 0x00 },
- { 0x0346, 0x00 },
- { 0x0347, 0x00 },
- { 0x0348, 0x0c },
- { 0x0349, 0xcf },
- { 0x034a, 0x09 },
- { 0x034b, 0x9f },
{ 0x0900, 0x01 },
{ 0x0901, 0x44 },
{ 0x0902, 0x00 },
- { 0x034c, 0x03 },
- { 0x034d, 0x34 },
- { 0x034e, 0x02 },
- { 0x034f, 0x68 },
{ 0x0700, 0x02 },
{ 0x0701, 0x78 },
};
@@ -590,6 +436,12 @@ static const struct imx355_mode supported_modes[] = {
.num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
.regs = mode_3280x2464_regs,
},
+ .x_add_start = 0x0000,
+ .y_add_start = 0x0000,
+ .x_add_end = 0x0ccf,
+ .y_add_end = 0x099f,
+ .x_out_size = 0x0cd0,
+ .y_out_size = 0x09a0,
},
{
.width = 3268,
@@ -602,6 +454,12 @@ static const struct imx355_mode supported_modes[] = {
.num_of_regs = ARRAY_SIZE(mode_3268x2448_regs),
.regs = mode_3268x2448_regs,
},
+ .x_add_start = 0x0008,
+ .y_add_start = 0x0008,
+ .x_add_end = 0x0ccb,
+ .y_add_end = 0x997,
+ .x_out_size = 0x0cc4,
+ .y_out_size = 0x0990,
},
{
.width = 3264,
@@ -614,6 +472,12 @@ static const struct imx355_mode supported_modes[] = {
.num_of_regs = ARRAY_SIZE(mode_3264x2448_regs),
.regs = mode_3264x2448_regs,
},
+ .x_add_start = 0x0008,
+ .y_add_start = 0x0008,
+ .x_add_end = 0x0cc7,
+ .y_add_end = 0x0997,
+ .x_out_size = 0x0cc0,
+ .y_out_size = 0x0990,
},
{
.width = 1940,
@@ -626,6 +490,12 @@ static const struct imx355_mode supported_modes[] = {
.num_of_regs = ARRAY_SIZE(mode_1940x1096_regs),
.regs = mode_1940x1096_regs,
},
+ .x_add_start = 0x02a0,
+ .y_add_start = 0x02ac,
+ .x_add_end = 0x0a33,
+ .y_add_end = 0x06f3,
+ .x_out_size = 0x0794,
+ .y_out_size = 0x0448,
},
{
.width = 1936,
@@ -638,6 +508,12 @@ static const struct imx355_mode supported_modes[] = {
.num_of_regs = ARRAY_SIZE(mode_1936x1096_regs),
.regs = mode_1936x1096_regs,
},
+ .x_add_start = 0x02a0,
+ .y_add_start = 0x02ac,
+ .x_add_end = 0x0a2f,
+ .y_add_end = 0x06f3,
+ .x_out_size = 0x0790,
+ .y_out_size = 0x0448,
},
{
.width = 1924,
@@ -650,6 +526,12 @@ static const struct imx355_mode supported_modes[] = {
.num_of_regs = ARRAY_SIZE(mode_1924x1080_regs),
.regs = mode_1924x1080_regs,
},
+ .x_add_start = 0x02a8,
+ .y_add_start = 0x02b4,
+ .x_add_end = 0x0a2b,
+ .y_add_end = 0x06eb,
+ .x_out_size = 0x0784,
+ .y_out_size = 0x0438,
},
{
.width = 1920,
@@ -662,6 +544,12 @@ static const struct imx355_mode supported_modes[] = {
.num_of_regs = ARRAY_SIZE(mode_1920x1080_regs),
.regs = mode_1920x1080_regs,
},
+ .x_add_start = 0x02a8,
+ .y_add_start = 0x02b4,
+ .x_add_end = 0x0a27,
+ .y_add_end = 0x06eb,
+ .x_out_size = 0x0780,
+ .y_out_size = 0x0438,
},
{
.width = 1640,
@@ -674,6 +562,12 @@ static const struct imx355_mode supported_modes[] = {
.num_of_regs = ARRAY_SIZE(mode_1640x1232_regs),
.regs = mode_1640x1232_regs,
},
+ .x_add_start = 0x0000,
+ .y_add_start = 0x0000,
+ .x_add_end = 0x0ccf,
+ .y_add_end = 0x099f,
+ .x_out_size = 0x0668,
+ .y_out_size = 0x04d0,
},
{
.width = 1640,
@@ -686,6 +580,12 @@ static const struct imx355_mode supported_modes[] = {
.num_of_regs = ARRAY_SIZE(mode_1640x922_regs),
.regs = mode_1640x922_regs,
},
+ .x_add_start = 0x0000,
+ .y_add_start = 0x0130,
+ .x_add_end = 0x0ccf,
+ .y_add_end = 0x0863,
+ .x_out_size = 0x0668,
+ .y_out_size = 0x039a,
},
{
.width = 1300,
@@ -698,6 +598,12 @@ static const struct imx355_mode supported_modes[] = {
.num_of_regs = ARRAY_SIZE(mode_1300x736_regs),
.regs = mode_1300x736_regs,
},
+ .x_add_start = 0x0158,
+ .y_add_start = 0x01f0,
+ .x_add_end = 0x0b7f,
+ .y_add_end = 0x07af,
+ .x_out_size = 0x0514,
+ .y_out_size = 0x02e0,
},
{
.width = 1296,
@@ -710,6 +616,12 @@ static const struct imx355_mode supported_modes[] = {
.num_of_regs = ARRAY_SIZE(mode_1296x736_regs),
.regs = mode_1296x736_regs,
},
+ .x_add_start = 0x0158,
+ .y_add_start = 0x01f0,
+ .x_add_end = 0x0b77,
+ .y_add_end = 0x07af,
+ .x_out_size = 0x0510,
+ .y_out_size = 0x02e0,
},
{
.width = 1284,
@@ -722,6 +634,12 @@ static const struct imx355_mode supported_modes[] = {
.num_of_regs = ARRAY_SIZE(mode_1284x720_regs),
.regs = mode_1284x720_regs,
},
+ .x_add_start = 0x0168,
+ .y_add_start = 0x0200,
+ .x_add_end = 0x0b6f,
+ .y_add_end = 0x079f,
+ .x_out_size = 0x0504,
+ .y_out_size = 0x02d0,
},
{
.width = 1280,
@@ -734,6 +652,12 @@ static const struct imx355_mode supported_modes[] = {
.num_of_regs = ARRAY_SIZE(mode_1280x720_regs),
.regs = mode_1280x720_regs,
},
+ .x_add_start = 0x0168,
+ .y_add_start = 0x0200,
+ .x_add_end = 0x0b67,
+ .y_add_end = 0x079f,
+ .x_out_size = 0x0500,
+ .y_out_size = 0x02d0,
},
{
.width = 820,
@@ -746,6 +670,12 @@ static const struct imx355_mode supported_modes[] = {
.num_of_regs = ARRAY_SIZE(mode_820x616_regs),
.regs = mode_820x616_regs,
},
+ .x_add_start = 0x0000,
+ .y_add_start = 0x0000,
+ .x_add_end = 0x0ccf,
+ .y_add_end = 0x099f,
+ .x_out_size = 0x0334,
+ .y_out_size = 0x0268,
},
};
@@ -1076,6 +1006,7 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
static int imx355_start_streaming(struct imx355 *imx355)
{
const struct imx355_reg_list *reg_list;
+ const struct imx355_mode *mode;
int ret;
/* Global Setting */
@@ -1087,13 +1018,40 @@ static int imx355_start_streaming(struct imx355 *imx355)
}
/* Apply default values of current mode */
- reg_list = &imx355->cur_mode->reg_list;
+ mode = imx355->cur_mode;
+ reg_list = &mode->reg_list;
ret = imx355_write_regs(imx355, reg_list->regs, reg_list->num_of_regs);
if (ret) {
dev_err(imx355->dev, "failed to set mode");
return ret;
}
+ /* Set readout crop and size registers */
+ ret = imx355_write_reg(imx355, IMX355_REG_X_ADD_START, 2,
+ mode->x_add_start);
+ if (ret)
+ return ret;
+ ret = imx355_write_reg(imx355, IMX355_REG_Y_ADD_START, 2,
+ mode->y_add_start);
+ if (ret)
+ return ret;
+ ret = imx355_write_reg(imx355, IMX355_REG_X_ADD_END, 2,
+ mode->x_add_end);
+ if (ret)
+ return ret;
+ ret = imx355_write_reg(imx355, IMX355_REG_Y_ADD_END, 2,
+ mode->y_add_end);
+ if (ret)
+ return ret;
+ ret = imx355_write_reg(imx355, IMX355_REG_X_OUT_SIZE, 2,
+ mode->x_out_size);
+ if (ret)
+ return ret;
+ ret = imx355_write_reg(imx355, IMX355_REG_Y_OUT_SIZE, 2,
+ mode->y_out_size);
+ if (ret)
+ return ret;
+
/* Set PLL registers for the external clock frequency */
ret = imx355_write_reg(imx355, IMX355_REG_EXTCLK_FREQ, 2,
imx355->clk_params->extclk_freq);
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread* Re: [PATCH 03/13] media: imx355: Programmatically set the crop parameters for each mode
2026-05-06 18:23 ` [PATCH 03/13] media: imx355: Programmatically set the crop parameters for each mode Dave Stevenson
@ 2026-05-07 14:00 ` Jacopo Mondi
2026-05-07 16:01 ` Dave Stevenson
0 siblings, 1 reply; 29+ messages in thread
From: Jacopo Mondi @ 2026-05-07 14:00 UTC (permalink / raw)
To: Dave Stevenson
Cc: Tianshu Qiu, Sakari Ailus, Mauro Carvalho Chehab, linux-media,
linux-kernel, David Heidelberg,
20260414-imx355-24mhz-v1-1-9ae77bc6e7ec
Hi Dave
On Wed, May 06, 2026 at 07:23:41PM +0100, Dave Stevenson wrote:
> Currently the cropping is set via register entries in the per mode
> register lists. Move those into the mode structure and set them
> programmatically.
>
> x_out_size and y_out_size are duplicates of width and height, but
> are retained in this patch for ease of review.
>
> Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
> ---
> drivers/media/i2c/imx355.c | 296 +++++++++++++++++++--------------------------
> 1 file changed, 127 insertions(+), 169 deletions(-)
>
> diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
> index 8ea510218c7c..6179fe74c897 100644
> --- a/drivers/media/i2c/imx355.c
> +++ b/drivers/media/i2c/imx355.c
> @@ -34,6 +34,13 @@
> #define IMX355_REG_FLL 0x0340
> #define IMX355_FLL_MAX 0xffff
>
> +#define IMX355_REG_X_ADD_START 0x0344
> +#define IMX355_REG_Y_ADD_START 0x0346
> +#define IMX355_REG_X_ADD_END 0x0348
> +#define IMX355_REG_Y_ADD_END 0x034a
> +#define IMX355_REG_X_OUT_SIZE 0x034c
> +#define IMX355_REG_Y_OUT_SIZE 0x034e
> +
> /* Exposure control */
> #define IMX355_REG_EXPOSURE 0x0202
> #define IMX355_EXPOSURE_MIN 1
> @@ -102,6 +109,13 @@ struct imx355_mode {
>
> /* Default register values */
> struct imx355_reg_list reg_list;
> +
> + u16 x_add_start;
> + u16 y_add_start;
> + u16 x_add_end;
> + u16 y_add_end;
> + u16 x_out_size;
> + u16 y_out_size;
Wouldn't it be better to define a per-mode v4l2_rect {} and
calculate the output size as [height - top + 1] (or [width - left + 1]) ?
In this way we can initialize a "sane" default analogue crop to
program at s_start time. It then would be trivial once the driver is
ported to the common RAW sensor model to use the selection target on
the (eventually introduced) internal pad and use that one to program
the analog crop ?
> };
>
> struct imx355_clk_params {
> @@ -256,21 +270,9 @@ static const struct imx355_reg_list imx355_global_setting = {
> static const struct imx355_reg mode_3268x2448_regs[] = {
> { 0x0342, 0x0e },
> { 0x0343, 0x58 },
> - { 0x0344, 0x00 },
> - { 0x0345, 0x08 },
> - { 0x0346, 0x00 },
> - { 0x0347, 0x08 },
> - { 0x0348, 0x0c },
> - { 0x0349, 0xcb },
> - { 0x034a, 0x09 },
> - { 0x034b, 0x97 },
> { 0x0900, 0x00 },
> { 0x0901, 0x11 },
> { 0x0902, 0x00 },
> - { 0x034c, 0x0c },
> - { 0x034d, 0xc4 },
> - { 0x034e, 0x09 },
> - { 0x034f, 0x90 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> };
> @@ -278,21 +280,9 @@ static const struct imx355_reg mode_3268x2448_regs[] = {
> static const struct imx355_reg mode_3264x2448_regs[] = {
> { 0x0342, 0x0e },
> { 0x0343, 0x58 },
> - { 0x0344, 0x00 },
> - { 0x0345, 0x08 },
> - { 0x0346, 0x00 },
> - { 0x0347, 0x08 },
> - { 0x0348, 0x0c },
> - { 0x0349, 0xc7 },
> - { 0x034a, 0x09 },
> - { 0x034b, 0x97 },
> { 0x0900, 0x00 },
> { 0x0901, 0x11 },
> { 0x0902, 0x00 },
> - { 0x034c, 0x0c },
> - { 0x034d, 0xc0 },
> - { 0x034e, 0x09 },
> - { 0x034f, 0x90 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> };
> @@ -300,21 +290,9 @@ static const struct imx355_reg mode_3264x2448_regs[] = {
> static const struct imx355_reg mode_3280x2464_regs[] = {
> { 0x0342, 0x0e },
> { 0x0343, 0x58 },
> - { 0x0344, 0x00 },
> - { 0x0345, 0x00 },
> - { 0x0346, 0x00 },
> - { 0x0347, 0x00 },
> - { 0x0348, 0x0c },
> - { 0x0349, 0xcf },
> - { 0x034a, 0x09 },
> - { 0x034b, 0x9f },
> { 0x0900, 0x00 },
> { 0x0901, 0x11 },
> { 0x0902, 0x00 },
> - { 0x034c, 0x0c },
> - { 0x034d, 0xd0 },
> - { 0x034e, 0x09 },
> - { 0x034f, 0xa0 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> };
> @@ -322,21 +300,9 @@ static const struct imx355_reg mode_3280x2464_regs[] = {
> static const struct imx355_reg mode_1940x1096_regs[] = {
> { 0x0342, 0x0e },
> { 0x0343, 0x58 },
> - { 0x0344, 0x02 },
> - { 0x0345, 0xa0 },
> - { 0x0346, 0x02 },
> - { 0x0347, 0xac },
> - { 0x0348, 0x0a },
> - { 0x0349, 0x33 },
> - { 0x034a, 0x06 },
> - { 0x034b, 0xf3 },
> { 0x0900, 0x00 },
> { 0x0901, 0x11 },
> { 0x0902, 0x00 },
> - { 0x034c, 0x07 },
> - { 0x034d, 0x94 },
> - { 0x034e, 0x04 },
> - { 0x034f, 0x48 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> };
> @@ -344,21 +310,9 @@ static const struct imx355_reg mode_1940x1096_regs[] = {
> static const struct imx355_reg mode_1936x1096_regs[] = {
> { 0x0342, 0x0e },
> { 0x0343, 0x58 },
> - { 0x0344, 0x02 },
> - { 0x0345, 0xa0 },
> - { 0x0346, 0x02 },
> - { 0x0347, 0xac },
> - { 0x0348, 0x0a },
> - { 0x0349, 0x2f },
> - { 0x034a, 0x06 },
> - { 0x034b, 0xf3 },
> { 0x0900, 0x00 },
> { 0x0901, 0x11 },
> { 0x0902, 0x00 },
> - { 0x034c, 0x07 },
> - { 0x034d, 0x90 },
> - { 0x034e, 0x04 },
> - { 0x034f, 0x48 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> };
> @@ -366,21 +320,9 @@ static const struct imx355_reg mode_1936x1096_regs[] = {
> static const struct imx355_reg mode_1924x1080_regs[] = {
> { 0x0342, 0x0e },
> { 0x0343, 0x58 },
> - { 0x0344, 0x02 },
> - { 0x0345, 0xa8 },
> - { 0x0346, 0x02 },
> - { 0x0347, 0xb4 },
> - { 0x0348, 0x0a },
> - { 0x0349, 0x2b },
> - { 0x034a, 0x06 },
> - { 0x034b, 0xeb },
> { 0x0900, 0x00 },
> { 0x0901, 0x11 },
> { 0x0902, 0x00 },
> - { 0x034c, 0x07 },
> - { 0x034d, 0x84 },
> - { 0x034e, 0x04 },
> - { 0x034f, 0x38 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> };
> @@ -388,21 +330,9 @@ static const struct imx355_reg mode_1924x1080_regs[] = {
> static const struct imx355_reg mode_1920x1080_regs[] = {
> { 0x0342, 0x0e },
> { 0x0343, 0x58 },
> - { 0x0344, 0x02 },
> - { 0x0345, 0xa8 },
> - { 0x0346, 0x02 },
> - { 0x0347, 0xb4 },
> - { 0x0348, 0x0a },
> - { 0x0349, 0x27 },
> - { 0x034a, 0x06 },
> - { 0x034b, 0xeb },
> { 0x0900, 0x00 },
> { 0x0901, 0x11 },
> { 0x0902, 0x00 },
> - { 0x034c, 0x07 },
> - { 0x034d, 0x80 },
> - { 0x034e, 0x04 },
> - { 0x034f, 0x38 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> };
> @@ -410,21 +340,9 @@ static const struct imx355_reg mode_1920x1080_regs[] = {
> static const struct imx355_reg mode_1640x1232_regs[] = {
> { 0x0342, 0x07 },
> { 0x0343, 0x2c },
> - { 0x0344, 0x00 },
> - { 0x0345, 0x00 },
> - { 0x0346, 0x00 },
> - { 0x0347, 0x00 },
> - { 0x0348, 0x0c },
> - { 0x0349, 0xcf },
> - { 0x034a, 0x09 },
> - { 0x034b, 0x9f },
> { 0x0900, 0x01 },
> { 0x0901, 0x22 },
> { 0x0902, 0x00 },
> - { 0x034c, 0x06 },
> - { 0x034d, 0x68 },
> - { 0x034e, 0x04 },
> - { 0x034f, 0xd0 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> };
> @@ -432,21 +350,9 @@ static const struct imx355_reg mode_1640x1232_regs[] = {
> static const struct imx355_reg mode_1640x922_regs[] = {
> { 0x0342, 0x07 },
> { 0x0343, 0x2c },
> - { 0x0344, 0x00 },
> - { 0x0345, 0x00 },
> - { 0x0346, 0x01 },
> - { 0x0347, 0x30 },
> - { 0x0348, 0x0c },
> - { 0x0349, 0xcf },
> - { 0x034a, 0x08 },
> - { 0x034b, 0x63 },
> { 0x0900, 0x01 },
> { 0x0901, 0x22 },
> { 0x0902, 0x00 },
> - { 0x034c, 0x06 },
> - { 0x034d, 0x68 },
> - { 0x034e, 0x03 },
> - { 0x034f, 0x9a },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> };
> @@ -454,21 +360,9 @@ static const struct imx355_reg mode_1640x922_regs[] = {
> static const struct imx355_reg mode_1300x736_regs[] = {
> { 0x0342, 0x07 },
> { 0x0343, 0x2c },
> - { 0x0344, 0x01 },
> - { 0x0345, 0x58 },
> - { 0x0346, 0x01 },
> - { 0x0347, 0xf0 },
> - { 0x0348, 0x0b },
> - { 0x0349, 0x7f },
> - { 0x034a, 0x07 },
> - { 0x034b, 0xaf },
> { 0x0900, 0x01 },
> { 0x0901, 0x22 },
> { 0x0902, 0x00 },
> - { 0x034c, 0x05 },
> - { 0x034d, 0x14 },
> - { 0x034e, 0x02 },
> - { 0x034f, 0xe0 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> };
> @@ -476,21 +370,9 @@ static const struct imx355_reg mode_1300x736_regs[] = {
> static const struct imx355_reg mode_1296x736_regs[] = {
> { 0x0342, 0x07 },
> { 0x0343, 0x2c },
> - { 0x0344, 0x01 },
> - { 0x0345, 0x58 },
> - { 0x0346, 0x01 },
> - { 0x0347, 0xf0 },
> - { 0x0348, 0x0b },
> - { 0x0349, 0x77 },
> - { 0x034a, 0x07 },
> - { 0x034b, 0xaf },
> { 0x0900, 0x01 },
> { 0x0901, 0x22 },
> { 0x0902, 0x00 },
> - { 0x034c, 0x05 },
> - { 0x034d, 0x10 },
> - { 0x034e, 0x02 },
> - { 0x034f, 0xe0 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> };
> @@ -498,21 +380,9 @@ static const struct imx355_reg mode_1296x736_regs[] = {
> static const struct imx355_reg mode_1284x720_regs[] = {
> { 0x0342, 0x07 },
> { 0x0343, 0x2c },
> - { 0x0344, 0x01 },
> - { 0x0345, 0x68 },
> - { 0x0346, 0x02 },
> - { 0x0347, 0x00 },
> - { 0x0348, 0x0b },
> - { 0x0349, 0x6f },
> - { 0x034a, 0x07 },
> - { 0x034b, 0x9f },
> { 0x0900, 0x01 },
> { 0x0901, 0x22 },
> { 0x0902, 0x00 },
> - { 0x034c, 0x05 },
> - { 0x034d, 0x04 },
> - { 0x034e, 0x02 },
> - { 0x034f, 0xd0 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> };
> @@ -520,21 +390,9 @@ static const struct imx355_reg mode_1284x720_regs[] = {
> static const struct imx355_reg mode_1280x720_regs[] = {
> { 0x0342, 0x07 },
> { 0x0343, 0x2c },
> - { 0x0344, 0x01 },
> - { 0x0345, 0x68 },
> - { 0x0346, 0x02 },
> - { 0x0347, 0x00 },
> - { 0x0348, 0x0b },
> - { 0x0349, 0x67 },
> - { 0x034a, 0x07 },
> - { 0x034b, 0x9f },
> { 0x0900, 0x01 },
> { 0x0901, 0x22 },
> { 0x0902, 0x00 },
> - { 0x034c, 0x05 },
> - { 0x034d, 0x00 },
> - { 0x034e, 0x02 },
> - { 0x034f, 0xd0 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> };
> @@ -542,21 +400,9 @@ static const struct imx355_reg mode_1280x720_regs[] = {
> static const struct imx355_reg mode_820x616_regs[] = {
> { 0x0342, 0x0e },
> { 0x0343, 0x58 },
> - { 0x0344, 0x00 },
> - { 0x0345, 0x00 },
> - { 0x0346, 0x00 },
> - { 0x0347, 0x00 },
> - { 0x0348, 0x0c },
> - { 0x0349, 0xcf },
> - { 0x034a, 0x09 },
> - { 0x034b, 0x9f },
> { 0x0900, 0x01 },
> { 0x0901, 0x44 },
> { 0x0902, 0x00 },
> - { 0x034c, 0x03 },
> - { 0x034d, 0x34 },
> - { 0x034e, 0x02 },
> - { 0x034f, 0x68 },
> { 0x0700, 0x02 },
> { 0x0701, 0x78 },
> };
> @@ -590,6 +436,12 @@ static const struct imx355_mode supported_modes[] = {
> .num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
> .regs = mode_3280x2464_regs,
> },
> + .x_add_start = 0x0000,
> + .y_add_start = 0x0000,
> + .x_add_end = 0x0ccf,
> + .y_add_end = 0x099f,
> + .x_out_size = 0x0cd0,
> + .y_out_size = 0x09a0,
> },
> {
> .width = 3268,
> @@ -602,6 +454,12 @@ static const struct imx355_mode supported_modes[] = {
> .num_of_regs = ARRAY_SIZE(mode_3268x2448_regs),
> .regs = mode_3268x2448_regs,
> },
> + .x_add_start = 0x0008,
> + .y_add_start = 0x0008,
> + .x_add_end = 0x0ccb,
> + .y_add_end = 0x997,
> + .x_out_size = 0x0cc4,
> + .y_out_size = 0x0990,
> },
> {
> .width = 3264,
> @@ -614,6 +472,12 @@ static const struct imx355_mode supported_modes[] = {
> .num_of_regs = ARRAY_SIZE(mode_3264x2448_regs),
> .regs = mode_3264x2448_regs,
> },
> + .x_add_start = 0x0008,
> + .y_add_start = 0x0008,
> + .x_add_end = 0x0cc7,
> + .y_add_end = 0x0997,
> + .x_out_size = 0x0cc0,
> + .y_out_size = 0x0990,
> },
> {
> .width = 1940,
> @@ -626,6 +490,12 @@ static const struct imx355_mode supported_modes[] = {
> .num_of_regs = ARRAY_SIZE(mode_1940x1096_regs),
> .regs = mode_1940x1096_regs,
> },
> + .x_add_start = 0x02a0,
> + .y_add_start = 0x02ac,
> + .x_add_end = 0x0a33,
> + .y_add_end = 0x06f3,
> + .x_out_size = 0x0794,
> + .y_out_size = 0x0448,
> },
> {
> .width = 1936,
> @@ -638,6 +508,12 @@ static const struct imx355_mode supported_modes[] = {
> .num_of_regs = ARRAY_SIZE(mode_1936x1096_regs),
> .regs = mode_1936x1096_regs,
> },
> + .x_add_start = 0x02a0,
> + .y_add_start = 0x02ac,
> + .x_add_end = 0x0a2f,
> + .y_add_end = 0x06f3,
> + .x_out_size = 0x0790,
> + .y_out_size = 0x0448,
> },
> {
> .width = 1924,
> @@ -650,6 +526,12 @@ static const struct imx355_mode supported_modes[] = {
> .num_of_regs = ARRAY_SIZE(mode_1924x1080_regs),
> .regs = mode_1924x1080_regs,
> },
> + .x_add_start = 0x02a8,
> + .y_add_start = 0x02b4,
> + .x_add_end = 0x0a2b,
> + .y_add_end = 0x06eb,
> + .x_out_size = 0x0784,
> + .y_out_size = 0x0438,
> },
> {
> .width = 1920,
> @@ -662,6 +544,12 @@ static const struct imx355_mode supported_modes[] = {
> .num_of_regs = ARRAY_SIZE(mode_1920x1080_regs),
> .regs = mode_1920x1080_regs,
> },
> + .x_add_start = 0x02a8,
> + .y_add_start = 0x02b4,
> + .x_add_end = 0x0a27,
> + .y_add_end = 0x06eb,
> + .x_out_size = 0x0780,
> + .y_out_size = 0x0438,
> },
> {
> .width = 1640,
> @@ -674,6 +562,12 @@ static const struct imx355_mode supported_modes[] = {
> .num_of_regs = ARRAY_SIZE(mode_1640x1232_regs),
> .regs = mode_1640x1232_regs,
> },
> + .x_add_start = 0x0000,
> + .y_add_start = 0x0000,
> + .x_add_end = 0x0ccf,
> + .y_add_end = 0x099f,
> + .x_out_size = 0x0668,
> + .y_out_size = 0x04d0,
> },
> {
> .width = 1640,
> @@ -686,6 +580,12 @@ static const struct imx355_mode supported_modes[] = {
> .num_of_regs = ARRAY_SIZE(mode_1640x922_regs),
> .regs = mode_1640x922_regs,
> },
> + .x_add_start = 0x0000,
> + .y_add_start = 0x0130,
> + .x_add_end = 0x0ccf,
> + .y_add_end = 0x0863,
> + .x_out_size = 0x0668,
> + .y_out_size = 0x039a,
> },
> {
> .width = 1300,
> @@ -698,6 +598,12 @@ static const struct imx355_mode supported_modes[] = {
> .num_of_regs = ARRAY_SIZE(mode_1300x736_regs),
> .regs = mode_1300x736_regs,
> },
> + .x_add_start = 0x0158,
> + .y_add_start = 0x01f0,
> + .x_add_end = 0x0b7f,
> + .y_add_end = 0x07af,
> + .x_out_size = 0x0514,
> + .y_out_size = 0x02e0,
> },
> {
> .width = 1296,
> @@ -710,6 +616,12 @@ static const struct imx355_mode supported_modes[] = {
> .num_of_regs = ARRAY_SIZE(mode_1296x736_regs),
> .regs = mode_1296x736_regs,
> },
> + .x_add_start = 0x0158,
> + .y_add_start = 0x01f0,
> + .x_add_end = 0x0b77,
> + .y_add_end = 0x07af,
> + .x_out_size = 0x0510,
> + .y_out_size = 0x02e0,
> },
> {
> .width = 1284,
> @@ -722,6 +634,12 @@ static const struct imx355_mode supported_modes[] = {
> .num_of_regs = ARRAY_SIZE(mode_1284x720_regs),
> .regs = mode_1284x720_regs,
> },
> + .x_add_start = 0x0168,
> + .y_add_start = 0x0200,
> + .x_add_end = 0x0b6f,
> + .y_add_end = 0x079f,
> + .x_out_size = 0x0504,
> + .y_out_size = 0x02d0,
> },
> {
> .width = 1280,
> @@ -734,6 +652,12 @@ static const struct imx355_mode supported_modes[] = {
> .num_of_regs = ARRAY_SIZE(mode_1280x720_regs),
> .regs = mode_1280x720_regs,
> },
> + .x_add_start = 0x0168,
> + .y_add_start = 0x0200,
> + .x_add_end = 0x0b67,
> + .y_add_end = 0x079f,
> + .x_out_size = 0x0500,
> + .y_out_size = 0x02d0,
> },
> {
> .width = 820,
> @@ -746,6 +670,12 @@ static const struct imx355_mode supported_modes[] = {
> .num_of_regs = ARRAY_SIZE(mode_820x616_regs),
> .regs = mode_820x616_regs,
> },
> + .x_add_start = 0x0000,
> + .y_add_start = 0x0000,
> + .x_add_end = 0x0ccf,
> + .y_add_end = 0x099f,
> + .x_out_size = 0x0334,
> + .y_out_size = 0x0268,
> },
> };
>
> @@ -1076,6 +1006,7 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
> static int imx355_start_streaming(struct imx355 *imx355)
> {
> const struct imx355_reg_list *reg_list;
> + const struct imx355_mode *mode;
> int ret;
>
> /* Global Setting */
> @@ -1087,13 +1018,40 @@ static int imx355_start_streaming(struct imx355 *imx355)
> }
>
> /* Apply default values of current mode */
> - reg_list = &imx355->cur_mode->reg_list;
> + mode = imx355->cur_mode;
> + reg_list = &mode->reg_list;
> ret = imx355_write_regs(imx355, reg_list->regs, reg_list->num_of_regs);
> if (ret) {
> dev_err(imx355->dev, "failed to set mode");
> return ret;
> }
>
> + /* Set readout crop and size registers */
> + ret = imx355_write_reg(imx355, IMX355_REG_X_ADD_START, 2,
> + mode->x_add_start);
> + if (ret)
> + return ret;
> + ret = imx355_write_reg(imx355, IMX355_REG_Y_ADD_START, 2,
> + mode->y_add_start);
> + if (ret)
> + return ret;
> + ret = imx355_write_reg(imx355, IMX355_REG_X_ADD_END, 2,
> + mode->x_add_end);
> + if (ret)
> + return ret;
> + ret = imx355_write_reg(imx355, IMX355_REG_Y_ADD_END, 2,
> + mode->y_add_end);
> + if (ret)
> + return ret;
> + ret = imx355_write_reg(imx355, IMX355_REG_X_OUT_SIZE, 2,
> + mode->x_out_size);
> + if (ret)
> + return ret;
> + ret = imx355_write_reg(imx355, IMX355_REG_Y_OUT_SIZE, 2,
> + mode->y_out_size);
> + if (ret)
> + return ret;
> +
> /* Set PLL registers for the external clock frequency */
> ret = imx355_write_reg(imx355, IMX355_REG_EXTCLK_FREQ, 2,
> imx355->clk_params->extclk_freq);
>
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 29+ messages in thread* Re: [PATCH 03/13] media: imx355: Programmatically set the crop parameters for each mode
2026-05-07 14:00 ` Jacopo Mondi
@ 2026-05-07 16:01 ` Dave Stevenson
0 siblings, 0 replies; 29+ messages in thread
From: Dave Stevenson @ 2026-05-07 16:01 UTC (permalink / raw)
To: Jacopo Mondi
Cc: Sakari Ailus, Mauro Carvalho Chehab, linux-media, linux-kernel,
David Heidelberg
Hi Jacopo
On Thu, 7 May 2026 at 15:00, Jacopo Mondi <jacopo.mondi@ideasonboard.com> wrote:
>
> Hi Dave
>
> On Wed, May 06, 2026 at 07:23:41PM +0100, Dave Stevenson wrote:
> > Currently the cropping is set via register entries in the per mode
> > register lists. Move those into the mode structure and set them
> > programmatically.
> >
> > x_out_size and y_out_size are duplicates of width and height, but
> > are retained in this patch for ease of review.
> >
> > Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
> > ---
> > drivers/media/i2c/imx355.c | 296 +++++++++++++++++++--------------------------
> > 1 file changed, 127 insertions(+), 169 deletions(-)
> >
> > diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
> > index 8ea510218c7c..6179fe74c897 100644
> > --- a/drivers/media/i2c/imx355.c
> > +++ b/drivers/media/i2c/imx355.c
> > @@ -34,6 +34,13 @@
> > #define IMX355_REG_FLL 0x0340
> > #define IMX355_FLL_MAX 0xffff
> >
> > +#define IMX355_REG_X_ADD_START 0x0344
> > +#define IMX355_REG_Y_ADD_START 0x0346
> > +#define IMX355_REG_X_ADD_END 0x0348
> > +#define IMX355_REG_Y_ADD_END 0x034a
> > +#define IMX355_REG_X_OUT_SIZE 0x034c
> > +#define IMX355_REG_Y_OUT_SIZE 0x034e
> > +
> > /* Exposure control */
> > #define IMX355_REG_EXPOSURE 0x0202
> > #define IMX355_EXPOSURE_MIN 1
> > @@ -102,6 +109,13 @@ struct imx355_mode {
> >
> > /* Default register values */
> > struct imx355_reg_list reg_list;
> > +
> > + u16 x_add_start;
> > + u16 y_add_start;
> > + u16 x_add_end;
> > + u16 y_add_end;
> > + u16 x_out_size;
> > + u16 y_out_size;
>
> Wouldn't it be better to define a per-mode v4l2_rect {} and
> calculate the output size as [height - top + 1] (or [width - left + 1]) ?
Again I was largely going for the softly softly to avoid regressions.
Shifting from reg writes to the same numbers being visible in the
structures is difficult to get wrong and easy to review. Converting to
top/left is obvious. If you're prepared to double check all the values
are correct, then I'll update to move width & height into a v4l2_rect
alongside top & left.
It'll also combine patch 4 into this one to make it a bigger bang.
> In this way we can initialize a "sane" default analogue crop to
> program at s_start time. It then would be trivial once the driver is
> ported to the common RAW sensor model to use the selection target on
> the (eventually introduced) internal pad and use that one to program
> the analog crop ?
I haven't had a chance to look into the common RAW sensor model and
how it impacts things.
Dave
>
> > };
> >
> > struct imx355_clk_params {
> > @@ -256,21 +270,9 @@ static const struct imx355_reg_list imx355_global_setting = {
> > static const struct imx355_reg mode_3268x2448_regs[] = {
> > { 0x0342, 0x0e },
> > { 0x0343, 0x58 },
> > - { 0x0344, 0x00 },
> > - { 0x0345, 0x08 },
> > - { 0x0346, 0x00 },
> > - { 0x0347, 0x08 },
> > - { 0x0348, 0x0c },
> > - { 0x0349, 0xcb },
> > - { 0x034a, 0x09 },
> > - { 0x034b, 0x97 },
> > { 0x0900, 0x00 },
> > { 0x0901, 0x11 },
> > { 0x0902, 0x00 },
> > - { 0x034c, 0x0c },
> > - { 0x034d, 0xc4 },
> > - { 0x034e, 0x09 },
> > - { 0x034f, 0x90 },
> > { 0x0700, 0x00 },
> > { 0x0701, 0x10 },
> > };
> > @@ -278,21 +280,9 @@ static const struct imx355_reg mode_3268x2448_regs[] = {
> > static const struct imx355_reg mode_3264x2448_regs[] = {
> > { 0x0342, 0x0e },
> > { 0x0343, 0x58 },
> > - { 0x0344, 0x00 },
> > - { 0x0345, 0x08 },
> > - { 0x0346, 0x00 },
> > - { 0x0347, 0x08 },
> > - { 0x0348, 0x0c },
> > - { 0x0349, 0xc7 },
> > - { 0x034a, 0x09 },
> > - { 0x034b, 0x97 },
> > { 0x0900, 0x00 },
> > { 0x0901, 0x11 },
> > { 0x0902, 0x00 },
> > - { 0x034c, 0x0c },
> > - { 0x034d, 0xc0 },
> > - { 0x034e, 0x09 },
> > - { 0x034f, 0x90 },
> > { 0x0700, 0x00 },
> > { 0x0701, 0x10 },
> > };
> > @@ -300,21 +290,9 @@ static const struct imx355_reg mode_3264x2448_regs[] = {
> > static const struct imx355_reg mode_3280x2464_regs[] = {
> > { 0x0342, 0x0e },
> > { 0x0343, 0x58 },
> > - { 0x0344, 0x00 },
> > - { 0x0345, 0x00 },
> > - { 0x0346, 0x00 },
> > - { 0x0347, 0x00 },
> > - { 0x0348, 0x0c },
> > - { 0x0349, 0xcf },
> > - { 0x034a, 0x09 },
> > - { 0x034b, 0x9f },
> > { 0x0900, 0x00 },
> > { 0x0901, 0x11 },
> > { 0x0902, 0x00 },
> > - { 0x034c, 0x0c },
> > - { 0x034d, 0xd0 },
> > - { 0x034e, 0x09 },
> > - { 0x034f, 0xa0 },
> > { 0x0700, 0x00 },
> > { 0x0701, 0x10 },
> > };
> > @@ -322,21 +300,9 @@ static const struct imx355_reg mode_3280x2464_regs[] = {
> > static const struct imx355_reg mode_1940x1096_regs[] = {
> > { 0x0342, 0x0e },
> > { 0x0343, 0x58 },
> > - { 0x0344, 0x02 },
> > - { 0x0345, 0xa0 },
> > - { 0x0346, 0x02 },
> > - { 0x0347, 0xac },
> > - { 0x0348, 0x0a },
> > - { 0x0349, 0x33 },
> > - { 0x034a, 0x06 },
> > - { 0x034b, 0xf3 },
> > { 0x0900, 0x00 },
> > { 0x0901, 0x11 },
> > { 0x0902, 0x00 },
> > - { 0x034c, 0x07 },
> > - { 0x034d, 0x94 },
> > - { 0x034e, 0x04 },
> > - { 0x034f, 0x48 },
> > { 0x0700, 0x00 },
> > { 0x0701, 0x10 },
> > };
> > @@ -344,21 +310,9 @@ static const struct imx355_reg mode_1940x1096_regs[] = {
> > static const struct imx355_reg mode_1936x1096_regs[] = {
> > { 0x0342, 0x0e },
> > { 0x0343, 0x58 },
> > - { 0x0344, 0x02 },
> > - { 0x0345, 0xa0 },
> > - { 0x0346, 0x02 },
> > - { 0x0347, 0xac },
> > - { 0x0348, 0x0a },
> > - { 0x0349, 0x2f },
> > - { 0x034a, 0x06 },
> > - { 0x034b, 0xf3 },
> > { 0x0900, 0x00 },
> > { 0x0901, 0x11 },
> > { 0x0902, 0x00 },
> > - { 0x034c, 0x07 },
> > - { 0x034d, 0x90 },
> > - { 0x034e, 0x04 },
> > - { 0x034f, 0x48 },
> > { 0x0700, 0x00 },
> > { 0x0701, 0x10 },
> > };
> > @@ -366,21 +320,9 @@ static const struct imx355_reg mode_1936x1096_regs[] = {
> > static const struct imx355_reg mode_1924x1080_regs[] = {
> > { 0x0342, 0x0e },
> > { 0x0343, 0x58 },
> > - { 0x0344, 0x02 },
> > - { 0x0345, 0xa8 },
> > - { 0x0346, 0x02 },
> > - { 0x0347, 0xb4 },
> > - { 0x0348, 0x0a },
> > - { 0x0349, 0x2b },
> > - { 0x034a, 0x06 },
> > - { 0x034b, 0xeb },
> > { 0x0900, 0x00 },
> > { 0x0901, 0x11 },
> > { 0x0902, 0x00 },
> > - { 0x034c, 0x07 },
> > - { 0x034d, 0x84 },
> > - { 0x034e, 0x04 },
> > - { 0x034f, 0x38 },
> > { 0x0700, 0x00 },
> > { 0x0701, 0x10 },
> > };
> > @@ -388,21 +330,9 @@ static const struct imx355_reg mode_1924x1080_regs[] = {
> > static const struct imx355_reg mode_1920x1080_regs[] = {
> > { 0x0342, 0x0e },
> > { 0x0343, 0x58 },
> > - { 0x0344, 0x02 },
> > - { 0x0345, 0xa8 },
> > - { 0x0346, 0x02 },
> > - { 0x0347, 0xb4 },
> > - { 0x0348, 0x0a },
> > - { 0x0349, 0x27 },
> > - { 0x034a, 0x06 },
> > - { 0x034b, 0xeb },
> > { 0x0900, 0x00 },
> > { 0x0901, 0x11 },
> > { 0x0902, 0x00 },
> > - { 0x034c, 0x07 },
> > - { 0x034d, 0x80 },
> > - { 0x034e, 0x04 },
> > - { 0x034f, 0x38 },
> > { 0x0700, 0x00 },
> > { 0x0701, 0x10 },
> > };
> > @@ -410,21 +340,9 @@ static const struct imx355_reg mode_1920x1080_regs[] = {
> > static const struct imx355_reg mode_1640x1232_regs[] = {
> > { 0x0342, 0x07 },
> > { 0x0343, 0x2c },
> > - { 0x0344, 0x00 },
> > - { 0x0345, 0x00 },
> > - { 0x0346, 0x00 },
> > - { 0x0347, 0x00 },
> > - { 0x0348, 0x0c },
> > - { 0x0349, 0xcf },
> > - { 0x034a, 0x09 },
> > - { 0x034b, 0x9f },
> > { 0x0900, 0x01 },
> > { 0x0901, 0x22 },
> > { 0x0902, 0x00 },
> > - { 0x034c, 0x06 },
> > - { 0x034d, 0x68 },
> > - { 0x034e, 0x04 },
> > - { 0x034f, 0xd0 },
> > { 0x0700, 0x00 },
> > { 0x0701, 0x10 },
> > };
> > @@ -432,21 +350,9 @@ static const struct imx355_reg mode_1640x1232_regs[] = {
> > static const struct imx355_reg mode_1640x922_regs[] = {
> > { 0x0342, 0x07 },
> > { 0x0343, 0x2c },
> > - { 0x0344, 0x00 },
> > - { 0x0345, 0x00 },
> > - { 0x0346, 0x01 },
> > - { 0x0347, 0x30 },
> > - { 0x0348, 0x0c },
> > - { 0x0349, 0xcf },
> > - { 0x034a, 0x08 },
> > - { 0x034b, 0x63 },
> > { 0x0900, 0x01 },
> > { 0x0901, 0x22 },
> > { 0x0902, 0x00 },
> > - { 0x034c, 0x06 },
> > - { 0x034d, 0x68 },
> > - { 0x034e, 0x03 },
> > - { 0x034f, 0x9a },
> > { 0x0700, 0x00 },
> > { 0x0701, 0x10 },
> > };
> > @@ -454,21 +360,9 @@ static const struct imx355_reg mode_1640x922_regs[] = {
> > static const struct imx355_reg mode_1300x736_regs[] = {
> > { 0x0342, 0x07 },
> > { 0x0343, 0x2c },
> > - { 0x0344, 0x01 },
> > - { 0x0345, 0x58 },
> > - { 0x0346, 0x01 },
> > - { 0x0347, 0xf0 },
> > - { 0x0348, 0x0b },
> > - { 0x0349, 0x7f },
> > - { 0x034a, 0x07 },
> > - { 0x034b, 0xaf },
> > { 0x0900, 0x01 },
> > { 0x0901, 0x22 },
> > { 0x0902, 0x00 },
> > - { 0x034c, 0x05 },
> > - { 0x034d, 0x14 },
> > - { 0x034e, 0x02 },
> > - { 0x034f, 0xe0 },
> > { 0x0700, 0x00 },
> > { 0x0701, 0x10 },
> > };
> > @@ -476,21 +370,9 @@ static const struct imx355_reg mode_1300x736_regs[] = {
> > static const struct imx355_reg mode_1296x736_regs[] = {
> > { 0x0342, 0x07 },
> > { 0x0343, 0x2c },
> > - { 0x0344, 0x01 },
> > - { 0x0345, 0x58 },
> > - { 0x0346, 0x01 },
> > - { 0x0347, 0xf0 },
> > - { 0x0348, 0x0b },
> > - { 0x0349, 0x77 },
> > - { 0x034a, 0x07 },
> > - { 0x034b, 0xaf },
> > { 0x0900, 0x01 },
> > { 0x0901, 0x22 },
> > { 0x0902, 0x00 },
> > - { 0x034c, 0x05 },
> > - { 0x034d, 0x10 },
> > - { 0x034e, 0x02 },
> > - { 0x034f, 0xe0 },
> > { 0x0700, 0x00 },
> > { 0x0701, 0x10 },
> > };
> > @@ -498,21 +380,9 @@ static const struct imx355_reg mode_1296x736_regs[] = {
> > static const struct imx355_reg mode_1284x720_regs[] = {
> > { 0x0342, 0x07 },
> > { 0x0343, 0x2c },
> > - { 0x0344, 0x01 },
> > - { 0x0345, 0x68 },
> > - { 0x0346, 0x02 },
> > - { 0x0347, 0x00 },
> > - { 0x0348, 0x0b },
> > - { 0x0349, 0x6f },
> > - { 0x034a, 0x07 },
> > - { 0x034b, 0x9f },
> > { 0x0900, 0x01 },
> > { 0x0901, 0x22 },
> > { 0x0902, 0x00 },
> > - { 0x034c, 0x05 },
> > - { 0x034d, 0x04 },
> > - { 0x034e, 0x02 },
> > - { 0x034f, 0xd0 },
> > { 0x0700, 0x00 },
> > { 0x0701, 0x10 },
> > };
> > @@ -520,21 +390,9 @@ static const struct imx355_reg mode_1284x720_regs[] = {
> > static const struct imx355_reg mode_1280x720_regs[] = {
> > { 0x0342, 0x07 },
> > { 0x0343, 0x2c },
> > - { 0x0344, 0x01 },
> > - { 0x0345, 0x68 },
> > - { 0x0346, 0x02 },
> > - { 0x0347, 0x00 },
> > - { 0x0348, 0x0b },
> > - { 0x0349, 0x67 },
> > - { 0x034a, 0x07 },
> > - { 0x034b, 0x9f },
> > { 0x0900, 0x01 },
> > { 0x0901, 0x22 },
> > { 0x0902, 0x00 },
> > - { 0x034c, 0x05 },
> > - { 0x034d, 0x00 },
> > - { 0x034e, 0x02 },
> > - { 0x034f, 0xd0 },
> > { 0x0700, 0x00 },
> > { 0x0701, 0x10 },
> > };
> > @@ -542,21 +400,9 @@ static const struct imx355_reg mode_1280x720_regs[] = {
> > static const struct imx355_reg mode_820x616_regs[] = {
> > { 0x0342, 0x0e },
> > { 0x0343, 0x58 },
> > - { 0x0344, 0x00 },
> > - { 0x0345, 0x00 },
> > - { 0x0346, 0x00 },
> > - { 0x0347, 0x00 },
> > - { 0x0348, 0x0c },
> > - { 0x0349, 0xcf },
> > - { 0x034a, 0x09 },
> > - { 0x034b, 0x9f },
> > { 0x0900, 0x01 },
> > { 0x0901, 0x44 },
> > { 0x0902, 0x00 },
> > - { 0x034c, 0x03 },
> > - { 0x034d, 0x34 },
> > - { 0x034e, 0x02 },
> > - { 0x034f, 0x68 },
> > { 0x0700, 0x02 },
> > { 0x0701, 0x78 },
> > };
> > @@ -590,6 +436,12 @@ static const struct imx355_mode supported_modes[] = {
> > .num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
> > .regs = mode_3280x2464_regs,
> > },
> > + .x_add_start = 0x0000,
> > + .y_add_start = 0x0000,
> > + .x_add_end = 0x0ccf,
> > + .y_add_end = 0x099f,
> > + .x_out_size = 0x0cd0,
> > + .y_out_size = 0x09a0,
> > },
> > {
> > .width = 3268,
> > @@ -602,6 +454,12 @@ static const struct imx355_mode supported_modes[] = {
> > .num_of_regs = ARRAY_SIZE(mode_3268x2448_regs),
> > .regs = mode_3268x2448_regs,
> > },
> > + .x_add_start = 0x0008,
> > + .y_add_start = 0x0008,
> > + .x_add_end = 0x0ccb,
> > + .y_add_end = 0x997,
> > + .x_out_size = 0x0cc4,
> > + .y_out_size = 0x0990,
> > },
> > {
> > .width = 3264,
> > @@ -614,6 +472,12 @@ static const struct imx355_mode supported_modes[] = {
> > .num_of_regs = ARRAY_SIZE(mode_3264x2448_regs),
> > .regs = mode_3264x2448_regs,
> > },
> > + .x_add_start = 0x0008,
> > + .y_add_start = 0x0008,
> > + .x_add_end = 0x0cc7,
> > + .y_add_end = 0x0997,
> > + .x_out_size = 0x0cc0,
> > + .y_out_size = 0x0990,
> > },
> > {
> > .width = 1940,
> > @@ -626,6 +490,12 @@ static const struct imx355_mode supported_modes[] = {
> > .num_of_regs = ARRAY_SIZE(mode_1940x1096_regs),
> > .regs = mode_1940x1096_regs,
> > },
> > + .x_add_start = 0x02a0,
> > + .y_add_start = 0x02ac,
> > + .x_add_end = 0x0a33,
> > + .y_add_end = 0x06f3,
> > + .x_out_size = 0x0794,
> > + .y_out_size = 0x0448,
> > },
> > {
> > .width = 1936,
> > @@ -638,6 +508,12 @@ static const struct imx355_mode supported_modes[] = {
> > .num_of_regs = ARRAY_SIZE(mode_1936x1096_regs),
> > .regs = mode_1936x1096_regs,
> > },
> > + .x_add_start = 0x02a0,
> > + .y_add_start = 0x02ac,
> > + .x_add_end = 0x0a2f,
> > + .y_add_end = 0x06f3,
> > + .x_out_size = 0x0790,
> > + .y_out_size = 0x0448,
> > },
> > {
> > .width = 1924,
> > @@ -650,6 +526,12 @@ static const struct imx355_mode supported_modes[] = {
> > .num_of_regs = ARRAY_SIZE(mode_1924x1080_regs),
> > .regs = mode_1924x1080_regs,
> > },
> > + .x_add_start = 0x02a8,
> > + .y_add_start = 0x02b4,
> > + .x_add_end = 0x0a2b,
> > + .y_add_end = 0x06eb,
> > + .x_out_size = 0x0784,
> > + .y_out_size = 0x0438,
> > },
> > {
> > .width = 1920,
> > @@ -662,6 +544,12 @@ static const struct imx355_mode supported_modes[] = {
> > .num_of_regs = ARRAY_SIZE(mode_1920x1080_regs),
> > .regs = mode_1920x1080_regs,
> > },
> > + .x_add_start = 0x02a8,
> > + .y_add_start = 0x02b4,
> > + .x_add_end = 0x0a27,
> > + .y_add_end = 0x06eb,
> > + .x_out_size = 0x0780,
> > + .y_out_size = 0x0438,
> > },
> > {
> > .width = 1640,
> > @@ -674,6 +562,12 @@ static const struct imx355_mode supported_modes[] = {
> > .num_of_regs = ARRAY_SIZE(mode_1640x1232_regs),
> > .regs = mode_1640x1232_regs,
> > },
> > + .x_add_start = 0x0000,
> > + .y_add_start = 0x0000,
> > + .x_add_end = 0x0ccf,
> > + .y_add_end = 0x099f,
> > + .x_out_size = 0x0668,
> > + .y_out_size = 0x04d0,
> > },
> > {
> > .width = 1640,
> > @@ -686,6 +580,12 @@ static const struct imx355_mode supported_modes[] = {
> > .num_of_regs = ARRAY_SIZE(mode_1640x922_regs),
> > .regs = mode_1640x922_regs,
> > },
> > + .x_add_start = 0x0000,
> > + .y_add_start = 0x0130,
> > + .x_add_end = 0x0ccf,
> > + .y_add_end = 0x0863,
> > + .x_out_size = 0x0668,
> > + .y_out_size = 0x039a,
> > },
> > {
> > .width = 1300,
> > @@ -698,6 +598,12 @@ static const struct imx355_mode supported_modes[] = {
> > .num_of_regs = ARRAY_SIZE(mode_1300x736_regs),
> > .regs = mode_1300x736_regs,
> > },
> > + .x_add_start = 0x0158,
> > + .y_add_start = 0x01f0,
> > + .x_add_end = 0x0b7f,
> > + .y_add_end = 0x07af,
> > + .x_out_size = 0x0514,
> > + .y_out_size = 0x02e0,
> > },
> > {
> > .width = 1296,
> > @@ -710,6 +616,12 @@ static const struct imx355_mode supported_modes[] = {
> > .num_of_regs = ARRAY_SIZE(mode_1296x736_regs),
> > .regs = mode_1296x736_regs,
> > },
> > + .x_add_start = 0x0158,
> > + .y_add_start = 0x01f0,
> > + .x_add_end = 0x0b77,
> > + .y_add_end = 0x07af,
> > + .x_out_size = 0x0510,
> > + .y_out_size = 0x02e0,
> > },
> > {
> > .width = 1284,
> > @@ -722,6 +634,12 @@ static const struct imx355_mode supported_modes[] = {
> > .num_of_regs = ARRAY_SIZE(mode_1284x720_regs),
> > .regs = mode_1284x720_regs,
> > },
> > + .x_add_start = 0x0168,
> > + .y_add_start = 0x0200,
> > + .x_add_end = 0x0b6f,
> > + .y_add_end = 0x079f,
> > + .x_out_size = 0x0504,
> > + .y_out_size = 0x02d0,
> > },
> > {
> > .width = 1280,
> > @@ -734,6 +652,12 @@ static const struct imx355_mode supported_modes[] = {
> > .num_of_regs = ARRAY_SIZE(mode_1280x720_regs),
> > .regs = mode_1280x720_regs,
> > },
> > + .x_add_start = 0x0168,
> > + .y_add_start = 0x0200,
> > + .x_add_end = 0x0b67,
> > + .y_add_end = 0x079f,
> > + .x_out_size = 0x0500,
> > + .y_out_size = 0x02d0,
> > },
> > {
> > .width = 820,
> > @@ -746,6 +670,12 @@ static const struct imx355_mode supported_modes[] = {
> > .num_of_regs = ARRAY_SIZE(mode_820x616_regs),
> > .regs = mode_820x616_regs,
> > },
> > + .x_add_start = 0x0000,
> > + .y_add_start = 0x0000,
> > + .x_add_end = 0x0ccf,
> > + .y_add_end = 0x099f,
> > + .x_out_size = 0x0334,
> > + .y_out_size = 0x0268,
> > },
> > };
> >
> > @@ -1076,6 +1006,7 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
> > static int imx355_start_streaming(struct imx355 *imx355)
> > {
> > const struct imx355_reg_list *reg_list;
> > + const struct imx355_mode *mode;
> > int ret;
> >
> > /* Global Setting */
> > @@ -1087,13 +1018,40 @@ static int imx355_start_streaming(struct imx355 *imx355)
> > }
> >
> > /* Apply default values of current mode */
> > - reg_list = &imx355->cur_mode->reg_list;
> > + mode = imx355->cur_mode;
> > + reg_list = &mode->reg_list;
> > ret = imx355_write_regs(imx355, reg_list->regs, reg_list->num_of_regs);
> > if (ret) {
> > dev_err(imx355->dev, "failed to set mode");
> > return ret;
> > }
> >
> > + /* Set readout crop and size registers */
> > + ret = imx355_write_reg(imx355, IMX355_REG_X_ADD_START, 2,
> > + mode->x_add_start);
> > + if (ret)
> > + return ret;
> > + ret = imx355_write_reg(imx355, IMX355_REG_Y_ADD_START, 2,
> > + mode->y_add_start);
> > + if (ret)
> > + return ret;
> > + ret = imx355_write_reg(imx355, IMX355_REG_X_ADD_END, 2,
> > + mode->x_add_end);
> > + if (ret)
> > + return ret;
> > + ret = imx355_write_reg(imx355, IMX355_REG_Y_ADD_END, 2,
> > + mode->y_add_end);
> > + if (ret)
> > + return ret;
> > + ret = imx355_write_reg(imx355, IMX355_REG_X_OUT_SIZE, 2,
> > + mode->x_out_size);
> > + if (ret)
> > + return ret;
> > + ret = imx355_write_reg(imx355, IMX355_REG_Y_OUT_SIZE, 2,
> > + mode->y_out_size);
> > + if (ret)
> > + return ret;
> > +
> > /* Set PLL registers for the external clock frequency */
> > ret = imx355_write_reg(imx355, IMX355_REG_EXTCLK_FREQ, 2,
> > imx355->clk_params->extclk_freq);
> >
> > --
> > 2.34.1
> >
> >
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH 04/13] media: imx355: Remove the duplication between width/height and x/y_out_size
2026-05-06 18:23 [PATCH 00/13] media/imx355: General code cleanups, and adding support for 2 lane operation Dave Stevenson
` (2 preceding siblings ...)
2026-05-06 18:23 ` [PATCH 03/13] media: imx355: Programmatically set the crop parameters for each mode Dave Stevenson
@ 2026-05-06 18:23 ` Dave Stevenson
2026-05-06 18:23 ` [PATCH 05/13] media: imx355: Set register LINE_LENGTH_PCK programmatically Dave Stevenson
` (8 subsequent siblings)
12 siblings, 0 replies; 29+ messages in thread
From: Dave Stevenson @ 2026-05-06 18:23 UTC (permalink / raw)
To: Tianshu Qiu, Sakari Ailus, Mauro Carvalho Chehab
Cc: linux-media, linux-kernel, David Heidelberg,
20260414-imx355-24mhz-v1-1-9ae77bc6e7ec, Dave Stevenson
The register settings x_out_size and y_out_size are just width and
height, so drop the values.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/media/i2c/imx355.c | 34 ++--------------------------------
1 file changed, 2 insertions(+), 32 deletions(-)
diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
index 6179fe74c897..589bad6c58e4 100644
--- a/drivers/media/i2c/imx355.c
+++ b/drivers/media/i2c/imx355.c
@@ -114,8 +114,6 @@ struct imx355_mode {
u16 y_add_start;
u16 x_add_end;
u16 y_add_end;
- u16 x_out_size;
- u16 y_out_size;
};
struct imx355_clk_params {
@@ -440,8 +438,6 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x0000,
.x_add_end = 0x0ccf,
.y_add_end = 0x099f,
- .x_out_size = 0x0cd0,
- .y_out_size = 0x09a0,
},
{
.width = 3268,
@@ -458,8 +454,6 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x0008,
.x_add_end = 0x0ccb,
.y_add_end = 0x997,
- .x_out_size = 0x0cc4,
- .y_out_size = 0x0990,
},
{
.width = 3264,
@@ -476,8 +470,6 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x0008,
.x_add_end = 0x0cc7,
.y_add_end = 0x0997,
- .x_out_size = 0x0cc0,
- .y_out_size = 0x0990,
},
{
.width = 1940,
@@ -494,8 +486,6 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x02ac,
.x_add_end = 0x0a33,
.y_add_end = 0x06f3,
- .x_out_size = 0x0794,
- .y_out_size = 0x0448,
},
{
.width = 1936,
@@ -512,8 +502,6 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x02ac,
.x_add_end = 0x0a2f,
.y_add_end = 0x06f3,
- .x_out_size = 0x0790,
- .y_out_size = 0x0448,
},
{
.width = 1924,
@@ -530,8 +518,6 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x02b4,
.x_add_end = 0x0a2b,
.y_add_end = 0x06eb,
- .x_out_size = 0x0784,
- .y_out_size = 0x0438,
},
{
.width = 1920,
@@ -548,8 +534,6 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x02b4,
.x_add_end = 0x0a27,
.y_add_end = 0x06eb,
- .x_out_size = 0x0780,
- .y_out_size = 0x0438,
},
{
.width = 1640,
@@ -566,8 +550,6 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x0000,
.x_add_end = 0x0ccf,
.y_add_end = 0x099f,
- .x_out_size = 0x0668,
- .y_out_size = 0x04d0,
},
{
.width = 1640,
@@ -584,8 +566,6 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x0130,
.x_add_end = 0x0ccf,
.y_add_end = 0x0863,
- .x_out_size = 0x0668,
- .y_out_size = 0x039a,
},
{
.width = 1300,
@@ -602,8 +582,6 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x01f0,
.x_add_end = 0x0b7f,
.y_add_end = 0x07af,
- .x_out_size = 0x0514,
- .y_out_size = 0x02e0,
},
{
.width = 1296,
@@ -620,8 +598,6 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x01f0,
.x_add_end = 0x0b77,
.y_add_end = 0x07af,
- .x_out_size = 0x0510,
- .y_out_size = 0x02e0,
},
{
.width = 1284,
@@ -638,8 +614,6 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x0200,
.x_add_end = 0x0b6f,
.y_add_end = 0x079f,
- .x_out_size = 0x0504,
- .y_out_size = 0x02d0,
},
{
.width = 1280,
@@ -656,8 +630,6 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x0200,
.x_add_end = 0x0b67,
.y_add_end = 0x079f,
- .x_out_size = 0x0500,
- .y_out_size = 0x02d0,
},
{
.width = 820,
@@ -674,8 +646,6 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x0000,
.x_add_end = 0x0ccf,
.y_add_end = 0x099f,
- .x_out_size = 0x0334,
- .y_out_size = 0x0268,
},
};
@@ -1044,11 +1014,11 @@ static int imx355_start_streaming(struct imx355 *imx355)
if (ret)
return ret;
ret = imx355_write_reg(imx355, IMX355_REG_X_OUT_SIZE, 2,
- mode->x_out_size);
+ mode->width);
if (ret)
return ret;
ret = imx355_write_reg(imx355, IMX355_REG_Y_OUT_SIZE, 2,
- mode->y_out_size);
+ mode->height);
if (ret)
return ret;
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread* [PATCH 05/13] media: imx355: Set register LINE_LENGTH_PCK programmatically
2026-05-06 18:23 [PATCH 00/13] media/imx355: General code cleanups, and adding support for 2 lane operation Dave Stevenson
` (3 preceding siblings ...)
2026-05-06 18:23 ` [PATCH 04/13] media: imx355: Remove the duplication between width/height and x/y_out_size Dave Stevenson
@ 2026-05-06 18:23 ` Dave Stevenson
2026-05-07 14:09 ` Jacopo Mondi
2026-05-06 18:23 ` [PATCH 06/13] media: imx355: Set binning mode registers programmatically Dave Stevenson
` (7 subsequent siblings)
12 siblings, 1 reply; 29+ messages in thread
From: Dave Stevenson @ 2026-05-06 18:23 UTC (permalink / raw)
To: Tianshu Qiu, Sakari Ailus, Mauro Carvalho Chehab
Cc: linux-media, linux-kernel, David Heidelberg,
20260414-imx355-24mhz-v1-1-9ae77bc6e7ec, Dave Stevenson
The driver already has the LLP value stored in the mode structure,
but also had the same value set via register writes in the mode's
register list. Remove this duplication.
This can't be implemented via a s_ctrl handler for V4L2_CID_HBLANK
as __v4l2_ctrl_handler_setup doesn't call s_ctrl for read only
controls.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
---
drivers/media/i2c/imx355.c | 38 ++++++++++----------------------------
1 file changed, 10 insertions(+), 28 deletions(-)
diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
index 589bad6c58e4..56a82f37709e 100644
--- a/drivers/media/i2c/imx355.c
+++ b/drivers/media/i2c/imx355.c
@@ -34,6 +34,9 @@
#define IMX355_REG_FLL 0x0340
#define IMX355_FLL_MAX 0xffff
+#define IMX355_REG_LLP 0x0342
+#define IMX355_LLP_MAX 0xffff
+
#define IMX355_REG_X_ADD_START 0x0344
#define IMX355_REG_Y_ADD_START 0x0346
#define IMX355_REG_X_ADD_END 0x0348
@@ -266,8 +269,6 @@ static const struct imx355_reg_list imx355_global_setting = {
};
static const struct imx355_reg mode_3268x2448_regs[] = {
- { 0x0342, 0x0e },
- { 0x0343, 0x58 },
{ 0x0900, 0x00 },
{ 0x0901, 0x11 },
{ 0x0902, 0x00 },
@@ -276,8 +277,6 @@ static const struct imx355_reg mode_3268x2448_regs[] = {
};
static const struct imx355_reg mode_3264x2448_regs[] = {
- { 0x0342, 0x0e },
- { 0x0343, 0x58 },
{ 0x0900, 0x00 },
{ 0x0901, 0x11 },
{ 0x0902, 0x00 },
@@ -286,8 +285,6 @@ static const struct imx355_reg mode_3264x2448_regs[] = {
};
static const struct imx355_reg mode_3280x2464_regs[] = {
- { 0x0342, 0x0e },
- { 0x0343, 0x58 },
{ 0x0900, 0x00 },
{ 0x0901, 0x11 },
{ 0x0902, 0x00 },
@@ -296,8 +293,6 @@ static const struct imx355_reg mode_3280x2464_regs[] = {
};
static const struct imx355_reg mode_1940x1096_regs[] = {
- { 0x0342, 0x0e },
- { 0x0343, 0x58 },
{ 0x0900, 0x00 },
{ 0x0901, 0x11 },
{ 0x0902, 0x00 },
@@ -306,8 +301,6 @@ static const struct imx355_reg mode_1940x1096_regs[] = {
};
static const struct imx355_reg mode_1936x1096_regs[] = {
- { 0x0342, 0x0e },
- { 0x0343, 0x58 },
{ 0x0900, 0x00 },
{ 0x0901, 0x11 },
{ 0x0902, 0x00 },
@@ -316,8 +309,6 @@ static const struct imx355_reg mode_1936x1096_regs[] = {
};
static const struct imx355_reg mode_1924x1080_regs[] = {
- { 0x0342, 0x0e },
- { 0x0343, 0x58 },
{ 0x0900, 0x00 },
{ 0x0901, 0x11 },
{ 0x0902, 0x00 },
@@ -326,8 +317,6 @@ static const struct imx355_reg mode_1924x1080_regs[] = {
};
static const struct imx355_reg mode_1920x1080_regs[] = {
- { 0x0342, 0x0e },
- { 0x0343, 0x58 },
{ 0x0900, 0x00 },
{ 0x0901, 0x11 },
{ 0x0902, 0x00 },
@@ -336,8 +325,6 @@ static const struct imx355_reg mode_1920x1080_regs[] = {
};
static const struct imx355_reg mode_1640x1232_regs[] = {
- { 0x0342, 0x07 },
- { 0x0343, 0x2c },
{ 0x0900, 0x01 },
{ 0x0901, 0x22 },
{ 0x0902, 0x00 },
@@ -346,8 +333,6 @@ static const struct imx355_reg mode_1640x1232_regs[] = {
};
static const struct imx355_reg mode_1640x922_regs[] = {
- { 0x0342, 0x07 },
- { 0x0343, 0x2c },
{ 0x0900, 0x01 },
{ 0x0901, 0x22 },
{ 0x0902, 0x00 },
@@ -356,8 +341,6 @@ static const struct imx355_reg mode_1640x922_regs[] = {
};
static const struct imx355_reg mode_1300x736_regs[] = {
- { 0x0342, 0x07 },
- { 0x0343, 0x2c },
{ 0x0900, 0x01 },
{ 0x0901, 0x22 },
{ 0x0902, 0x00 },
@@ -366,8 +349,6 @@ static const struct imx355_reg mode_1300x736_regs[] = {
};
static const struct imx355_reg mode_1296x736_regs[] = {
- { 0x0342, 0x07 },
- { 0x0343, 0x2c },
{ 0x0900, 0x01 },
{ 0x0901, 0x22 },
{ 0x0902, 0x00 },
@@ -376,8 +357,6 @@ static const struct imx355_reg mode_1296x736_regs[] = {
};
static const struct imx355_reg mode_1284x720_regs[] = {
- { 0x0342, 0x07 },
- { 0x0343, 0x2c },
{ 0x0900, 0x01 },
{ 0x0901, 0x22 },
{ 0x0902, 0x00 },
@@ -386,8 +365,6 @@ static const struct imx355_reg mode_1284x720_regs[] = {
};
static const struct imx355_reg mode_1280x720_regs[] = {
- { 0x0342, 0x07 },
- { 0x0343, 0x2c },
{ 0x0900, 0x01 },
{ 0x0901, 0x22 },
{ 0x0902, 0x00 },
@@ -396,8 +373,6 @@ static const struct imx355_reg mode_1280x720_regs[] = {
};
static const struct imx355_reg mode_820x616_regs[] = {
- { 0x0342, 0x0e },
- { 0x0343, 0x58 },
{ 0x0900, 0x01 },
{ 0x0901, 0x44 },
{ 0x0902, 0x00 },
@@ -1041,6 +1016,13 @@ static int imx355_start_streaming(struct imx355 *imx355)
if (ret)
return ret;
+ /* set line length */
+ ret = imx355_write_reg(imx355, IMX355_REG_LLP,
+ imx355->hblank->val + imx355->cur_mode->width,
+ 2);
+ if (ret)
+ return ret;
+
/* Apply customized values from user */
ret = __v4l2_ctrl_handler_setup(imx355->sd.ctrl_handler);
if (ret)
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread* Re: [PATCH 05/13] media: imx355: Set register LINE_LENGTH_PCK programmatically
2026-05-06 18:23 ` [PATCH 05/13] media: imx355: Set register LINE_LENGTH_PCK programmatically Dave Stevenson
@ 2026-05-07 14:09 ` Jacopo Mondi
2026-05-07 15:18 ` Dave Stevenson
0 siblings, 1 reply; 29+ messages in thread
From: Jacopo Mondi @ 2026-05-07 14:09 UTC (permalink / raw)
To: Dave Stevenson
Cc: Tianshu Qiu, Sakari Ailus, Mauro Carvalho Chehab, linux-media,
linux-kernel, David Heidelberg,
20260414-imx355-24mhz-v1-1-9ae77bc6e7ec
Hi Dave
On Wed, May 06, 2026 at 07:23:43PM +0100, Dave Stevenson wrote:
> The driver already has the LLP value stored in the mode structure,
> but also had the same value set via register writes in the mode's
> register list. Remove this duplication.
Moving stuff from register data tables to modes is .. better for sure.
You know.. freely configurable etc etc
But this is an improvement, so...
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
>
> This can't be implemented via a s_ctrl handler for V4L2_CID_HBLANK
> as __v4l2_ctrl_handler_setup doesn't call s_ctrl for read only
> controls.
Kind of unrelated, but I wonder if imx355_set_ctrl() doesn't actually
get called for hblank but the error simply goes ignored. The real
solution here would be to initialize the hblank control with a NULL
control handler.
>
> Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
> ---
> ---
> drivers/media/i2c/imx355.c | 38 ++++++++++----------------------------
> 1 file changed, 10 insertions(+), 28 deletions(-)
>
> diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
> index 589bad6c58e4..56a82f37709e 100644
> --- a/drivers/media/i2c/imx355.c
> +++ b/drivers/media/i2c/imx355.c
> @@ -34,6 +34,9 @@
> #define IMX355_REG_FLL 0x0340
> #define IMX355_FLL_MAX 0xffff
>
> +#define IMX355_REG_LLP 0x0342
> +#define IMX355_LLP_MAX 0xffff
> +
> #define IMX355_REG_X_ADD_START 0x0344
> #define IMX355_REG_Y_ADD_START 0x0346
> #define IMX355_REG_X_ADD_END 0x0348
> @@ -266,8 +269,6 @@ static const struct imx355_reg_list imx355_global_setting = {
> };
>
> static const struct imx355_reg mode_3268x2448_regs[] = {
> - { 0x0342, 0x0e },
> - { 0x0343, 0x58 },
> { 0x0900, 0x00 },
> { 0x0901, 0x11 },
> { 0x0902, 0x00 },
> @@ -276,8 +277,6 @@ static const struct imx355_reg mode_3268x2448_regs[] = {
> };
>
> static const struct imx355_reg mode_3264x2448_regs[] = {
> - { 0x0342, 0x0e },
> - { 0x0343, 0x58 },
> { 0x0900, 0x00 },
> { 0x0901, 0x11 },
> { 0x0902, 0x00 },
> @@ -286,8 +285,6 @@ static const struct imx355_reg mode_3264x2448_regs[] = {
> };
>
> static const struct imx355_reg mode_3280x2464_regs[] = {
> - { 0x0342, 0x0e },
> - { 0x0343, 0x58 },
> { 0x0900, 0x00 },
> { 0x0901, 0x11 },
> { 0x0902, 0x00 },
> @@ -296,8 +293,6 @@ static const struct imx355_reg mode_3280x2464_regs[] = {
> };
>
> static const struct imx355_reg mode_1940x1096_regs[] = {
> - { 0x0342, 0x0e },
> - { 0x0343, 0x58 },
> { 0x0900, 0x00 },
> { 0x0901, 0x11 },
> { 0x0902, 0x00 },
> @@ -306,8 +301,6 @@ static const struct imx355_reg mode_1940x1096_regs[] = {
> };
>
> static const struct imx355_reg mode_1936x1096_regs[] = {
> - { 0x0342, 0x0e },
> - { 0x0343, 0x58 },
> { 0x0900, 0x00 },
> { 0x0901, 0x11 },
> { 0x0902, 0x00 },
> @@ -316,8 +309,6 @@ static const struct imx355_reg mode_1936x1096_regs[] = {
> };
>
> static const struct imx355_reg mode_1924x1080_regs[] = {
> - { 0x0342, 0x0e },
> - { 0x0343, 0x58 },
> { 0x0900, 0x00 },
> { 0x0901, 0x11 },
> { 0x0902, 0x00 },
> @@ -326,8 +317,6 @@ static const struct imx355_reg mode_1924x1080_regs[] = {
> };
>
> static const struct imx355_reg mode_1920x1080_regs[] = {
> - { 0x0342, 0x0e },
> - { 0x0343, 0x58 },
> { 0x0900, 0x00 },
> { 0x0901, 0x11 },
> { 0x0902, 0x00 },
> @@ -336,8 +325,6 @@ static const struct imx355_reg mode_1920x1080_regs[] = {
> };
>
> static const struct imx355_reg mode_1640x1232_regs[] = {
> - { 0x0342, 0x07 },
> - { 0x0343, 0x2c },
> { 0x0900, 0x01 },
> { 0x0901, 0x22 },
> { 0x0902, 0x00 },
> @@ -346,8 +333,6 @@ static const struct imx355_reg mode_1640x1232_regs[] = {
> };
>
> static const struct imx355_reg mode_1640x922_regs[] = {
> - { 0x0342, 0x07 },
> - { 0x0343, 0x2c },
> { 0x0900, 0x01 },
> { 0x0901, 0x22 },
> { 0x0902, 0x00 },
> @@ -356,8 +341,6 @@ static const struct imx355_reg mode_1640x922_regs[] = {
> };
>
> static const struct imx355_reg mode_1300x736_regs[] = {
> - { 0x0342, 0x07 },
> - { 0x0343, 0x2c },
> { 0x0900, 0x01 },
> { 0x0901, 0x22 },
> { 0x0902, 0x00 },
> @@ -366,8 +349,6 @@ static const struct imx355_reg mode_1300x736_regs[] = {
> };
>
> static const struct imx355_reg mode_1296x736_regs[] = {
> - { 0x0342, 0x07 },
> - { 0x0343, 0x2c },
> { 0x0900, 0x01 },
> { 0x0901, 0x22 },
> { 0x0902, 0x00 },
> @@ -376,8 +357,6 @@ static const struct imx355_reg mode_1296x736_regs[] = {
> };
>
> static const struct imx355_reg mode_1284x720_regs[] = {
> - { 0x0342, 0x07 },
> - { 0x0343, 0x2c },
> { 0x0900, 0x01 },
> { 0x0901, 0x22 },
> { 0x0902, 0x00 },
> @@ -386,8 +365,6 @@ static const struct imx355_reg mode_1284x720_regs[] = {
> };
>
> static const struct imx355_reg mode_1280x720_regs[] = {
> - { 0x0342, 0x07 },
> - { 0x0343, 0x2c },
> { 0x0900, 0x01 },
> { 0x0901, 0x22 },
> { 0x0902, 0x00 },
> @@ -396,8 +373,6 @@ static const struct imx355_reg mode_1280x720_regs[] = {
> };
>
> static const struct imx355_reg mode_820x616_regs[] = {
> - { 0x0342, 0x0e },
> - { 0x0343, 0x58 },
> { 0x0900, 0x01 },
> { 0x0901, 0x44 },
> { 0x0902, 0x00 },
> @@ -1041,6 +1016,13 @@ static int imx355_start_streaming(struct imx355 *imx355)
> if (ret)
> return ret;
>
> + /* set line length */
> + ret = imx355_write_reg(imx355, IMX355_REG_LLP,
> + imx355->hblank->val + imx355->cur_mode->width,
> + 2);
> + if (ret)
> + return ret;
> +
> /* Apply customized values from user */
> ret = __v4l2_ctrl_handler_setup(imx355->sd.ctrl_handler);
> if (ret)
>
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 29+ messages in thread* Re: [PATCH 05/13] media: imx355: Set register LINE_LENGTH_PCK programmatically
2026-05-07 14:09 ` Jacopo Mondi
@ 2026-05-07 15:18 ` Dave Stevenson
0 siblings, 0 replies; 29+ messages in thread
From: Dave Stevenson @ 2026-05-07 15:18 UTC (permalink / raw)
To: Jacopo Mondi
Cc: Tianshu Qiu, Sakari Ailus, Mauro Carvalho Chehab, linux-media,
linux-kernel, David Heidelberg
Hi Jacopo
On Thu, 7 May 2026 at 15:09, Jacopo Mondi <jacopo.mondi@ideasonboard.com> wrote:
>
> Hi Dave
>
> On Wed, May 06, 2026 at 07:23:43PM +0100, Dave Stevenson wrote:
> > The driver already has the LLP value stored in the mode structure,
> > but also had the same value set via register writes in the mode's
> > register list. Remove this duplication.
>
> Moving stuff from register data tables to modes is .. better for sure.
> You know.. freely configurable etc etc
> But this is an improvement, so...
AFAIK there is currently no accepted way to convert a driver from
having a load of defined modes to freely configurable.
This driver already has 14 modes advertised, so how do you retain
backwards compatibility with selecting those modes via set_fmt whilst
also allowing freely configurable cropping? AIUI set_fmt is not
allowed to update the value returned from get_selection. That means
we're stuck with these modes.
I also don't currently have a datasheet for this sensor, so I don't
know what restrictions are documented with respect to cropping on this
sensor.
> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
>
> >
> > This can't be implemented via a s_ctrl handler for V4L2_CID_HBLANK
> > as __v4l2_ctrl_handler_setup doesn't call s_ctrl for read only
> > controls.
>
> Kind of unrelated, but I wonder if imx355_set_ctrl() doesn't actually
> get called for hblank but the error simply goes ignored. The real
> solution here would be to initialize the hblank control with a NULL
> control handler.
This was partly a comment for future me as well as reviewers. I'd
expected to be able to handle it in s_ctrl and then found it didn't
work.
I believe you are right that the
__v4l2_ctrl_modify_range(imx355->hblank....) call in
imx355_set_pad_format will result in s_ctrl being called for
V4L2_CID_HBLANK, but the return value isn't checked. When min, max,
and def are all the same, it isn't going to fail. Using a NULL control
handler would tidy that up though.
Dave
> >
> > Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
> > ---
> > ---
> > drivers/media/i2c/imx355.c | 38 ++++++++++----------------------------
> > 1 file changed, 10 insertions(+), 28 deletions(-)
> >
> > diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
> > index 589bad6c58e4..56a82f37709e 100644
> > --- a/drivers/media/i2c/imx355.c
> > +++ b/drivers/media/i2c/imx355.c
> > @@ -34,6 +34,9 @@
> > #define IMX355_REG_FLL 0x0340
> > #define IMX355_FLL_MAX 0xffff
> >
> > +#define IMX355_REG_LLP 0x0342
> > +#define IMX355_LLP_MAX 0xffff
> > +
> > #define IMX355_REG_X_ADD_START 0x0344
> > #define IMX355_REG_Y_ADD_START 0x0346
> > #define IMX355_REG_X_ADD_END 0x0348
> > @@ -266,8 +269,6 @@ static const struct imx355_reg_list imx355_global_setting = {
> > };
> >
> > static const struct imx355_reg mode_3268x2448_regs[] = {
> > - { 0x0342, 0x0e },
> > - { 0x0343, 0x58 },
> > { 0x0900, 0x00 },
> > { 0x0901, 0x11 },
> > { 0x0902, 0x00 },
> > @@ -276,8 +277,6 @@ static const struct imx355_reg mode_3268x2448_regs[] = {
> > };
> >
> > static const struct imx355_reg mode_3264x2448_regs[] = {
> > - { 0x0342, 0x0e },
> > - { 0x0343, 0x58 },
> > { 0x0900, 0x00 },
> > { 0x0901, 0x11 },
> > { 0x0902, 0x00 },
> > @@ -286,8 +285,6 @@ static const struct imx355_reg mode_3264x2448_regs[] = {
> > };
> >
> > static const struct imx355_reg mode_3280x2464_regs[] = {
> > - { 0x0342, 0x0e },
> > - { 0x0343, 0x58 },
> > { 0x0900, 0x00 },
> > { 0x0901, 0x11 },
> > { 0x0902, 0x00 },
> > @@ -296,8 +293,6 @@ static const struct imx355_reg mode_3280x2464_regs[] = {
> > };
> >
> > static const struct imx355_reg mode_1940x1096_regs[] = {
> > - { 0x0342, 0x0e },
> > - { 0x0343, 0x58 },
> > { 0x0900, 0x00 },
> > { 0x0901, 0x11 },
> > { 0x0902, 0x00 },
> > @@ -306,8 +301,6 @@ static const struct imx355_reg mode_1940x1096_regs[] = {
> > };
> >
> > static const struct imx355_reg mode_1936x1096_regs[] = {
> > - { 0x0342, 0x0e },
> > - { 0x0343, 0x58 },
> > { 0x0900, 0x00 },
> > { 0x0901, 0x11 },
> > { 0x0902, 0x00 },
> > @@ -316,8 +309,6 @@ static const struct imx355_reg mode_1936x1096_regs[] = {
> > };
> >
> > static const struct imx355_reg mode_1924x1080_regs[] = {
> > - { 0x0342, 0x0e },
> > - { 0x0343, 0x58 },
> > { 0x0900, 0x00 },
> > { 0x0901, 0x11 },
> > { 0x0902, 0x00 },
> > @@ -326,8 +317,6 @@ static const struct imx355_reg mode_1924x1080_regs[] = {
> > };
> >
> > static const struct imx355_reg mode_1920x1080_regs[] = {
> > - { 0x0342, 0x0e },
> > - { 0x0343, 0x58 },
> > { 0x0900, 0x00 },
> > { 0x0901, 0x11 },
> > { 0x0902, 0x00 },
> > @@ -336,8 +325,6 @@ static const struct imx355_reg mode_1920x1080_regs[] = {
> > };
> >
> > static const struct imx355_reg mode_1640x1232_regs[] = {
> > - { 0x0342, 0x07 },
> > - { 0x0343, 0x2c },
> > { 0x0900, 0x01 },
> > { 0x0901, 0x22 },
> > { 0x0902, 0x00 },
> > @@ -346,8 +333,6 @@ static const struct imx355_reg mode_1640x1232_regs[] = {
> > };
> >
> > static const struct imx355_reg mode_1640x922_regs[] = {
> > - { 0x0342, 0x07 },
> > - { 0x0343, 0x2c },
> > { 0x0900, 0x01 },
> > { 0x0901, 0x22 },
> > { 0x0902, 0x00 },
> > @@ -356,8 +341,6 @@ static const struct imx355_reg mode_1640x922_regs[] = {
> > };
> >
> > static const struct imx355_reg mode_1300x736_regs[] = {
> > - { 0x0342, 0x07 },
> > - { 0x0343, 0x2c },
> > { 0x0900, 0x01 },
> > { 0x0901, 0x22 },
> > { 0x0902, 0x00 },
> > @@ -366,8 +349,6 @@ static const struct imx355_reg mode_1300x736_regs[] = {
> > };
> >
> > static const struct imx355_reg mode_1296x736_regs[] = {
> > - { 0x0342, 0x07 },
> > - { 0x0343, 0x2c },
> > { 0x0900, 0x01 },
> > { 0x0901, 0x22 },
> > { 0x0902, 0x00 },
> > @@ -376,8 +357,6 @@ static const struct imx355_reg mode_1296x736_regs[] = {
> > };
> >
> > static const struct imx355_reg mode_1284x720_regs[] = {
> > - { 0x0342, 0x07 },
> > - { 0x0343, 0x2c },
> > { 0x0900, 0x01 },
> > { 0x0901, 0x22 },
> > { 0x0902, 0x00 },
> > @@ -386,8 +365,6 @@ static const struct imx355_reg mode_1284x720_regs[] = {
> > };
> >
> > static const struct imx355_reg mode_1280x720_regs[] = {
> > - { 0x0342, 0x07 },
> > - { 0x0343, 0x2c },
> > { 0x0900, 0x01 },
> > { 0x0901, 0x22 },
> > { 0x0902, 0x00 },
> > @@ -396,8 +373,6 @@ static const struct imx355_reg mode_1280x720_regs[] = {
> > };
> >
> > static const struct imx355_reg mode_820x616_regs[] = {
> > - { 0x0342, 0x0e },
> > - { 0x0343, 0x58 },
> > { 0x0900, 0x01 },
> > { 0x0901, 0x44 },
> > { 0x0902, 0x00 },
> > @@ -1041,6 +1016,13 @@ static int imx355_start_streaming(struct imx355 *imx355)
> > if (ret)
> > return ret;
> >
> > + /* set line length */
> > + ret = imx355_write_reg(imx355, IMX355_REG_LLP,
> > + imx355->hblank->val + imx355->cur_mode->width,
> > + 2);
> > + if (ret)
> > + return ret;
> > +
> > /* Apply customized values from user */
> > ret = __v4l2_ctrl_handler_setup(imx355->sd.ctrl_handler);
> > if (ret)
> >
> > --
> > 2.34.1
> >
> >
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH 06/13] media: imx355: Set binning mode registers programmatically
2026-05-06 18:23 [PATCH 00/13] media/imx355: General code cleanups, and adding support for 2 lane operation Dave Stevenson
` (4 preceding siblings ...)
2026-05-06 18:23 ` [PATCH 05/13] media: imx355: Set register LINE_LENGTH_PCK programmatically Dave Stevenson
@ 2026-05-06 18:23 ` Dave Stevenson
2026-05-07 14:12 ` Jacopo Mondi
2026-05-06 18:23 ` [PATCH 07/13] media: imx355: Remove link_freq_index from each mode as ununsed Dave Stevenson
` (6 subsequent siblings)
12 siblings, 1 reply; 29+ messages in thread
From: Dave Stevenson @ 2026-05-06 18:23 UTC (permalink / raw)
To: Tianshu Qiu, Sakari Ailus, Mauro Carvalho Chehab
Cc: linux-media, linux-kernel, David Heidelberg,
20260414-imx355-24mhz-v1-1-9ae77bc6e7ec, Dave Stevenson
Store the binning mode in the mode structure and set the registers
based on that, rather than having the bare register writes spelled
out for each mode.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/media/i2c/imx355.c | 73 ++++++++++++++++++++--------------------------
1 file changed, 31 insertions(+), 42 deletions(-)
diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
index 56a82f37709e..422454e529a7 100644
--- a/drivers/media/i2c/imx355.c
+++ b/drivers/media/i2c/imx355.c
@@ -73,6 +73,10 @@
#define IMX355_TEST_PATTERN_GRAY_COLOR_BARS 3
#define IMX355_TEST_PATTERN_PN9 4
+#define IMX355_REG_BINNING_MODE 0x0900
+#define IMX355_REG_BINNING_TYPE 0x0901
+#define IMX355_REG_BINNING_WEIGHTING 0x0902
+
/* Flip Control */
#define IMX355_REG_ORIENTATION 0x0101
@@ -117,6 +121,7 @@ struct imx355_mode {
u16 y_add_start;
u16 x_add_end;
u16 y_add_end;
+ u8 binning_mode;
};
struct imx355_clk_params {
@@ -269,113 +274,71 @@ static const struct imx355_reg_list imx355_global_setting = {
};
static const struct imx355_reg mode_3268x2448_regs[] = {
- { 0x0900, 0x00 },
- { 0x0901, 0x11 },
- { 0x0902, 0x00 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
};
static const struct imx355_reg mode_3264x2448_regs[] = {
- { 0x0900, 0x00 },
- { 0x0901, 0x11 },
- { 0x0902, 0x00 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
};
static const struct imx355_reg mode_3280x2464_regs[] = {
- { 0x0900, 0x00 },
- { 0x0901, 0x11 },
- { 0x0902, 0x00 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
};
static const struct imx355_reg mode_1940x1096_regs[] = {
- { 0x0900, 0x00 },
- { 0x0901, 0x11 },
- { 0x0902, 0x00 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
};
static const struct imx355_reg mode_1936x1096_regs[] = {
- { 0x0900, 0x00 },
- { 0x0901, 0x11 },
- { 0x0902, 0x00 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
};
static const struct imx355_reg mode_1924x1080_regs[] = {
- { 0x0900, 0x00 },
- { 0x0901, 0x11 },
- { 0x0902, 0x00 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
};
static const struct imx355_reg mode_1920x1080_regs[] = {
- { 0x0900, 0x00 },
- { 0x0901, 0x11 },
- { 0x0902, 0x00 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
};
static const struct imx355_reg mode_1640x1232_regs[] = {
- { 0x0900, 0x01 },
- { 0x0901, 0x22 },
- { 0x0902, 0x00 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
};
static const struct imx355_reg mode_1640x922_regs[] = {
- { 0x0900, 0x01 },
- { 0x0901, 0x22 },
- { 0x0902, 0x00 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
};
static const struct imx355_reg mode_1300x736_regs[] = {
- { 0x0900, 0x01 },
- { 0x0901, 0x22 },
- { 0x0902, 0x00 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
};
static const struct imx355_reg mode_1296x736_regs[] = {
- { 0x0900, 0x01 },
- { 0x0901, 0x22 },
- { 0x0902, 0x00 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
};
static const struct imx355_reg mode_1284x720_regs[] = {
- { 0x0900, 0x01 },
- { 0x0901, 0x22 },
- { 0x0902, 0x00 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
};
static const struct imx355_reg mode_1280x720_regs[] = {
- { 0x0900, 0x01 },
- { 0x0901, 0x22 },
- { 0x0902, 0x00 },
{ 0x0700, 0x00 },
{ 0x0701, 0x10 },
};
static const struct imx355_reg mode_820x616_regs[] = {
- { 0x0900, 0x01 },
- { 0x0901, 0x44 },
- { 0x0902, 0x00 },
{ 0x0700, 0x02 },
{ 0x0701, 0x78 },
};
@@ -413,6 +376,7 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x0000,
.x_add_end = 0x0ccf,
.y_add_end = 0x099f,
+ .binning_mode = 0x11,
},
{
.width = 3268,
@@ -429,6 +393,7 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x0008,
.x_add_end = 0x0ccb,
.y_add_end = 0x997,
+ .binning_mode = 0x11,
},
{
.width = 3264,
@@ -445,6 +410,7 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x0008,
.x_add_end = 0x0cc7,
.y_add_end = 0x0997,
+ .binning_mode = 0x11,
},
{
.width = 1940,
@@ -461,6 +427,7 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x02ac,
.x_add_end = 0x0a33,
.y_add_end = 0x06f3,
+ .binning_mode = 0x11,
},
{
.width = 1936,
@@ -477,6 +444,7 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x02ac,
.x_add_end = 0x0a2f,
.y_add_end = 0x06f3,
+ .binning_mode = 0x11,
},
{
.width = 1924,
@@ -493,6 +461,7 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x02b4,
.x_add_end = 0x0a2b,
.y_add_end = 0x06eb,
+ .binning_mode = 0x11,
},
{
.width = 1920,
@@ -509,6 +478,7 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x02b4,
.x_add_end = 0x0a27,
.y_add_end = 0x06eb,
+ .binning_mode = 0x11,
},
{
.width = 1640,
@@ -525,6 +495,7 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x0000,
.x_add_end = 0x0ccf,
.y_add_end = 0x099f,
+ .binning_mode = 0x22,
},
{
.width = 1640,
@@ -541,6 +512,7 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x0130,
.x_add_end = 0x0ccf,
.y_add_end = 0x0863,
+ .binning_mode = 0x22,
},
{
.width = 1300,
@@ -557,6 +529,7 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x01f0,
.x_add_end = 0x0b7f,
.y_add_end = 0x07af,
+ .binning_mode = 0x22,
},
{
.width = 1296,
@@ -573,6 +546,7 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x01f0,
.x_add_end = 0x0b77,
.y_add_end = 0x07af,
+ .binning_mode = 0x22,
},
{
.width = 1284,
@@ -589,6 +563,7 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x0200,
.x_add_end = 0x0b6f,
.y_add_end = 0x079f,
+ .binning_mode = 0x22,
},
{
.width = 1280,
@@ -605,6 +580,7 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x0200,
.x_add_end = 0x0b67,
.y_add_end = 0x079f,
+ .binning_mode = 0x22,
},
{
.width = 820,
@@ -621,6 +597,7 @@ static const struct imx355_mode supported_modes[] = {
.y_add_start = 0x0000,
.x_add_end = 0x0ccf,
.y_add_end = 0x099f,
+ .binning_mode = 0x44,
},
};
@@ -997,6 +974,18 @@ static int imx355_start_streaming(struct imx355 *imx355)
if (ret)
return ret;
+ ret = imx355_write_reg(imx355, IMX355_REG_BINNING_MODE, 1,
+ mode->binning_mode == 0x11 ? 0x00 : 0x01);
+ if (ret)
+ return ret;
+ ret = imx355_write_reg(imx355, IMX355_REG_BINNING_TYPE, 1,
+ mode->binning_mode);
+ if (ret)
+ return ret;
+ ret = imx355_write_reg(imx355, IMX355_REG_BINNING_WEIGHTING, 1, 0x00);
+ if (ret)
+ return ret;
+
/* Set PLL registers for the external clock frequency */
ret = imx355_write_reg(imx355, IMX355_REG_EXTCLK_FREQ, 2,
imx355->clk_params->extclk_freq);
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread* Re: [PATCH 06/13] media: imx355: Set binning mode registers programmatically
2026-05-06 18:23 ` [PATCH 06/13] media: imx355: Set binning mode registers programmatically Dave Stevenson
@ 2026-05-07 14:12 ` Jacopo Mondi
0 siblings, 0 replies; 29+ messages in thread
From: Jacopo Mondi @ 2026-05-07 14:12 UTC (permalink / raw)
To: Dave Stevenson
Cc: Tianshu Qiu, Sakari Ailus, Mauro Carvalho Chehab, linux-media,
linux-kernel, David Heidelberg,
20260414-imx355-24mhz-v1-1-9ae77bc6e7ec
Hi Dave
On Wed, May 06, 2026 at 07:23:44PM +0100, Dave Stevenson wrote:
> Store the binning mode in the mode structure and set the registers
> based on that, rather than having the bare register writes spelled
> out for each mode.
Isn't it trivial to calculate this from the (analog crop / visible
size) ratios ?
>
> Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
> ---
> drivers/media/i2c/imx355.c | 73 ++++++++++++++++++++--------------------------
> 1 file changed, 31 insertions(+), 42 deletions(-)
>
> diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
> index 56a82f37709e..422454e529a7 100644
> --- a/drivers/media/i2c/imx355.c
> +++ b/drivers/media/i2c/imx355.c
> @@ -73,6 +73,10 @@
> #define IMX355_TEST_PATTERN_GRAY_COLOR_BARS 3
> #define IMX355_TEST_PATTERN_PN9 4
>
> +#define IMX355_REG_BINNING_MODE 0x0900
> +#define IMX355_REG_BINNING_TYPE 0x0901
> +#define IMX355_REG_BINNING_WEIGHTING 0x0902
> +
> /* Flip Control */
> #define IMX355_REG_ORIENTATION 0x0101
>
> @@ -117,6 +121,7 @@ struct imx355_mode {
> u16 y_add_start;
> u16 x_add_end;
> u16 y_add_end;
> + u8 binning_mode;
> };
>
> struct imx355_clk_params {
> @@ -269,113 +274,71 @@ static const struct imx355_reg_list imx355_global_setting = {
> };
>
> static const struct imx355_reg mode_3268x2448_regs[] = {
> - { 0x0900, 0x00 },
> - { 0x0901, 0x11 },
> - { 0x0902, 0x00 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> };
>
> static const struct imx355_reg mode_3264x2448_regs[] = {
> - { 0x0900, 0x00 },
> - { 0x0901, 0x11 },
> - { 0x0902, 0x00 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> };
>
> static const struct imx355_reg mode_3280x2464_regs[] = {
> - { 0x0900, 0x00 },
> - { 0x0901, 0x11 },
> - { 0x0902, 0x00 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> };
>
> static const struct imx355_reg mode_1940x1096_regs[] = {
> - { 0x0900, 0x00 },
> - { 0x0901, 0x11 },
> - { 0x0902, 0x00 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> };
>
> static const struct imx355_reg mode_1936x1096_regs[] = {
> - { 0x0900, 0x00 },
> - { 0x0901, 0x11 },
> - { 0x0902, 0x00 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> };
>
> static const struct imx355_reg mode_1924x1080_regs[] = {
> - { 0x0900, 0x00 },
> - { 0x0901, 0x11 },
> - { 0x0902, 0x00 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> };
>
> static const struct imx355_reg mode_1920x1080_regs[] = {
> - { 0x0900, 0x00 },
> - { 0x0901, 0x11 },
> - { 0x0902, 0x00 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> };
>
> static const struct imx355_reg mode_1640x1232_regs[] = {
> - { 0x0900, 0x01 },
> - { 0x0901, 0x22 },
> - { 0x0902, 0x00 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> };
>
> static const struct imx355_reg mode_1640x922_regs[] = {
> - { 0x0900, 0x01 },
> - { 0x0901, 0x22 },
> - { 0x0902, 0x00 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> };
>
> static const struct imx355_reg mode_1300x736_regs[] = {
> - { 0x0900, 0x01 },
> - { 0x0901, 0x22 },
> - { 0x0902, 0x00 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> };
>
> static const struct imx355_reg mode_1296x736_regs[] = {
> - { 0x0900, 0x01 },
> - { 0x0901, 0x22 },
> - { 0x0902, 0x00 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> };
>
> static const struct imx355_reg mode_1284x720_regs[] = {
> - { 0x0900, 0x01 },
> - { 0x0901, 0x22 },
> - { 0x0902, 0x00 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> };
>
> static const struct imx355_reg mode_1280x720_regs[] = {
> - { 0x0900, 0x01 },
> - { 0x0901, 0x22 },
> - { 0x0902, 0x00 },
> { 0x0700, 0x00 },
> { 0x0701, 0x10 },
> };
>
> static const struct imx355_reg mode_820x616_regs[] = {
> - { 0x0900, 0x01 },
> - { 0x0901, 0x44 },
> - { 0x0902, 0x00 },
> { 0x0700, 0x02 },
> { 0x0701, 0x78 },
> };
> @@ -413,6 +376,7 @@ static const struct imx355_mode supported_modes[] = {
> .y_add_start = 0x0000,
> .x_add_end = 0x0ccf,
> .y_add_end = 0x099f,
> + .binning_mode = 0x11,
> },
> {
> .width = 3268,
> @@ -429,6 +393,7 @@ static const struct imx355_mode supported_modes[] = {
> .y_add_start = 0x0008,
> .x_add_end = 0x0ccb,
> .y_add_end = 0x997,
> + .binning_mode = 0x11,
> },
> {
> .width = 3264,
> @@ -445,6 +410,7 @@ static const struct imx355_mode supported_modes[] = {
> .y_add_start = 0x0008,
> .x_add_end = 0x0cc7,
> .y_add_end = 0x0997,
> + .binning_mode = 0x11,
> },
> {
> .width = 1940,
> @@ -461,6 +427,7 @@ static const struct imx355_mode supported_modes[] = {
> .y_add_start = 0x02ac,
> .x_add_end = 0x0a33,
> .y_add_end = 0x06f3,
> + .binning_mode = 0x11,
> },
> {
> .width = 1936,
> @@ -477,6 +444,7 @@ static const struct imx355_mode supported_modes[] = {
> .y_add_start = 0x02ac,
> .x_add_end = 0x0a2f,
> .y_add_end = 0x06f3,
> + .binning_mode = 0x11,
> },
> {
> .width = 1924,
> @@ -493,6 +461,7 @@ static const struct imx355_mode supported_modes[] = {
> .y_add_start = 0x02b4,
> .x_add_end = 0x0a2b,
> .y_add_end = 0x06eb,
> + .binning_mode = 0x11,
> },
> {
> .width = 1920,
> @@ -509,6 +478,7 @@ static const struct imx355_mode supported_modes[] = {
> .y_add_start = 0x02b4,
> .x_add_end = 0x0a27,
> .y_add_end = 0x06eb,
> + .binning_mode = 0x11,
> },
> {
> .width = 1640,
> @@ -525,6 +495,7 @@ static const struct imx355_mode supported_modes[] = {
> .y_add_start = 0x0000,
> .x_add_end = 0x0ccf,
> .y_add_end = 0x099f,
> + .binning_mode = 0x22,
> },
> {
> .width = 1640,
> @@ -541,6 +512,7 @@ static const struct imx355_mode supported_modes[] = {
> .y_add_start = 0x0130,
> .x_add_end = 0x0ccf,
> .y_add_end = 0x0863,
> + .binning_mode = 0x22,
> },
> {
> .width = 1300,
> @@ -557,6 +529,7 @@ static const struct imx355_mode supported_modes[] = {
> .y_add_start = 0x01f0,
> .x_add_end = 0x0b7f,
> .y_add_end = 0x07af,
> + .binning_mode = 0x22,
> },
> {
> .width = 1296,
> @@ -573,6 +546,7 @@ static const struct imx355_mode supported_modes[] = {
> .y_add_start = 0x01f0,
> .x_add_end = 0x0b77,
> .y_add_end = 0x07af,
> + .binning_mode = 0x22,
> },
> {
> .width = 1284,
> @@ -589,6 +563,7 @@ static const struct imx355_mode supported_modes[] = {
> .y_add_start = 0x0200,
> .x_add_end = 0x0b6f,
> .y_add_end = 0x079f,
> + .binning_mode = 0x22,
> },
> {
> .width = 1280,
> @@ -605,6 +580,7 @@ static const struct imx355_mode supported_modes[] = {
> .y_add_start = 0x0200,
> .x_add_end = 0x0b67,
> .y_add_end = 0x079f,
> + .binning_mode = 0x22,
> },
> {
> .width = 820,
> @@ -621,6 +597,7 @@ static const struct imx355_mode supported_modes[] = {
> .y_add_start = 0x0000,
> .x_add_end = 0x0ccf,
> .y_add_end = 0x099f,
> + .binning_mode = 0x44,
> },
> };
>
> @@ -997,6 +974,18 @@ static int imx355_start_streaming(struct imx355 *imx355)
> if (ret)
> return ret;
>
> + ret = imx355_write_reg(imx355, IMX355_REG_BINNING_MODE, 1,
> + mode->binning_mode == 0x11 ? 0x00 : 0x01);
> + if (ret)
> + return ret;
> + ret = imx355_write_reg(imx355, IMX355_REG_BINNING_TYPE, 1,
> + mode->binning_mode);
> + if (ret)
> + return ret;
> + ret = imx355_write_reg(imx355, IMX355_REG_BINNING_WEIGHTING, 1, 0x00);
> + if (ret)
> + return ret;
> +
> /* Set PLL registers for the external clock frequency */
> ret = imx355_write_reg(imx355, IMX355_REG_EXTCLK_FREQ, 2,
> imx355->clk_params->extclk_freq);
>
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH 07/13] media: imx355: Remove link_freq_index from each mode as ununsed
2026-05-06 18:23 [PATCH 00/13] media/imx355: General code cleanups, and adding support for 2 lane operation Dave Stevenson
` (5 preceding siblings ...)
2026-05-06 18:23 ` [PATCH 06/13] media: imx355: Set binning mode registers programmatically Dave Stevenson
@ 2026-05-06 18:23 ` Dave Stevenson
2026-05-07 14:12 ` Jacopo Mondi
2026-05-06 18:23 ` [PATCH 08/13] media: imx355: pixel_rate never changes, so don't recompute Dave Stevenson
` (5 subsequent siblings)
12 siblings, 1 reply; 29+ messages in thread
From: Dave Stevenson @ 2026-05-06 18:23 UTC (permalink / raw)
To: Tianshu Qiu, Sakari Ailus, Mauro Carvalho Chehab
Cc: linux-media, linux-kernel, David Heidelberg,
20260414-imx355-24mhz-v1-1-9ae77bc6e7ec, Dave Stevenson
The link_freq_index value in imx355_mode is unused, so remove it.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/media/i2c/imx355.c | 18 ------------------
1 file changed, 18 deletions(-)
diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
index 422454e529a7..b0cddb614775 100644
--- a/drivers/media/i2c/imx355.c
+++ b/drivers/media/i2c/imx355.c
@@ -82,7 +82,6 @@
/* default link frequency and external clock */
#define IMX355_LINK_FREQ_DEFAULT 360000000LL
-#define IMX355_LINK_FREQ_INDEX 0
/* number of data lanes */
#define IMX355_DATA_LANES 4
@@ -111,9 +110,6 @@ struct imx355_mode {
/* H-timing */
u32 llp;
- /* index of link frequency */
- u32 link_freq_index;
-
/* Default register values */
struct imx355_reg_list reg_list;
@@ -367,7 +363,6 @@ static const struct imx355_mode supported_modes[] = {
.fll_def = 2615,
.fll_min = 2615,
.llp = 3672,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
.regs = mode_3280x2464_regs,
@@ -384,7 +379,6 @@ static const struct imx355_mode supported_modes[] = {
.fll_def = 2615,
.fll_min = 2615,
.llp = 3672,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_3268x2448_regs),
.regs = mode_3268x2448_regs,
@@ -401,7 +395,6 @@ static const struct imx355_mode supported_modes[] = {
.fll_def = 2615,
.fll_min = 2615,
.llp = 3672,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_3264x2448_regs),
.regs = mode_3264x2448_regs,
@@ -418,7 +411,6 @@ static const struct imx355_mode supported_modes[] = {
.fll_def = 1306,
.fll_min = 1306,
.llp = 3672,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1940x1096_regs),
.regs = mode_1940x1096_regs,
@@ -435,7 +427,6 @@ static const struct imx355_mode supported_modes[] = {
.fll_def = 1306,
.fll_min = 1306,
.llp = 3672,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1936x1096_regs),
.regs = mode_1936x1096_regs,
@@ -452,7 +443,6 @@ static const struct imx355_mode supported_modes[] = {
.fll_def = 1306,
.fll_min = 1306,
.llp = 3672,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1924x1080_regs),
.regs = mode_1924x1080_regs,
@@ -469,7 +459,6 @@ static const struct imx355_mode supported_modes[] = {
.fll_def = 1306,
.fll_min = 1306,
.llp = 3672,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1920x1080_regs),
.regs = mode_1920x1080_regs,
@@ -486,7 +475,6 @@ static const struct imx355_mode supported_modes[] = {
.fll_def = 1306,
.fll_min = 1306,
.llp = 1836,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1640x1232_regs),
.regs = mode_1640x1232_regs,
@@ -503,7 +491,6 @@ static const struct imx355_mode supported_modes[] = {
.fll_def = 1306,
.fll_min = 1306,
.llp = 1836,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1640x922_regs),
.regs = mode_1640x922_regs,
@@ -520,7 +507,6 @@ static const struct imx355_mode supported_modes[] = {
.fll_def = 1306,
.fll_min = 1306,
.llp = 1836,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1300x736_regs),
.regs = mode_1300x736_regs,
@@ -537,7 +523,6 @@ static const struct imx355_mode supported_modes[] = {
.fll_def = 1306,
.fll_min = 1306,
.llp = 1836,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1296x736_regs),
.regs = mode_1296x736_regs,
@@ -554,7 +539,6 @@ static const struct imx355_mode supported_modes[] = {
.fll_def = 1306,
.fll_min = 1306,
.llp = 1836,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1284x720_regs),
.regs = mode_1284x720_regs,
@@ -571,7 +555,6 @@ static const struct imx355_mode supported_modes[] = {
.fll_def = 1306,
.fll_min = 1306,
.llp = 1836,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1280x720_regs),
.regs = mode_1280x720_regs,
@@ -588,7 +571,6 @@ static const struct imx355_mode supported_modes[] = {
.fll_def = 652,
.fll_min = 652,
.llp = 3672,
- .link_freq_index = IMX355_LINK_FREQ_INDEX,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_820x616_regs),
.regs = mode_820x616_regs,
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread* Re: [PATCH 07/13] media: imx355: Remove link_freq_index from each mode as ununsed
2026-05-06 18:23 ` [PATCH 07/13] media: imx355: Remove link_freq_index from each mode as ununsed Dave Stevenson
@ 2026-05-07 14:12 ` Jacopo Mondi
0 siblings, 0 replies; 29+ messages in thread
From: Jacopo Mondi @ 2026-05-07 14:12 UTC (permalink / raw)
To: Dave Stevenson
Cc: Tianshu Qiu, Sakari Ailus, Mauro Carvalho Chehab, linux-media,
linux-kernel, David Heidelberg,
20260414-imx355-24mhz-v1-1-9ae77bc6e7ec
Hi Dave
On Wed, May 06, 2026 at 07:23:45PM +0100, Dave Stevenson wrote:
> The link_freq_index value in imx355_mode is unused, so remove it.
>
> Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
> ---
> drivers/media/i2c/imx355.c | 18 ------------------
> 1 file changed, 18 deletions(-)
>
> diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
> index 422454e529a7..b0cddb614775 100644
> --- a/drivers/media/i2c/imx355.c
> +++ b/drivers/media/i2c/imx355.c
> @@ -82,7 +82,6 @@
>
> /* default link frequency and external clock */
> #define IMX355_LINK_FREQ_DEFAULT 360000000LL
> -#define IMX355_LINK_FREQ_INDEX 0
>
> /* number of data lanes */
> #define IMX355_DATA_LANES 4
> @@ -111,9 +110,6 @@ struct imx355_mode {
> /* H-timing */
> u32 llp;
>
> - /* index of link frequency */
> - u32 link_freq_index;
> -
> /* Default register values */
> struct imx355_reg_list reg_list;
>
> @@ -367,7 +363,6 @@ static const struct imx355_mode supported_modes[] = {
> .fll_def = 2615,
> .fll_min = 2615,
> .llp = 3672,
> - .link_freq_index = IMX355_LINK_FREQ_INDEX,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
> .regs = mode_3280x2464_regs,
> @@ -384,7 +379,6 @@ static const struct imx355_mode supported_modes[] = {
> .fll_def = 2615,
> .fll_min = 2615,
> .llp = 3672,
> - .link_freq_index = IMX355_LINK_FREQ_INDEX,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_3268x2448_regs),
> .regs = mode_3268x2448_regs,
> @@ -401,7 +395,6 @@ static const struct imx355_mode supported_modes[] = {
> .fll_def = 2615,
> .fll_min = 2615,
> .llp = 3672,
> - .link_freq_index = IMX355_LINK_FREQ_INDEX,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_3264x2448_regs),
> .regs = mode_3264x2448_regs,
> @@ -418,7 +411,6 @@ static const struct imx355_mode supported_modes[] = {
> .fll_def = 1306,
> .fll_min = 1306,
> .llp = 3672,
> - .link_freq_index = IMX355_LINK_FREQ_INDEX,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_1940x1096_regs),
> .regs = mode_1940x1096_regs,
> @@ -435,7 +427,6 @@ static const struct imx355_mode supported_modes[] = {
> .fll_def = 1306,
> .fll_min = 1306,
> .llp = 3672,
> - .link_freq_index = IMX355_LINK_FREQ_INDEX,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_1936x1096_regs),
> .regs = mode_1936x1096_regs,
> @@ -452,7 +443,6 @@ static const struct imx355_mode supported_modes[] = {
> .fll_def = 1306,
> .fll_min = 1306,
> .llp = 3672,
> - .link_freq_index = IMX355_LINK_FREQ_INDEX,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_1924x1080_regs),
> .regs = mode_1924x1080_regs,
> @@ -469,7 +459,6 @@ static const struct imx355_mode supported_modes[] = {
> .fll_def = 1306,
> .fll_min = 1306,
> .llp = 3672,
> - .link_freq_index = IMX355_LINK_FREQ_INDEX,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_1920x1080_regs),
> .regs = mode_1920x1080_regs,
> @@ -486,7 +475,6 @@ static const struct imx355_mode supported_modes[] = {
> .fll_def = 1306,
> .fll_min = 1306,
> .llp = 1836,
> - .link_freq_index = IMX355_LINK_FREQ_INDEX,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_1640x1232_regs),
> .regs = mode_1640x1232_regs,
> @@ -503,7 +491,6 @@ static const struct imx355_mode supported_modes[] = {
> .fll_def = 1306,
> .fll_min = 1306,
> .llp = 1836,
> - .link_freq_index = IMX355_LINK_FREQ_INDEX,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_1640x922_regs),
> .regs = mode_1640x922_regs,
> @@ -520,7 +507,6 @@ static const struct imx355_mode supported_modes[] = {
> .fll_def = 1306,
> .fll_min = 1306,
> .llp = 1836,
> - .link_freq_index = IMX355_LINK_FREQ_INDEX,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_1300x736_regs),
> .regs = mode_1300x736_regs,
> @@ -537,7 +523,6 @@ static const struct imx355_mode supported_modes[] = {
> .fll_def = 1306,
> .fll_min = 1306,
> .llp = 1836,
> - .link_freq_index = IMX355_LINK_FREQ_INDEX,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_1296x736_regs),
> .regs = mode_1296x736_regs,
> @@ -554,7 +539,6 @@ static const struct imx355_mode supported_modes[] = {
> .fll_def = 1306,
> .fll_min = 1306,
> .llp = 1836,
> - .link_freq_index = IMX355_LINK_FREQ_INDEX,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_1284x720_regs),
> .regs = mode_1284x720_regs,
> @@ -571,7 +555,6 @@ static const struct imx355_mode supported_modes[] = {
> .fll_def = 1306,
> .fll_min = 1306,
> .llp = 1836,
> - .link_freq_index = IMX355_LINK_FREQ_INDEX,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_1280x720_regs),
> .regs = mode_1280x720_regs,
> @@ -588,7 +571,6 @@ static const struct imx355_mode supported_modes[] = {
> .fll_def = 652,
> .fll_min = 652,
> .llp = 3672,
> - .link_freq_index = IMX355_LINK_FREQ_INDEX,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_820x616_regs),
> .regs = mode_820x616_regs,
>
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH 08/13] media: imx355: pixel_rate never changes, so don't recompute
2026-05-06 18:23 [PATCH 00/13] media/imx355: General code cleanups, and adding support for 2 lane operation Dave Stevenson
` (6 preceding siblings ...)
2026-05-06 18:23 ` [PATCH 07/13] media: imx355: Remove link_freq_index from each mode as ununsed Dave Stevenson
@ 2026-05-06 18:23 ` Dave Stevenson
2026-05-07 14:13 ` Jacopo Mondi
2026-05-06 18:23 ` [PATCH 09/13] media: imx355: Remove redundant fll_min, and implement fixed offset Dave Stevenson
` (4 subsequent siblings)
12 siblings, 1 reply; 29+ messages in thread
From: Dave Stevenson @ 2026-05-06 18:23 UTC (permalink / raw)
To: Tianshu Qiu, Sakari Ailus, Mauro Carvalho Chehab
Cc: linux-media, linux-kernel, David Heidelberg,
20260414-imx355-24mhz-v1-1-9ae77bc6e7ec, Dave Stevenson
The pixel rate is always the same, so there is no need to try and
recompute it in imx355_set_pad_format, and then no need to have the
pointer to it stored.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/media/i2c/imx355.c | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
index b0cddb614775..12005bc40f36 100644
--- a/drivers/media/i2c/imx355.c
+++ b/drivers/media/i2c/imx355.c
@@ -161,7 +161,6 @@ struct imx355 {
struct v4l2_ctrl_handler ctrl_handler;
/* V4L2 Controls */
struct v4l2_ctrl *link_freq;
- struct v4l2_ctrl *pixel_rate;
struct v4l2_ctrl *vblank;
struct v4l2_ctrl *hblank;
struct v4l2_ctrl *exposure;
@@ -860,7 +859,6 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
s32 vblank_def;
s32 vblank_min;
s64 h_blank;
- u64 pixel_rate;
u32 height;
mutex_lock(&imx355->mutex);
@@ -881,9 +879,6 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
*framefmt = fmt->format;
} else {
imx355->cur_mode = mode;
- pixel_rate = IMX355_LINK_FREQ_DEFAULT * 2 * 4;
- do_div(pixel_rate, 10);
- __v4l2_ctrl_s_ctrl_int64(imx355->pixel_rate, pixel_rate);
/* Update limits and set FPS to default */
height = imx355->cur_mode->height;
vblank_def = imx355->cur_mode->fll_def - height;
@@ -1175,9 +1170,8 @@ static int imx355_init_controls(struct imx355 *imx355)
pixel_rate = IMX355_LINK_FREQ_DEFAULT * 2 * 4;
do_div(pixel_rate, 10);
/* By default, PIXEL_RATE is read only */
- imx355->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
- V4L2_CID_PIXEL_RATE, pixel_rate,
- pixel_rate, 1, pixel_rate);
+ v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops, V4L2_CID_PIXEL_RATE,
+ pixel_rate, pixel_rate, 1, pixel_rate);
/* Initialize vblank/hblank/exposure parameters based on current mode */
mode = imx355->cur_mode;
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread* Re: [PATCH 08/13] media: imx355: pixel_rate never changes, so don't recompute
2026-05-06 18:23 ` [PATCH 08/13] media: imx355: pixel_rate never changes, so don't recompute Dave Stevenson
@ 2026-05-07 14:13 ` Jacopo Mondi
0 siblings, 0 replies; 29+ messages in thread
From: Jacopo Mondi @ 2026-05-07 14:13 UTC (permalink / raw)
To: Dave Stevenson
Cc: Tianshu Qiu, Sakari Ailus, Mauro Carvalho Chehab, linux-media,
linux-kernel, David Heidelberg,
20260414-imx355-24mhz-v1-1-9ae77bc6e7ec
Hi Dave
On Wed, May 06, 2026 at 07:23:46PM +0100, Dave Stevenson wrote:
> The pixel rate is always the same, so there is no need to try and
> recompute it in imx355_set_pad_format, and then no need to have the
> pointer to it stored.
>
> Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
> ---
> drivers/media/i2c/imx355.c | 10 ++--------
> 1 file changed, 2 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
> index b0cddb614775..12005bc40f36 100644
> --- a/drivers/media/i2c/imx355.c
> +++ b/drivers/media/i2c/imx355.c
> @@ -161,7 +161,6 @@ struct imx355 {
> struct v4l2_ctrl_handler ctrl_handler;
> /* V4L2 Controls */
> struct v4l2_ctrl *link_freq;
> - struct v4l2_ctrl *pixel_rate;
> struct v4l2_ctrl *vblank;
> struct v4l2_ctrl *hblank;
> struct v4l2_ctrl *exposure;
> @@ -860,7 +859,6 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
> s32 vblank_def;
> s32 vblank_min;
> s64 h_blank;
> - u64 pixel_rate;
> u32 height;
>
> mutex_lock(&imx355->mutex);
> @@ -881,9 +879,6 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
> *framefmt = fmt->format;
> } else {
> imx355->cur_mode = mode;
> - pixel_rate = IMX355_LINK_FREQ_DEFAULT * 2 * 4;
> - do_div(pixel_rate, 10);
> - __v4l2_ctrl_s_ctrl_int64(imx355->pixel_rate, pixel_rate);
> /* Update limits and set FPS to default */
> height = imx355->cur_mode->height;
> vblank_def = imx355->cur_mode->fll_def - height;
> @@ -1175,9 +1170,8 @@ static int imx355_init_controls(struct imx355 *imx355)
> pixel_rate = IMX355_LINK_FREQ_DEFAULT * 2 * 4;
> do_div(pixel_rate, 10);
> /* By default, PIXEL_RATE is read only */
> - imx355->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
> - V4L2_CID_PIXEL_RATE, pixel_rate,
> - pixel_rate, 1, pixel_rate);
> + v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops, V4L2_CID_PIXEL_RATE,
> + pixel_rate, pixel_rate, 1, pixel_rate);
>
> /* Initialize vblank/hblank/exposure parameters based on current mode */
> mode = imx355->cur_mode;
>
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH 09/13] media: imx355: Remove redundant fll_min, and implement fixed offset
2026-05-06 18:23 [PATCH 00/13] media/imx355: General code cleanups, and adding support for 2 lane operation Dave Stevenson
` (7 preceding siblings ...)
2026-05-06 18:23 ` [PATCH 08/13] media: imx355: pixel_rate never changes, so don't recompute Dave Stevenson
@ 2026-05-06 18:23 ` Dave Stevenson
2026-05-07 14:29 ` Jacopo Mondi
2026-05-06 18:23 ` [PATCH 10/13] media: imx355: Add support for get_selection Dave Stevenson
` (3 subsequent siblings)
12 siblings, 1 reply; 29+ messages in thread
From: Dave Stevenson @ 2026-05-06 18:23 UTC (permalink / raw)
To: Tianshu Qiu, Sakari Ailus, Mauro Carvalho Chehab
Cc: linux-media, linux-kernel, David Heidelberg,
20260414-imx355-24mhz-v1-1-9ae77bc6e7ec, Dave Stevenson
fll_min (Frame Length Lines) is set to the same value as fll_def
for all modes, which makes it redundant.
The actual value is also erroneous as sensor works in all the
defined modes with FLL set at the mode height + 20 lines, so
set the vblank control minimum to 20 rather than varying it.
This also improves the maximum frame rate achievable.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/media/i2c/imx355.c | 27 +++++----------------------
1 file changed, 5 insertions(+), 22 deletions(-)
diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
index 12005bc40f36..5a3bfcd0f51c 100644
--- a/drivers/media/i2c/imx355.c
+++ b/drivers/media/i2c/imx355.c
@@ -33,6 +33,8 @@
/* V_TIMING internal */
#define IMX355_REG_FLL 0x0340
#define IMX355_FLL_MAX 0xffff
+/* Number of lines above frame height that are required. */
+#define IMX355_FLL_OFFSET 20
#define IMX355_REG_LLP 0x0342
#define IMX355_LLP_MAX 0xffff
@@ -105,7 +107,6 @@ struct imx355_mode {
/* V-timing */
u32 fll_def;
- u32 fll_min;
/* H-timing */
u32 llp;
@@ -360,7 +361,6 @@ static const struct imx355_mode supported_modes[] = {
.width = 3280,
.height = 2464,
.fll_def = 2615,
- .fll_min = 2615,
.llp = 3672,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
@@ -376,7 +376,6 @@ static const struct imx355_mode supported_modes[] = {
.width = 3268,
.height = 2448,
.fll_def = 2615,
- .fll_min = 2615,
.llp = 3672,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_3268x2448_regs),
@@ -392,7 +391,6 @@ static const struct imx355_mode supported_modes[] = {
.width = 3264,
.height = 2448,
.fll_def = 2615,
- .fll_min = 2615,
.llp = 3672,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_3264x2448_regs),
@@ -408,7 +406,6 @@ static const struct imx355_mode supported_modes[] = {
.width = 1940,
.height = 1096,
.fll_def = 1306,
- .fll_min = 1306,
.llp = 3672,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1940x1096_regs),
@@ -424,7 +421,6 @@ static const struct imx355_mode supported_modes[] = {
.width = 1936,
.height = 1096,
.fll_def = 1306,
- .fll_min = 1306,
.llp = 3672,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1936x1096_regs),
@@ -440,7 +436,6 @@ static const struct imx355_mode supported_modes[] = {
.width = 1924,
.height = 1080,
.fll_def = 1306,
- .fll_min = 1306,
.llp = 3672,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1924x1080_regs),
@@ -456,7 +451,6 @@ static const struct imx355_mode supported_modes[] = {
.width = 1920,
.height = 1080,
.fll_def = 1306,
- .fll_min = 1306,
.llp = 3672,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1920x1080_regs),
@@ -472,7 +466,6 @@ static const struct imx355_mode supported_modes[] = {
.width = 1640,
.height = 1232,
.fll_def = 1306,
- .fll_min = 1306,
.llp = 1836,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1640x1232_regs),
@@ -488,7 +481,6 @@ static const struct imx355_mode supported_modes[] = {
.width = 1640,
.height = 922,
.fll_def = 1306,
- .fll_min = 1306,
.llp = 1836,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1640x922_regs),
@@ -504,7 +496,6 @@ static const struct imx355_mode supported_modes[] = {
.width = 1300,
.height = 736,
.fll_def = 1306,
- .fll_min = 1306,
.llp = 1836,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1300x736_regs),
@@ -520,7 +511,6 @@ static const struct imx355_mode supported_modes[] = {
.width = 1296,
.height = 736,
.fll_def = 1306,
- .fll_min = 1306,
.llp = 1836,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1296x736_regs),
@@ -536,7 +526,6 @@ static const struct imx355_mode supported_modes[] = {
.width = 1284,
.height = 720,
.fll_def = 1306,
- .fll_min = 1306,
.llp = 1836,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1284x720_regs),
@@ -552,7 +541,6 @@ static const struct imx355_mode supported_modes[] = {
.width = 1280,
.height = 720,
.fll_def = 1306,
- .fll_min = 1306,
.llp = 1836,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1280x720_regs),
@@ -568,7 +556,6 @@ static const struct imx355_mode supported_modes[] = {
.width = 820,
.height = 616,
.fll_def = 652,
- .fll_min = 652,
.llp = 3672,
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_820x616_regs),
@@ -857,7 +844,6 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
const struct imx355_mode *mode;
struct v4l2_mbus_framefmt *framefmt;
s32 vblank_def;
- s32 vblank_min;
s64 h_blank;
u32 height;
@@ -882,10 +868,9 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
/* Update limits and set FPS to default */
height = imx355->cur_mode->height;
vblank_def = imx355->cur_mode->fll_def - height;
- vblank_min = imx355->cur_mode->fll_min - height;
height = IMX355_FLL_MAX - height;
- __v4l2_ctrl_modify_range(imx355->vblank, vblank_min, height, 1,
- vblank_def);
+ __v4l2_ctrl_modify_range(imx355->vblank, IMX355_FLL_OFFSET,
+ height, 1, vblank_def);
__v4l2_ctrl_s_ctrl(imx355->vblank, vblank_def);
h_blank = mode->llp - imx355->cur_mode->width;
/*
@@ -1146,7 +1131,6 @@ static int imx355_init_controls(struct imx355 *imx355)
struct v4l2_ctrl_handler *ctrl_hdlr;
s64 exposure_max;
s64 vblank_def;
- s64 vblank_min;
s64 hblank;
u64 pixel_rate;
const struct imx355_mode *mode;
@@ -1176,9 +1160,8 @@ static int imx355_init_controls(struct imx355 *imx355)
/* Initialize vblank/hblank/exposure parameters based on current mode */
mode = imx355->cur_mode;
vblank_def = mode->fll_def - mode->height;
- vblank_min = mode->fll_min - mode->height;
imx355->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
- V4L2_CID_VBLANK, vblank_min,
+ V4L2_CID_VBLANK, IMX355_FLL_OFFSET,
IMX355_FLL_MAX - mode->height,
1, vblank_def);
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread* Re: [PATCH 09/13] media: imx355: Remove redundant fll_min, and implement fixed offset
2026-05-06 18:23 ` [PATCH 09/13] media: imx355: Remove redundant fll_min, and implement fixed offset Dave Stevenson
@ 2026-05-07 14:29 ` Jacopo Mondi
2026-05-07 15:21 ` Dave Stevenson
0 siblings, 1 reply; 29+ messages in thread
From: Jacopo Mondi @ 2026-05-07 14:29 UTC (permalink / raw)
To: Dave Stevenson
Cc: Tianshu Qiu, Sakari Ailus, Mauro Carvalho Chehab, linux-media,
linux-kernel, David Heidelberg,
20260414-imx355-24mhz-v1-1-9ae77bc6e7ec
Hi Dave
On Wed, May 06, 2026 at 07:23:47PM +0100, Dave Stevenson wrote:
> fll_min (Frame Length Lines) is set to the same value as fll_def
> for all modes, which makes it redundant.
>
> The actual value is also erroneous as sensor works in all the
> defined modes with FLL set at the mode height + 20 lines, so
> set the vblank control minimum to 20 rather than varying it.
> This also improves the maximum frame rate achievable.
>
> Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
> ---
> drivers/media/i2c/imx355.c | 27 +++++----------------------
> 1 file changed, 5 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
> index 12005bc40f36..5a3bfcd0f51c 100644
> --- a/drivers/media/i2c/imx355.c
> +++ b/drivers/media/i2c/imx355.c
> @@ -33,6 +33,8 @@
> /* V_TIMING internal */
> #define IMX355_REG_FLL 0x0340
> #define IMX355_FLL_MAX 0xffff
> +/* Number of lines above frame height that are required. */
> +#define IMX355_FLL_OFFSET 20
I would have called it FFL_MIN, but it's probably just a matter of
taste
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
>
> #define IMX355_REG_LLP 0x0342
> #define IMX355_LLP_MAX 0xffff
> @@ -105,7 +107,6 @@ struct imx355_mode {
>
> /* V-timing */
> u32 fll_def;
> - u32 fll_min;
>
> /* H-timing */
> u32 llp;
> @@ -360,7 +361,6 @@ static const struct imx355_mode supported_modes[] = {
> .width = 3280,
> .height = 2464,
> .fll_def = 2615,
> - .fll_min = 2615,
> .llp = 3672,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
> @@ -376,7 +376,6 @@ static const struct imx355_mode supported_modes[] = {
> .width = 3268,
> .height = 2448,
> .fll_def = 2615,
> - .fll_min = 2615,
> .llp = 3672,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_3268x2448_regs),
> @@ -392,7 +391,6 @@ static const struct imx355_mode supported_modes[] = {
> .width = 3264,
> .height = 2448,
> .fll_def = 2615,
> - .fll_min = 2615,
> .llp = 3672,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_3264x2448_regs),
> @@ -408,7 +406,6 @@ static const struct imx355_mode supported_modes[] = {
> .width = 1940,
> .height = 1096,
> .fll_def = 1306,
> - .fll_min = 1306,
> .llp = 3672,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_1940x1096_regs),
> @@ -424,7 +421,6 @@ static const struct imx355_mode supported_modes[] = {
> .width = 1936,
> .height = 1096,
> .fll_def = 1306,
> - .fll_min = 1306,
> .llp = 3672,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_1936x1096_regs),
> @@ -440,7 +436,6 @@ static const struct imx355_mode supported_modes[] = {
> .width = 1924,
> .height = 1080,
> .fll_def = 1306,
> - .fll_min = 1306,
> .llp = 3672,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_1924x1080_regs),
> @@ -456,7 +451,6 @@ static const struct imx355_mode supported_modes[] = {
> .width = 1920,
> .height = 1080,
> .fll_def = 1306,
> - .fll_min = 1306,
> .llp = 3672,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_1920x1080_regs),
> @@ -472,7 +466,6 @@ static const struct imx355_mode supported_modes[] = {
> .width = 1640,
> .height = 1232,
> .fll_def = 1306,
> - .fll_min = 1306,
> .llp = 1836,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_1640x1232_regs),
> @@ -488,7 +481,6 @@ static const struct imx355_mode supported_modes[] = {
> .width = 1640,
> .height = 922,
> .fll_def = 1306,
> - .fll_min = 1306,
> .llp = 1836,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_1640x922_regs),
> @@ -504,7 +496,6 @@ static const struct imx355_mode supported_modes[] = {
> .width = 1300,
> .height = 736,
> .fll_def = 1306,
> - .fll_min = 1306,
> .llp = 1836,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_1300x736_regs),
> @@ -520,7 +511,6 @@ static const struct imx355_mode supported_modes[] = {
> .width = 1296,
> .height = 736,
> .fll_def = 1306,
> - .fll_min = 1306,
> .llp = 1836,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_1296x736_regs),
> @@ -536,7 +526,6 @@ static const struct imx355_mode supported_modes[] = {
> .width = 1284,
> .height = 720,
> .fll_def = 1306,
> - .fll_min = 1306,
> .llp = 1836,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_1284x720_regs),
> @@ -552,7 +541,6 @@ static const struct imx355_mode supported_modes[] = {
> .width = 1280,
> .height = 720,
> .fll_def = 1306,
> - .fll_min = 1306,
> .llp = 1836,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_1280x720_regs),
> @@ -568,7 +556,6 @@ static const struct imx355_mode supported_modes[] = {
> .width = 820,
> .height = 616,
> .fll_def = 652,
> - .fll_min = 652,
> .llp = 3672,
> .reg_list = {
> .num_of_regs = ARRAY_SIZE(mode_820x616_regs),
> @@ -857,7 +844,6 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
> const struct imx355_mode *mode;
> struct v4l2_mbus_framefmt *framefmt;
> s32 vblank_def;
> - s32 vblank_min;
> s64 h_blank;
> u32 height;
>
> @@ -882,10 +868,9 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
> /* Update limits and set FPS to default */
> height = imx355->cur_mode->height;
> vblank_def = imx355->cur_mode->fll_def - height;
> - vblank_min = imx355->cur_mode->fll_min - height;
> height = IMX355_FLL_MAX - height;
re-using 'height' here is not nice, but I understand it was there
already
> - __v4l2_ctrl_modify_range(imx355->vblank, vblank_min, height, 1,
> - vblank_def);
> + __v4l2_ctrl_modify_range(imx355->vblank, IMX355_FLL_OFFSET,
> + height, 1, vblank_def);
> __v4l2_ctrl_s_ctrl(imx355->vblank, vblank_def);
> h_blank = mode->llp - imx355->cur_mode->width;
> /*
> @@ -1146,7 +1131,6 @@ static int imx355_init_controls(struct imx355 *imx355)
> struct v4l2_ctrl_handler *ctrl_hdlr;
> s64 exposure_max;
> s64 vblank_def;
> - s64 vblank_min;
> s64 hblank;
> u64 pixel_rate;
> const struct imx355_mode *mode;
> @@ -1176,9 +1160,8 @@ static int imx355_init_controls(struct imx355 *imx355)
> /* Initialize vblank/hblank/exposure parameters based on current mode */
> mode = imx355->cur_mode;
> vblank_def = mode->fll_def - mode->height;
> - vblank_min = mode->fll_min - mode->height;
> imx355->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
> - V4L2_CID_VBLANK, vblank_min,
> + V4L2_CID_VBLANK, IMX355_FLL_OFFSET,
> IMX355_FLL_MAX - mode->height,
> 1, vblank_def);
>
>
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 29+ messages in thread* Re: [PATCH 09/13] media: imx355: Remove redundant fll_min, and implement fixed offset
2026-05-07 14:29 ` Jacopo Mondi
@ 2026-05-07 15:21 ` Dave Stevenson
0 siblings, 0 replies; 29+ messages in thread
From: Dave Stevenson @ 2026-05-07 15:21 UTC (permalink / raw)
To: Jacopo Mondi
Cc: Sakari Ailus, Mauro Carvalho Chehab, linux-media, linux-kernel,
David Heidelberg
Hi Jacopo
On Thu, 7 May 2026 at 15:29, Jacopo Mondi <jacopo.mondi@ideasonboard.com> wrote:
>
> Hi Dave
>
> On Wed, May 06, 2026 at 07:23:47PM +0100, Dave Stevenson wrote:
> > fll_min (Frame Length Lines) is set to the same value as fll_def
> > for all modes, which makes it redundant.
> >
> > The actual value is also erroneous as sensor works in all the
> > defined modes with FLL set at the mode height + 20 lines, so
> > set the vblank control minimum to 20 rather than varying it.
> > This also improves the maximum frame rate achievable.
> >
> > Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
> > ---
> > drivers/media/i2c/imx355.c | 27 +++++----------------------
> > 1 file changed, 5 insertions(+), 22 deletions(-)
> >
> > diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
> > index 12005bc40f36..5a3bfcd0f51c 100644
> > --- a/drivers/media/i2c/imx355.c
> > +++ b/drivers/media/i2c/imx355.c
> > @@ -33,6 +33,8 @@
> > /* V_TIMING internal */
> > #define IMX355_REG_FLL 0x0340
> > #define IMX355_FLL_MAX 0xffff
> > +/* Number of lines above frame height that are required. */
> > +#define IMX355_FLL_OFFSET 20
>
> I would have called it FFL_MIN, but it's probably just a matter of
> taste
It's not the minimum value for the FFL register though as that
includes the image height.
It could be IMX355_VBLANK_MIN if preferred.
Dave
> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
>
> >
> > #define IMX355_REG_LLP 0x0342
> > #define IMX355_LLP_MAX 0xffff
> > @@ -105,7 +107,6 @@ struct imx355_mode {
> >
> > /* V-timing */
> > u32 fll_def;
> > - u32 fll_min;
> >
> > /* H-timing */
> > u32 llp;
> > @@ -360,7 +361,6 @@ static const struct imx355_mode supported_modes[] = {
> > .width = 3280,
> > .height = 2464,
> > .fll_def = 2615,
> > - .fll_min = 2615,
> > .llp = 3672,
> > .reg_list = {
> > .num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
> > @@ -376,7 +376,6 @@ static const struct imx355_mode supported_modes[] = {
> > .width = 3268,
> > .height = 2448,
> > .fll_def = 2615,
> > - .fll_min = 2615,
> > .llp = 3672,
> > .reg_list = {
> > .num_of_regs = ARRAY_SIZE(mode_3268x2448_regs),
> > @@ -392,7 +391,6 @@ static const struct imx355_mode supported_modes[] = {
> > .width = 3264,
> > .height = 2448,
> > .fll_def = 2615,
> > - .fll_min = 2615,
> > .llp = 3672,
> > .reg_list = {
> > .num_of_regs = ARRAY_SIZE(mode_3264x2448_regs),
> > @@ -408,7 +406,6 @@ static const struct imx355_mode supported_modes[] = {
> > .width = 1940,
> > .height = 1096,
> > .fll_def = 1306,
> > - .fll_min = 1306,
> > .llp = 3672,
> > .reg_list = {
> > .num_of_regs = ARRAY_SIZE(mode_1940x1096_regs),
> > @@ -424,7 +421,6 @@ static const struct imx355_mode supported_modes[] = {
> > .width = 1936,
> > .height = 1096,
> > .fll_def = 1306,
> > - .fll_min = 1306,
> > .llp = 3672,
> > .reg_list = {
> > .num_of_regs = ARRAY_SIZE(mode_1936x1096_regs),
> > @@ -440,7 +436,6 @@ static const struct imx355_mode supported_modes[] = {
> > .width = 1924,
> > .height = 1080,
> > .fll_def = 1306,
> > - .fll_min = 1306,
> > .llp = 3672,
> > .reg_list = {
> > .num_of_regs = ARRAY_SIZE(mode_1924x1080_regs),
> > @@ -456,7 +451,6 @@ static const struct imx355_mode supported_modes[] = {
> > .width = 1920,
> > .height = 1080,
> > .fll_def = 1306,
> > - .fll_min = 1306,
> > .llp = 3672,
> > .reg_list = {
> > .num_of_regs = ARRAY_SIZE(mode_1920x1080_regs),
> > @@ -472,7 +466,6 @@ static const struct imx355_mode supported_modes[] = {
> > .width = 1640,
> > .height = 1232,
> > .fll_def = 1306,
> > - .fll_min = 1306,
> > .llp = 1836,
> > .reg_list = {
> > .num_of_regs = ARRAY_SIZE(mode_1640x1232_regs),
> > @@ -488,7 +481,6 @@ static const struct imx355_mode supported_modes[] = {
> > .width = 1640,
> > .height = 922,
> > .fll_def = 1306,
> > - .fll_min = 1306,
> > .llp = 1836,
> > .reg_list = {
> > .num_of_regs = ARRAY_SIZE(mode_1640x922_regs),
> > @@ -504,7 +496,6 @@ static const struct imx355_mode supported_modes[] = {
> > .width = 1300,
> > .height = 736,
> > .fll_def = 1306,
> > - .fll_min = 1306,
> > .llp = 1836,
> > .reg_list = {
> > .num_of_regs = ARRAY_SIZE(mode_1300x736_regs),
> > @@ -520,7 +511,6 @@ static const struct imx355_mode supported_modes[] = {
> > .width = 1296,
> > .height = 736,
> > .fll_def = 1306,
> > - .fll_min = 1306,
> > .llp = 1836,
> > .reg_list = {
> > .num_of_regs = ARRAY_SIZE(mode_1296x736_regs),
> > @@ -536,7 +526,6 @@ static const struct imx355_mode supported_modes[] = {
> > .width = 1284,
> > .height = 720,
> > .fll_def = 1306,
> > - .fll_min = 1306,
> > .llp = 1836,
> > .reg_list = {
> > .num_of_regs = ARRAY_SIZE(mode_1284x720_regs),
> > @@ -552,7 +541,6 @@ static const struct imx355_mode supported_modes[] = {
> > .width = 1280,
> > .height = 720,
> > .fll_def = 1306,
> > - .fll_min = 1306,
> > .llp = 1836,
> > .reg_list = {
> > .num_of_regs = ARRAY_SIZE(mode_1280x720_regs),
> > @@ -568,7 +556,6 @@ static const struct imx355_mode supported_modes[] = {
> > .width = 820,
> > .height = 616,
> > .fll_def = 652,
> > - .fll_min = 652,
> > .llp = 3672,
> > .reg_list = {
> > .num_of_regs = ARRAY_SIZE(mode_820x616_regs),
> > @@ -857,7 +844,6 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
> > const struct imx355_mode *mode;
> > struct v4l2_mbus_framefmt *framefmt;
> > s32 vblank_def;
> > - s32 vblank_min;
> > s64 h_blank;
> > u32 height;
> >
> > @@ -882,10 +868,9 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
> > /* Update limits and set FPS to default */
> > height = imx355->cur_mode->height;
> > vblank_def = imx355->cur_mode->fll_def - height;
> > - vblank_min = imx355->cur_mode->fll_min - height;
> > height = IMX355_FLL_MAX - height;
>
> re-using 'height' here is not nice, but I understand it was there
> already
>
> > - __v4l2_ctrl_modify_range(imx355->vblank, vblank_min, height, 1,
> > - vblank_def);
> > + __v4l2_ctrl_modify_range(imx355->vblank, IMX355_FLL_OFFSET,
> > + height, 1, vblank_def);
> > __v4l2_ctrl_s_ctrl(imx355->vblank, vblank_def);
> > h_blank = mode->llp - imx355->cur_mode->width;
> > /*
> > @@ -1146,7 +1131,6 @@ static int imx355_init_controls(struct imx355 *imx355)
> > struct v4l2_ctrl_handler *ctrl_hdlr;
> > s64 exposure_max;
> > s64 vblank_def;
> > - s64 vblank_min;
> > s64 hblank;
> > u64 pixel_rate;
> > const struct imx355_mode *mode;
> > @@ -1176,9 +1160,8 @@ static int imx355_init_controls(struct imx355 *imx355)
> > /* Initialize vblank/hblank/exposure parameters based on current mode */
> > mode = imx355->cur_mode;
> > vblank_def = mode->fll_def - mode->height;
> > - vblank_min = mode->fll_min - mode->height;
> > imx355->vblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
> > - V4L2_CID_VBLANK, vblank_min,
> > + V4L2_CID_VBLANK, IMX355_FLL_OFFSET,
> > IMX355_FLL_MAX - mode->height,
> > 1, vblank_def);
> >
> >
> > --
> > 2.34.1
> >
> >
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH 10/13] media: imx355: Add support for get_selection
2026-05-06 18:23 [PATCH 00/13] media/imx355: General code cleanups, and adding support for 2 lane operation Dave Stevenson
` (8 preceding siblings ...)
2026-05-06 18:23 ` [PATCH 09/13] media: imx355: Remove redundant fll_min, and implement fixed offset Dave Stevenson
@ 2026-05-06 18:23 ` Dave Stevenson
2026-05-07 14:42 ` Jacopo Mondi
2026-05-06 18:23 ` [PATCH 11/13] media: imx355: Use pm_runtime autosuspend_delay Dave Stevenson
` (2 subsequent siblings)
12 siblings, 1 reply; 29+ messages in thread
From: Dave Stevenson @ 2026-05-06 18:23 UTC (permalink / raw)
To: Tianshu Qiu, Sakari Ailus, Mauro Carvalho Chehab
Cc: linux-media, linux-kernel, David Heidelberg,
20260414-imx355-24mhz-v1-1-9ae77bc6e7ec, Dave Stevenson
Provide all the cropping information via get_selection.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/media/i2c/imx355.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
index 5a3bfcd0f51c..d8d7cc0ceab9 100644
--- a/drivers/media/i2c/imx355.c
+++ b/drivers/media/i2c/imx355.c
@@ -88,6 +88,11 @@
/* number of data lanes */
#define IMX355_DATA_LANES 4
+#define IMX355_PIXEL_ARRAY_TOP 0
+#define IMX355_PIXEL_ARRAY_LEFT 0
+#define IMX355_PIXEL_ARRAY_WIDTH 3280
+#define IMX355_PIXEL_ARRAY_HEIGHT 2464
+
struct imx355_reg {
u16 address;
u8 val;
@@ -671,6 +676,7 @@ static int imx355_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
struct imx355 *imx355 = to_imx355(sd);
struct v4l2_mbus_framefmt *try_fmt =
v4l2_subdev_state_get_format(fh->state, 0);
+ struct v4l2_rect *crop = v4l2_subdev_state_get_crop(fh->state, 0);
mutex_lock(&imx355->mutex);
@@ -680,6 +686,11 @@ static int imx355_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
try_fmt->code = imx355_get_format_code(imx355);
try_fmt->field = V4L2_FIELD_NONE;
+ crop->left = imx355->cur_mode->x_add_start;
+ crop->top = imx355->cur_mode->y_add_start;
+ crop->width = imx355->cur_mode->width;
+ crop->height = imx355->cur_mode->height;
+
mutex_unlock(&imx355->mutex);
return 0;
@@ -886,6 +897,52 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
return 0;
}
+static void
+__imx355_get_pad_crop(struct imx355 *imx355,
+ struct v4l2_subdev_state *sd_state, unsigned int pad,
+ enum v4l2_subdev_format_whence which, struct v4l2_rect *r)
+{
+ switch (which) {
+ case V4L2_SUBDEV_FORMAT_TRY:
+ *r = *v4l2_subdev_state_get_crop(sd_state, pad);
+ break;
+ case V4L2_SUBDEV_FORMAT_ACTIVE:
+ r->left = imx355->cur_mode->x_add_start;
+ r->top = imx355->cur_mode->y_add_start;
+ r->width = imx355->cur_mode->width;
+ r->height = imx355->cur_mode->height;
+ break;
+ }
+}
+
+static int imx355_get_selection(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *sd_state,
+ struct v4l2_subdev_selection *sel)
+{
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP:
+ struct imx355 *imx355 = to_imx355(sd);
+
+ mutex_lock(&imx355->mutex);
+ __imx355_get_pad_crop(imx355, sd_state, sel->pad, sel->which,
+ &sel->r);
+ mutex_unlock(&imx355->mutex);
+
+ return 0;
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ case V4L2_SEL_TGT_NATIVE_SIZE:
+ sel->r.top = IMX355_PIXEL_ARRAY_TOP;
+ sel->r.left = IMX355_PIXEL_ARRAY_LEFT;
+ sel->r.width = IMX355_PIXEL_ARRAY_WIDTH;
+ sel->r.height = IMX355_PIXEL_ARRAY_HEIGHT;
+
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
/* Start streaming */
static int imx355_start_streaming(struct imx355 *imx355)
{
@@ -1062,6 +1119,7 @@ static const struct v4l2_subdev_pad_ops imx355_pad_ops = {
.get_fmt = imx355_get_pad_format,
.set_fmt = imx355_set_pad_format,
.enum_frame_size = imx355_enum_frame_size,
+ .get_selection = imx355_get_selection,
};
static const struct v4l2_subdev_ops imx355_subdev_ops = {
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread* Re: [PATCH 10/13] media: imx355: Add support for get_selection
2026-05-06 18:23 ` [PATCH 10/13] media: imx355: Add support for get_selection Dave Stevenson
@ 2026-05-07 14:42 ` Jacopo Mondi
2026-05-07 15:02 ` Dave Stevenson
0 siblings, 1 reply; 29+ messages in thread
From: Jacopo Mondi @ 2026-05-07 14:42 UTC (permalink / raw)
To: Dave Stevenson
Cc: Tianshu Qiu, Sakari Ailus, Mauro Carvalho Chehab, linux-media,
linux-kernel, David Heidelberg,
20260414-imx355-24mhz-v1-1-9ae77bc6e7ec
On Wed, May 06, 2026 at 07:23:48PM +0100, Dave Stevenson wrote:
> Provide all the cropping information via get_selection.
I think this could be simplified if the driver is ported to use the
active state.
See df3ef05b51e02ef9386346288c1e63f366372f5b
I'm afraid usage of the active state is warmly suggested nowadays,
especially if you're adding code that has to deal with ACTIVE/TRY or
initializes per-fh data in open().
Is it too much yak shaving to ask ?
>
> Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
> ---
> drivers/media/i2c/imx355.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 58 insertions(+)
>
> diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
> index 5a3bfcd0f51c..d8d7cc0ceab9 100644
> --- a/drivers/media/i2c/imx355.c
> +++ b/drivers/media/i2c/imx355.c
> @@ -88,6 +88,11 @@
> /* number of data lanes */
> #define IMX355_DATA_LANES 4
>
> +#define IMX355_PIXEL_ARRAY_TOP 0
> +#define IMX355_PIXEL_ARRAY_LEFT 0
> +#define IMX355_PIXEL_ARRAY_WIDTH 3280
> +#define IMX355_PIXEL_ARRAY_HEIGHT 2464
> +
> struct imx355_reg {
> u16 address;
> u8 val;
> @@ -671,6 +676,7 @@ static int imx355_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
> struct imx355 *imx355 = to_imx355(sd);
> struct v4l2_mbus_framefmt *try_fmt =
> v4l2_subdev_state_get_format(fh->state, 0);
> + struct v4l2_rect *crop = v4l2_subdev_state_get_crop(fh->state, 0);
>
> mutex_lock(&imx355->mutex);
>
> @@ -680,6 +686,11 @@ static int imx355_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
> try_fmt->code = imx355_get_format_code(imx355);
> try_fmt->field = V4L2_FIELD_NONE;
>
> + crop->left = imx355->cur_mode->x_add_start;
> + crop->top = imx355->cur_mode->y_add_start;
> + crop->width = imx355->cur_mode->width;
> + crop->height = imx355->cur_mode->height;
> +
> mutex_unlock(&imx355->mutex);
>
> return 0;
> @@ -886,6 +897,52 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
> return 0;
> }
>
> +static void
> +__imx355_get_pad_crop(struct imx355 *imx355,
> + struct v4l2_subdev_state *sd_state, unsigned int pad,
> + enum v4l2_subdev_format_whence which, struct v4l2_rect *r)
> +{
> + switch (which) {
> + case V4L2_SUBDEV_FORMAT_TRY:
> + *r = *v4l2_subdev_state_get_crop(sd_state, pad);
> + break;
> + case V4L2_SUBDEV_FORMAT_ACTIVE:
> + r->left = imx355->cur_mode->x_add_start;
> + r->top = imx355->cur_mode->y_add_start;
> + r->width = imx355->cur_mode->width;
> + r->height = imx355->cur_mode->height;
> + break;
> + }
> +}
> +
> +static int imx355_get_selection(struct v4l2_subdev *sd,
> + struct v4l2_subdev_state *sd_state,
> + struct v4l2_subdev_selection *sel)
> +{
> + switch (sel->target) {
> + case V4L2_SEL_TGT_CROP:
> + struct imx355 *imx355 = to_imx355(sd);
> +
> + mutex_lock(&imx355->mutex);
> + __imx355_get_pad_crop(imx355, sd_state, sel->pad, sel->which,
> + &sel->r);
> + mutex_unlock(&imx355->mutex);
> +
> + return 0;
> + case V4L2_SEL_TGT_CROP_DEFAULT:
> + case V4L2_SEL_TGT_CROP_BOUNDS:
> + case V4L2_SEL_TGT_NATIVE_SIZE:
> + sel->r.top = IMX355_PIXEL_ARRAY_TOP;
> + sel->r.left = IMX355_PIXEL_ARRAY_LEFT;
> + sel->r.width = IMX355_PIXEL_ARRAY_WIDTH;
> + sel->r.height = IMX355_PIXEL_ARRAY_HEIGHT;
> +
> + return 0;
> + }
> +
> + return -EINVAL;
> +}
> +
> /* Start streaming */
> static int imx355_start_streaming(struct imx355 *imx355)
> {
> @@ -1062,6 +1119,7 @@ static const struct v4l2_subdev_pad_ops imx355_pad_ops = {
> .get_fmt = imx355_get_pad_format,
> .set_fmt = imx355_set_pad_format,
> .enum_frame_size = imx355_enum_frame_size,
> + .get_selection = imx355_get_selection,
> };
>
> static const struct v4l2_subdev_ops imx355_subdev_ops = {
>
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 29+ messages in thread* Re: [PATCH 10/13] media: imx355: Add support for get_selection
2026-05-07 14:42 ` Jacopo Mondi
@ 2026-05-07 15:02 ` Dave Stevenson
0 siblings, 0 replies; 29+ messages in thread
From: Dave Stevenson @ 2026-05-07 15:02 UTC (permalink / raw)
To: Jacopo Mondi
Cc: Sakari Ailus, Mauro Carvalho Chehab, linux-media, linux-kernel,
David Heidelberg
Hi Jacopo
Thanks for all your reviews
On Thu, 7 May 2026 at 15:42, Jacopo Mondi <jacopo.mondi@ideasonboard.com> wrote:
>
> On Wed, May 06, 2026 at 07:23:48PM +0100, Dave Stevenson wrote:
> > Provide all the cropping information via get_selection.
>
> I think this could be simplified if the driver is ported to use the
> active state.
> See df3ef05b51e02ef9386346288c1e63f366372f5b
>
> I'm afraid usage of the active state is warmly suggested nowadays,
> especially if you're adding code that has to deal with ACTIVE/TRY or
> initializes per-fh data in open().
>
> Is it too much yak shaving to ask ?
As this was an existing driver and I can't test on the original
hardware, I was taking a softly softly approach to ensure nothing
broke for the existing users.
Tianshu's email address is bouncing, so I guess Sakari would be the
one to know if Intel still care about IMX355.
If Intel no longer care, then I'll see if I can find the time to swap
it to active state.
Dave
> >
> > Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
> > ---
> > drivers/media/i2c/imx355.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 58 insertions(+)
> >
> > diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
> > index 5a3bfcd0f51c..d8d7cc0ceab9 100644
> > --- a/drivers/media/i2c/imx355.c
> > +++ b/drivers/media/i2c/imx355.c
> > @@ -88,6 +88,11 @@
> > /* number of data lanes */
> > #define IMX355_DATA_LANES 4
> >
> > +#define IMX355_PIXEL_ARRAY_TOP 0
> > +#define IMX355_PIXEL_ARRAY_LEFT 0
> > +#define IMX355_PIXEL_ARRAY_WIDTH 3280
> > +#define IMX355_PIXEL_ARRAY_HEIGHT 2464
> > +
> > struct imx355_reg {
> > u16 address;
> > u8 val;
> > @@ -671,6 +676,7 @@ static int imx355_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
> > struct imx355 *imx355 = to_imx355(sd);
> > struct v4l2_mbus_framefmt *try_fmt =
> > v4l2_subdev_state_get_format(fh->state, 0);
> > + struct v4l2_rect *crop = v4l2_subdev_state_get_crop(fh->state, 0);
> >
> > mutex_lock(&imx355->mutex);
> >
> > @@ -680,6 +686,11 @@ static int imx355_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
> > try_fmt->code = imx355_get_format_code(imx355);
> > try_fmt->field = V4L2_FIELD_NONE;
> >
> > + crop->left = imx355->cur_mode->x_add_start;
> > + crop->top = imx355->cur_mode->y_add_start;
> > + crop->width = imx355->cur_mode->width;
> > + crop->height = imx355->cur_mode->height;
> > +
> > mutex_unlock(&imx355->mutex);
> >
> > return 0;
> > @@ -886,6 +897,52 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
> > return 0;
> > }
> >
> > +static void
> > +__imx355_get_pad_crop(struct imx355 *imx355,
> > + struct v4l2_subdev_state *sd_state, unsigned int pad,
> > + enum v4l2_subdev_format_whence which, struct v4l2_rect *r)
> > +{
> > + switch (which) {
> > + case V4L2_SUBDEV_FORMAT_TRY:
> > + *r = *v4l2_subdev_state_get_crop(sd_state, pad);
> > + break;
> > + case V4L2_SUBDEV_FORMAT_ACTIVE:
> > + r->left = imx355->cur_mode->x_add_start;
> > + r->top = imx355->cur_mode->y_add_start;
> > + r->width = imx355->cur_mode->width;
> > + r->height = imx355->cur_mode->height;
> > + break;
> > + }
> > +}
> > +
> > +static int imx355_get_selection(struct v4l2_subdev *sd,
> > + struct v4l2_subdev_state *sd_state,
> > + struct v4l2_subdev_selection *sel)
> > +{
> > + switch (sel->target) {
> > + case V4L2_SEL_TGT_CROP:
> > + struct imx355 *imx355 = to_imx355(sd);
> > +
> > + mutex_lock(&imx355->mutex);
> > + __imx355_get_pad_crop(imx355, sd_state, sel->pad, sel->which,
> > + &sel->r);
> > + mutex_unlock(&imx355->mutex);
> > +
> > + return 0;
> > + case V4L2_SEL_TGT_CROP_DEFAULT:
> > + case V4L2_SEL_TGT_CROP_BOUNDS:
> > + case V4L2_SEL_TGT_NATIVE_SIZE:
> > + sel->r.top = IMX355_PIXEL_ARRAY_TOP;
> > + sel->r.left = IMX355_PIXEL_ARRAY_LEFT;
> > + sel->r.width = IMX355_PIXEL_ARRAY_WIDTH;
> > + sel->r.height = IMX355_PIXEL_ARRAY_HEIGHT;
> > +
> > + return 0;
> > + }
> > +
> > + return -EINVAL;
> > +}
> > +
> > /* Start streaming */
> > static int imx355_start_streaming(struct imx355 *imx355)
> > {
> > @@ -1062,6 +1119,7 @@ static const struct v4l2_subdev_pad_ops imx355_pad_ops = {
> > .get_fmt = imx355_get_pad_format,
> > .set_fmt = imx355_set_pad_format,
> > .enum_frame_size = imx355_enum_frame_size,
> > + .get_selection = imx355_get_selection,
> > };
> >
> > static const struct v4l2_subdev_ops imx355_subdev_ops = {
> >
> > --
> > 2.34.1
> >
> >
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH 11/13] media: imx355: Use pm_runtime autosuspend_delay
2026-05-06 18:23 [PATCH 00/13] media/imx355: General code cleanups, and adding support for 2 lane operation Dave Stevenson
` (9 preceding siblings ...)
2026-05-06 18:23 ` [PATCH 10/13] media: imx355: Add support for get_selection Dave Stevenson
@ 2026-05-06 18:23 ` Dave Stevenson
2026-05-07 14:43 ` Jacopo Mondi
2026-05-06 18:23 ` [PATCH 12/13] media: imx355: Convert to new CCI register access helpers Dave Stevenson
2026-05-06 18:23 ` [PATCH 13/13] media: imx355: Support 2 lane readout Dave Stevenson
12 siblings, 1 reply; 29+ messages in thread
From: Dave Stevenson @ 2026-05-06 18:23 UTC (permalink / raw)
To: Tianshu Qiu, Sakari Ailus, Mauro Carvalho Chehab
Cc: linux-media, linux-kernel, David Heidelberg,
20260414-imx355-24mhz-v1-1-9ae77bc6e7ec, Dave Stevenson
Avoid powering the sensor up and down unnecessarily by using
pm_runtime's autosuspend_delay feature.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/media/i2c/imx355.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
index d8d7cc0ceab9..c6fcd649c32a 100644
--- a/drivers/media/i2c/imx355.c
+++ b/drivers/media/i2c/imx355.c
@@ -1068,7 +1068,7 @@ static int imx355_set_stream(struct v4l2_subdev *sd, int enable)
goto err_rpm_put;
} else {
imx355_stop_streaming(imx355);
- pm_runtime_put(imx355->dev);
+ pm_runtime_put_autosuspend(imx355->dev);
}
/* vflip and hflip cannot change during streaming */
@@ -1080,7 +1080,7 @@ static int imx355_set_stream(struct v4l2_subdev *sd, int enable)
return ret;
err_rpm_put:
- pm_runtime_put(imx355->dev);
+ pm_runtime_put_autosuspend(imx355->dev);
err_unlock:
mutex_unlock(&imx355->mutex);
@@ -1431,6 +1431,8 @@ static int imx355_probe(struct i2c_client *client)
pm_runtime_set_active(imx355->dev);
pm_runtime_enable(imx355->dev);
pm_runtime_idle(imx355->dev);
+ pm_runtime_set_autosuspend_delay(imx355->dev, 1000);
+ pm_runtime_use_autosuspend(imx355->dev);
ret = v4l2_async_register_subdev_sensor(&imx355->sd);
if (ret < 0)
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread* Re: [PATCH 11/13] media: imx355: Use pm_runtime autosuspend_delay
2026-05-06 18:23 ` [PATCH 11/13] media: imx355: Use pm_runtime autosuspend_delay Dave Stevenson
@ 2026-05-07 14:43 ` Jacopo Mondi
0 siblings, 0 replies; 29+ messages in thread
From: Jacopo Mondi @ 2026-05-07 14:43 UTC (permalink / raw)
To: Dave Stevenson
Cc: Tianshu Qiu, Sakari Ailus, Mauro Carvalho Chehab, linux-media,
linux-kernel, David Heidelberg,
20260414-imx355-24mhz-v1-1-9ae77bc6e7ec
Hi Dave
On Wed, May 06, 2026 at 07:23:49PM +0100, Dave Stevenson wrote:
> Avoid powering the sensor up and down unnecessarily by using
> pm_runtime's autosuspend_delay feature.
>
> Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
> ---
> drivers/media/i2c/imx355.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
> index d8d7cc0ceab9..c6fcd649c32a 100644
> --- a/drivers/media/i2c/imx355.c
> +++ b/drivers/media/i2c/imx355.c
> @@ -1068,7 +1068,7 @@ static int imx355_set_stream(struct v4l2_subdev *sd, int enable)
> goto err_rpm_put;
> } else {
> imx355_stop_streaming(imx355);
> - pm_runtime_put(imx355->dev);
> + pm_runtime_put_autosuspend(imx355->dev);
> }
>
> /* vflip and hflip cannot change during streaming */
> @@ -1080,7 +1080,7 @@ static int imx355_set_stream(struct v4l2_subdev *sd, int enable)
> return ret;
>
> err_rpm_put:
> - pm_runtime_put(imx355->dev);
> + pm_runtime_put_autosuspend(imx355->dev);
> err_unlock:
> mutex_unlock(&imx355->mutex);
>
> @@ -1431,6 +1431,8 @@ static int imx355_probe(struct i2c_client *client)
> pm_runtime_set_active(imx355->dev);
> pm_runtime_enable(imx355->dev);
> pm_runtime_idle(imx355->dev);
> + pm_runtime_set_autosuspend_delay(imx355->dev, 1000);
> + pm_runtime_use_autosuspend(imx355->dev);
>
> ret = v4l2_async_register_subdev_sensor(&imx355->sd);
> if (ret < 0)
>
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH 12/13] media: imx355: Convert to new CCI register access helpers
2026-05-06 18:23 [PATCH 00/13] media/imx355: General code cleanups, and adding support for 2 lane operation Dave Stevenson
` (10 preceding siblings ...)
2026-05-06 18:23 ` [PATCH 11/13] media: imx355: Use pm_runtime autosuspend_delay Dave Stevenson
@ 2026-05-06 18:23 ` Dave Stevenson
2026-05-07 14:49 ` Jacopo Mondi
2026-05-06 18:23 ` [PATCH 13/13] media: imx355: Support 2 lane readout Dave Stevenson
12 siblings, 1 reply; 29+ messages in thread
From: Dave Stevenson @ 2026-05-06 18:23 UTC (permalink / raw)
To: Tianshu Qiu, Sakari Ailus, Mauro Carvalho Chehab
Cc: linux-media, linux-kernel, David Heidelberg,
20260414-imx355-24mhz-v1-1-9ae77bc6e7ec, Dave Stevenson
Use the new comon CCI register access helpers to replace the private
register access helpers in the imx355 driver.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/media/i2c/Kconfig | 1 +
drivers/media/i2c/imx355.c | 502 ++++++++++++++++++---------------------------
2 files changed, 196 insertions(+), 307 deletions(-)
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
index 8f2ba4121586..38f23306722c 100644
--- a/drivers/media/i2c/Kconfig
+++ b/drivers/media/i2c/Kconfig
@@ -259,6 +259,7 @@ config VIDEO_IMX335
config VIDEO_IMX355
tristate "Sony IMX355 sensor support"
+ select V4L2_CCI_I2C
help
This is a Video4Linux2 sensor driver for the Sony
IMX355 camera.
diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
index c6fcd649c32a..d0e0e81d1e7c 100644
--- a/drivers/media/i2c/imx355.c
+++ b/drivers/media/i2c/imx355.c
@@ -9,78 +9,80 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/unaligned.h>
+#include <media/v4l2-cci.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-event.h>
#include <media/v4l2-fwnode.h>
-#define IMX355_REG_MODE_SELECT 0x0100
+#define IMX355_REG_MODE_SELECT CCI_REG8(0x0100)
#define IMX355_MODE_STANDBY 0x00
#define IMX355_MODE_STREAMING 0x01
/* Chip ID */
-#define IMX355_REG_CHIP_ID 0x0016
+#define IMX355_REG_CHIP_ID CCI_REG16(0x0016)
#define IMX355_CHIP_ID 0x0355
/* PLL registers that depend on the external clock frequency */
-#define IMX355_REG_EXTCLK_FREQ 0x0136
-#define IMX355_REG_PLL_VT_MUL 0x0306
-#define IMX355_REG_PLL_OP_MUL 0x030e
+#define IMX355_REG_EXTCLK_FREQ CCI_REG16(0x0136)
+#define IMX355_REG_PLL_VT_MUL CCI_REG16(0x0306)
+#define IMX355_REG_PLL_OP_MUL CCI_REG16(0x030e)
/* V_TIMING internal */
-#define IMX355_REG_FLL 0x0340
+#define IMX355_REG_FLL CCI_REG16(0x0340)
#define IMX355_FLL_MAX 0xffff
/* Number of lines above frame height that are required. */
#define IMX355_FLL_OFFSET 20
-#define IMX355_REG_LLP 0x0342
+#define IMX355_REG_LLP CCI_REG16(0x0342)
#define IMX355_LLP_MAX 0xffff
-#define IMX355_REG_X_ADD_START 0x0344
-#define IMX355_REG_Y_ADD_START 0x0346
-#define IMX355_REG_X_ADD_END 0x0348
-#define IMX355_REG_Y_ADD_END 0x034a
-#define IMX355_REG_X_OUT_SIZE 0x034c
-#define IMX355_REG_Y_OUT_SIZE 0x034e
+#define IMX355_REG_X_ADD_START CCI_REG16(0x0344)
+#define IMX355_REG_Y_ADD_START CCI_REG16(0x0346)
+#define IMX355_REG_X_ADD_END CCI_REG16(0x0348)
+#define IMX355_REG_Y_ADD_END CCI_REG16(0x034a)
+#define IMX355_REG_X_OUT_SIZE CCI_REG16(0x034c)
+#define IMX355_REG_Y_OUT_SIZE CCI_REG16(0x034e)
/* Exposure control */
-#define IMX355_REG_EXPOSURE 0x0202
+#define IMX355_REG_EXPOSURE CCI_REG16(0x0202)
#define IMX355_EXPOSURE_MIN 1
#define IMX355_EXPOSURE_STEP 1
#define IMX355_EXPOSURE_DEFAULT 0x0282
/* Analog gain control */
-#define IMX355_REG_ANALOG_GAIN 0x0204
+#define IMX355_REG_ANALOG_GAIN CCI_REG16(0x0204)
#define IMX355_ANA_GAIN_MIN 0
#define IMX355_ANA_GAIN_MAX 960
#define IMX355_ANA_GAIN_STEP 1
#define IMX355_ANA_GAIN_DEFAULT 0
/* Digital gain control */
-#define IMX355_REG_DPGA_USE_GLOBAL_GAIN 0x3070
-#define IMX355_REG_DIG_GAIN_GLOBAL 0x020e
+#define IMX355_REG_DPGA_USE_GLOBAL_GAIN CCI_REG8(0x3070)
+#define IMX355_REG_DIG_GAIN_GLOBAL CCI_REG16(0x020e)
#define IMX355_DGTL_GAIN_MIN 256
#define IMX355_DGTL_GAIN_MAX 4095
#define IMX355_DGTL_GAIN_STEP 1
#define IMX355_DGTL_GAIN_DEFAULT 256
/* Test Pattern Control */
-#define IMX355_REG_TEST_PATTERN 0x0600
+#define IMX355_REG_TEST_PATTERN CCI_REG8(0x0600)
#define IMX355_TEST_PATTERN_DISABLED 0
#define IMX355_TEST_PATTERN_SOLID_COLOR 1
#define IMX355_TEST_PATTERN_COLOR_BARS 2
#define IMX355_TEST_PATTERN_GRAY_COLOR_BARS 3
#define IMX355_TEST_PATTERN_PN9 4
-#define IMX355_REG_BINNING_MODE 0x0900
-#define IMX355_REG_BINNING_TYPE 0x0901
-#define IMX355_REG_BINNING_WEIGHTING 0x0902
+#define IMX355_REG_BINNING_MODE CCI_REG8(0x0900)
+#define IMX355_REG_BINNING_TYPE CCI_REG8(0x0901)
+#define IMX355_REG_BINNING_WEIGHTING CCI_REG8(0x0902)
/* Flip Control */
-#define IMX355_REG_ORIENTATION 0x0101
+#define IMX355_REG_ORIENTATION CCI_REG8(0x0101)
/* default link frequency and external clock */
#define IMX355_LINK_FREQ_DEFAULT 360000000LL
@@ -93,14 +95,9 @@
#define IMX355_PIXEL_ARRAY_WIDTH 3280
#define IMX355_PIXEL_ARRAY_HEIGHT 2464
-struct imx355_reg {
- u16 address;
- u8 val;
-};
-
struct imx355_reg_list {
u32 num_of_regs;
- const struct imx355_reg *regs;
+ const struct cci_reg_sequence *regs;
};
/* Mode : resolution and related config&values */
@@ -160,6 +157,7 @@ struct imx355_hwcfg {
struct imx355 {
struct device *dev;
struct clk *clk;
+ struct regmap *regmap;
struct v4l2_subdev sd;
struct media_pad pad;
@@ -196,152 +194,147 @@ static const struct regulator_bulk_data imx355_supplies[] = {
{ .supply = "dovdd" },
};
-static const struct imx355_reg imx355_global_regs[] = {
- { 0x304e, 0x03 },
- { 0x4348, 0x16 },
- { 0x4350, 0x19 },
- { 0x4408, 0x0a },
- { 0x440c, 0x0b },
- { 0x4411, 0x5f },
- { 0x4412, 0x2c },
- { 0x4623, 0x00 },
- { 0x462c, 0x0f },
- { 0x462d, 0x00 },
- { 0x462e, 0x00 },
- { 0x4684, 0x54 },
- { 0x480a, 0x07 },
- { 0x4908, 0x07 },
- { 0x4909, 0x07 },
- { 0x490d, 0x0a },
- { 0x491e, 0x0f },
- { 0x4921, 0x06 },
- { 0x4923, 0x28 },
- { 0x4924, 0x28 },
- { 0x4925, 0x29 },
- { 0x4926, 0x29 },
- { 0x4927, 0x1f },
- { 0x4928, 0x20 },
- { 0x4929, 0x20 },
- { 0x492a, 0x20 },
- { 0x492c, 0x05 },
- { 0x492d, 0x06 },
- { 0x492e, 0x06 },
- { 0x492f, 0x06 },
- { 0x4930, 0x03 },
- { 0x4931, 0x04 },
- { 0x4932, 0x04 },
- { 0x4933, 0x05 },
- { 0x595e, 0x01 },
- { 0x5963, 0x01 },
- { 0x3030, 0x01 },
- { 0x3031, 0x01 },
- { 0x3045, 0x01 },
- { 0x4010, 0x00 },
- { 0x4011, 0x00 },
- { 0x4012, 0x00 },
- { 0x4013, 0x01 },
- { 0x68a8, 0xfe },
- { 0x68a9, 0xff },
- { 0x6888, 0x00 },
- { 0x6889, 0x00 },
- { 0x68b0, 0x00 },
- { 0x3058, 0x00 },
- { 0x305a, 0x00 },
- { 0x0112, 0x0a },
- { 0x0113, 0x0a },
- { 0x0114, 0x03 },
- { 0x0301, 0x05 },
- { 0x0303, 0x01 },
- { 0x0305, 0x02 },
- { 0x030d, 0x02 },
- { 0x0310, 0x00 },
- { 0x0220, 0x00 },
- { 0x0222, 0x01 },
- { 0x0820, 0x0b },
- { 0x0821, 0x40 },
- { 0x3088, 0x04 },
- { 0x6813, 0x02 },
- { 0x6835, 0x07 },
- { 0x6836, 0x01 },
- { 0x6837, 0x04 },
- { 0x684d, 0x07 },
- { 0x684e, 0x01 },
- { 0x684f, 0x04 },
+static const struct cci_reg_sequence imx355_global_regs[] = {
+ { CCI_REG8(0x304e), 0x03 },
+ { CCI_REG8(0x4348), 0x16 },
+ { CCI_REG8(0x4350), 0x19 },
+ { CCI_REG8(0x4408), 0x0a },
+ { CCI_REG8(0x440c), 0x0b },
+ { CCI_REG8(0x4411), 0x5f },
+ { CCI_REG8(0x4412), 0x2c },
+ { CCI_REG8(0x4623), 0x00 },
+ { CCI_REG8(0x462c), 0x0f },
+ { CCI_REG8(0x462d), 0x00 },
+ { CCI_REG8(0x462e), 0x00 },
+ { CCI_REG8(0x4684), 0x54 },
+ { CCI_REG8(0x480a), 0x07 },
+ { CCI_REG8(0x4908), 0x07 },
+ { CCI_REG8(0x4909), 0x07 },
+ { CCI_REG8(0x490d), 0x0a },
+ { CCI_REG8(0x491e), 0x0f },
+ { CCI_REG8(0x4921), 0x06 },
+ { CCI_REG8(0x4923), 0x28 },
+ { CCI_REG8(0x4924), 0x28 },
+ { CCI_REG8(0x4925), 0x29 },
+ { CCI_REG8(0x4926), 0x29 },
+ { CCI_REG8(0x4927), 0x1f },
+ { CCI_REG8(0x4928), 0x20 },
+ { CCI_REG8(0x4929), 0x20 },
+ { CCI_REG8(0x492a), 0x20 },
+ { CCI_REG8(0x492c), 0x05 },
+ { CCI_REG8(0x492d), 0x06 },
+ { CCI_REG8(0x492e), 0x06 },
+ { CCI_REG8(0x492f), 0x06 },
+ { CCI_REG8(0x4930), 0x03 },
+ { CCI_REG8(0x4931), 0x04 },
+ { CCI_REG8(0x4932), 0x04 },
+ { CCI_REG8(0x4933), 0x05 },
+ { CCI_REG8(0x595e), 0x01 },
+ { CCI_REG8(0x5963), 0x01 },
+ { CCI_REG8(0x3030), 0x01 },
+ { CCI_REG8(0x3031), 0x01 },
+ { CCI_REG8(0x3045), 0x01 },
+ { CCI_REG8(0x4010), 0x00 },
+ { CCI_REG8(0x4011), 0x00 },
+ { CCI_REG8(0x4012), 0x00 },
+ { CCI_REG8(0x4013), 0x01 },
+ { CCI_REG8(0x68a8), 0xfe },
+ { CCI_REG8(0x68a9), 0xff },
+ { CCI_REG8(0x6888), 0x00 },
+ { CCI_REG8(0x6889), 0x00 },
+ { CCI_REG8(0x68b0), 0x00 },
+ { CCI_REG8(0x3058), 0x00 },
+ { CCI_REG8(0x305a), 0x00 },
+ { CCI_REG8(0x0112), 0x0a },
+ { CCI_REG8(0x0113), 0x0a },
+ { CCI_REG8(0x0114), 0x03 },
+ { CCI_REG8(0x0301), 0x05 },
+ { CCI_REG8(0x0303), 0x01 },
+ { CCI_REG8(0x0305), 0x02 },
+ { CCI_REG8(0x030d), 0x02 },
+ { CCI_REG8(0x0310), 0x00 },
+ { CCI_REG8(0x0220), 0x00 },
+ { CCI_REG8(0x0222), 0x01 },
+ { CCI_REG8(0x0820), 0x0b },
+ { CCI_REG8(0x0821), 0x40 },
+ { CCI_REG8(0x3088), 0x04 },
+ { CCI_REG8(0x6813), 0x02 },
+ { CCI_REG8(0x6835), 0x07 },
+ { CCI_REG8(0x6836), 0x01 },
+ { CCI_REG8(0x6837), 0x04 },
+ { CCI_REG8(0x684d), 0x07 },
+ { CCI_REG8(0x684e), 0x01 },
+ { CCI_REG8(0x684f), 0x04 },
};
-static const struct imx355_reg_list imx355_global_setting = {
- .num_of_regs = ARRAY_SIZE(imx355_global_regs),
- .regs = imx355_global_regs,
+static const struct cci_reg_sequence mode_3268x2448_regs[] = {
+ { CCI_REG8(0x0700), 0x00 },
+ { CCI_REG8(0x0701), 0x10 },
};
-static const struct imx355_reg mode_3268x2448_regs[] = {
- { 0x0700, 0x00 },
- { 0x0701, 0x10 },
+static const struct cci_reg_sequence mode_3264x2448_regs[] = {
+ { CCI_REG8(0x0700), 0x00 },
+ { CCI_REG8(0x0701), 0x10 },
};
-static const struct imx355_reg mode_3264x2448_regs[] = {
- { 0x0700, 0x00 },
- { 0x0701, 0x10 },
+static const struct cci_reg_sequence mode_3280x2464_regs[] = {
+ { CCI_REG8(0x0700), 0x00 },
+ { CCI_REG8(0x0701), 0x10 },
};
-static const struct imx355_reg mode_3280x2464_regs[] = {
- { 0x0700, 0x00 },
- { 0x0701, 0x10 },
+static const struct cci_reg_sequence mode_1940x1096_regs[] = {
+ { CCI_REG8(0x0700), 0x00 },
+ { CCI_REG8(0x0701), 0x10 },
};
-static const struct imx355_reg mode_1940x1096_regs[] = {
- { 0x0700, 0x00 },
- { 0x0701, 0x10 },
+static const struct cci_reg_sequence mode_1936x1096_regs[] = {
+ { CCI_REG8(0x0700), 0x00 },
+ { CCI_REG8(0x0701), 0x10 },
};
-static const struct imx355_reg mode_1936x1096_regs[] = {
- { 0x0700, 0x00 },
- { 0x0701, 0x10 },
+static const struct cci_reg_sequence mode_1924x1080_regs[] = {
+ { CCI_REG8(0x0700), 0x00 },
+ { CCI_REG8(0x0701), 0x10 },
};
-static const struct imx355_reg mode_1924x1080_regs[] = {
- { 0x0700, 0x00 },
- { 0x0701, 0x10 },
+static const struct cci_reg_sequence mode_1920x1080_regs[] = {
+ { CCI_REG8(0x0700), 0x00 },
+ { CCI_REG8(0x0701), 0x10 },
};
-static const struct imx355_reg mode_1920x1080_regs[] = {
- { 0x0700, 0x00 },
- { 0x0701, 0x10 },
+static const struct cci_reg_sequence mode_1640x1232_regs[] = {
+ { CCI_REG8(0x0700), 0x00 },
+ { CCI_REG8(0x0701), 0x10 },
};
-static const struct imx355_reg mode_1640x1232_regs[] = {
- { 0x0700, 0x00 },
- { 0x0701, 0x10 },
+static const struct cci_reg_sequence mode_1640x922_regs[] = {
+ { CCI_REG8(0x0700), 0x00 },
+ { CCI_REG8(0x0701), 0x10 },
};
-static const struct imx355_reg mode_1640x922_regs[] = {
- { 0x0700, 0x00 },
- { 0x0701, 0x10 },
+static const struct cci_reg_sequence mode_1300x736_regs[] = {
+ { CCI_REG8(0x0700), 0x00 },
+ { CCI_REG8(0x0701), 0x10 },
};
-static const struct imx355_reg mode_1300x736_regs[] = {
- { 0x0700, 0x00 },
- { 0x0701, 0x10 },
+static const struct cci_reg_sequence mode_1296x736_regs[] = {
+ { CCI_REG8(0x0700), 0x00 },
+ { CCI_REG8(0x0701), 0x10 },
};
-static const struct imx355_reg mode_1296x736_regs[] = {
- { 0x0700, 0x00 },
- { 0x0701, 0x10 },
+static const struct cci_reg_sequence mode_1284x720_regs[] = {
+ { CCI_REG8(0x0700), 0x00 },
+ { CCI_REG8(0x0701), 0x10 },
};
-static const struct imx355_reg mode_1284x720_regs[] = {
- { 0x0700, 0x00 },
- { 0x0701, 0x10 },
+static const struct cci_reg_sequence mode_1280x720_regs[] = {
+ { CCI_REG8(0x0700), 0x00 },
+ { CCI_REG8(0x0701), 0x10 },
};
-static const struct imx355_reg mode_1280x720_regs[] = {
- { 0x0700, 0x00 },
- { 0x0701, 0x10 },
-};
-
-static const struct imx355_reg mode_820x616_regs[] = {
- { 0x0700, 0x02 },
- { 0x0701, 0x78 },
+static const struct cci_reg_sequence mode_820x616_regs[] = {
+ { CCI_REG8(0x0700), 0x02 },
+ { CCI_REG8(0x0701), 0x78 },
};
static const char * const imx355_test_pattern_menu[] = {
@@ -598,78 +591,6 @@ static u32 imx355_get_format_code(struct imx355 *imx355)
return code;
}
-/* Read registers up to 4 at a time */
-static int imx355_read_reg(struct imx355 *imx355, u16 reg, u32 len, u32 *val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
- struct i2c_msg msgs[2];
- u8 addr_buf[2];
- u8 data_buf[4] = { 0 };
- int ret;
-
- if (len > 4)
- return -EINVAL;
-
- put_unaligned_be16(reg, addr_buf);
- /* Write register address */
- msgs[0].addr = client->addr;
- msgs[0].flags = 0;
- msgs[0].len = ARRAY_SIZE(addr_buf);
- msgs[0].buf = addr_buf;
-
- /* Read data from register */
- msgs[1].addr = client->addr;
- msgs[1].flags = I2C_M_RD;
- msgs[1].len = len;
- msgs[1].buf = &data_buf[4 - len];
-
- ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
- if (ret != ARRAY_SIZE(msgs))
- return -EIO;
-
- *val = get_unaligned_be32(data_buf);
-
- return 0;
-}
-
-/* Write registers up to 4 at a time */
-static int imx355_write_reg(struct imx355 *imx355, u16 reg, u32 len, u32 val)
-{
- struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
- u8 buf[6];
-
- if (len > 4)
- return -EINVAL;
-
- put_unaligned_be16(reg, buf);
- put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
- if (i2c_master_send(client, buf, len + 2) != len + 2)
- return -EIO;
-
- return 0;
-}
-
-/* Write a list of registers */
-static int imx355_write_regs(struct imx355 *imx355,
- const struct imx355_reg *regs, u32 len)
-{
- int ret;
- u32 i;
-
- for (i = 0; i < len; i++) {
- ret = imx355_write_reg(imx355, regs[i].address, 1, regs[i].val);
- if (ret) {
- dev_err_ratelimited(imx355->dev,
- "write reg 0x%4.4x return err %d",
- regs[i].address, ret);
-
- return ret;
- }
- }
-
- return 0;
-}
-
/* Open sub-device */
static int imx355_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
@@ -724,31 +645,31 @@ static int imx355_set_ctrl(struct v4l2_ctrl *ctrl)
switch (ctrl->id) {
case V4L2_CID_ANALOGUE_GAIN:
/* Analog gain = 1024/(1024 - ctrl->val) times */
- ret = imx355_write_reg(imx355, IMX355_REG_ANALOG_GAIN, 2,
- ctrl->val);
+ ret = cci_write(imx355->regmap, IMX355_REG_ANALOG_GAIN,
+ ctrl->val, NULL);
break;
case V4L2_CID_DIGITAL_GAIN:
- ret = imx355_write_reg(imx355, IMX355_REG_DIG_GAIN_GLOBAL, 2,
- ctrl->val);
+ ret = cci_write(imx355->regmap, IMX355_REG_DIG_GAIN_GLOBAL,
+ ctrl->val, NULL);
break;
case V4L2_CID_EXPOSURE:
- ret = imx355_write_reg(imx355, IMX355_REG_EXPOSURE, 2,
- ctrl->val);
+ ret = cci_write(imx355->regmap, IMX355_REG_EXPOSURE,
+ ctrl->val, NULL);
break;
case V4L2_CID_VBLANK:
/* Update FLL that meets expected vertical blanking */
- ret = imx355_write_reg(imx355, IMX355_REG_FLL, 2,
- imx355->cur_mode->height + ctrl->val);
+ ret = cci_write(imx355->regmap, IMX355_REG_FLL,
+ imx355->cur_mode->height + ctrl->val, NULL);
break;
case V4L2_CID_TEST_PATTERN:
- ret = imx355_write_reg(imx355, IMX355_REG_TEST_PATTERN,
- 2, ctrl->val);
+ ret = cci_write(imx355->regmap, IMX355_REG_TEST_PATTERN,
+ ctrl->val, NULL);
break;
case V4L2_CID_HFLIP:
case V4L2_CID_VFLIP:
- ret = imx355_write_reg(imx355, IMX355_REG_ORIENTATION, 1,
- imx355->hflip->val |
- imx355->vflip->val << 1);
+ ret = cci_write(imx355->regmap, IMX355_REG_ORIENTATION,
+ imx355->hflip->val | imx355->vflip->val << 1,
+ NULL);
break;
default:
ret = -EINVAL;
@@ -948,103 +869,64 @@ static int imx355_start_streaming(struct imx355 *imx355)
{
const struct imx355_reg_list *reg_list;
const struct imx355_mode *mode;
- int ret;
+ int ret = 0;
/* Global Setting */
- reg_list = &imx355_global_setting;
- ret = imx355_write_regs(imx355, reg_list->regs, reg_list->num_of_regs);
- if (ret) {
- dev_err(imx355->dev, "failed to set global settings");
- return ret;
- }
+ cci_multi_reg_write(imx355->regmap, imx355_global_regs,
+ ARRAY_SIZE(imx355_global_regs), &ret);
/* Apply default values of current mode */
mode = imx355->cur_mode;
reg_list = &mode->reg_list;
- ret = imx355_write_regs(imx355, reg_list->regs, reg_list->num_of_regs);
- if (ret) {
- dev_err(imx355->dev, "failed to set mode");
- return ret;
- }
+ cci_multi_reg_write(imx355->regmap, reg_list->regs,
+ reg_list->num_of_regs, &ret);
/* Set readout crop and size registers */
- ret = imx355_write_reg(imx355, IMX355_REG_X_ADD_START, 2,
- mode->x_add_start);
- if (ret)
- return ret;
- ret = imx355_write_reg(imx355, IMX355_REG_Y_ADD_START, 2,
- mode->y_add_start);
- if (ret)
- return ret;
- ret = imx355_write_reg(imx355, IMX355_REG_X_ADD_END, 2,
- mode->x_add_end);
- if (ret)
- return ret;
- ret = imx355_write_reg(imx355, IMX355_REG_Y_ADD_END, 2,
- mode->y_add_end);
- if (ret)
- return ret;
- ret = imx355_write_reg(imx355, IMX355_REG_X_OUT_SIZE, 2,
- mode->width);
- if (ret)
- return ret;
- ret = imx355_write_reg(imx355, IMX355_REG_Y_OUT_SIZE, 2,
- mode->height);
- if (ret)
- return ret;
-
- ret = imx355_write_reg(imx355, IMX355_REG_BINNING_MODE, 1,
- mode->binning_mode == 0x11 ? 0x00 : 0x01);
- if (ret)
- return ret;
- ret = imx355_write_reg(imx355, IMX355_REG_BINNING_TYPE, 1,
- mode->binning_mode);
- if (ret)
- return ret;
- ret = imx355_write_reg(imx355, IMX355_REG_BINNING_WEIGHTING, 1, 0x00);
- if (ret)
- return ret;
+ cci_write(imx355->regmap, IMX355_REG_X_ADD_START, mode->x_add_start,
+ &ret);
+ cci_write(imx355->regmap, IMX355_REG_Y_ADD_START, mode->y_add_start,
+ &ret);
+ cci_write(imx355->regmap, IMX355_REG_X_ADD_END, mode->x_add_end, &ret);
+ cci_write(imx355->regmap, IMX355_REG_Y_ADD_END, mode->y_add_end, &ret);
+ cci_write(imx355->regmap, IMX355_REG_X_OUT_SIZE, mode->width, &ret);
+ cci_write(imx355->regmap, IMX355_REG_Y_OUT_SIZE, mode->height, &ret);
+ cci_write(imx355->regmap, IMX355_REG_BINNING_MODE,
+ mode->binning_mode == 0x11 ? 0x00 : 0x01, &ret);
+ cci_write(imx355->regmap, IMX355_REG_BINNING_TYPE, mode->binning_mode,
+ &ret);
+ cci_write(imx355->regmap, IMX355_REG_BINNING_WEIGHTING, 0x00, &ret);
/* Set PLL registers for the external clock frequency */
- ret = imx355_write_reg(imx355, IMX355_REG_EXTCLK_FREQ, 2,
- imx355->clk_params->extclk_freq);
- if (ret)
- return ret;
- ret = imx355_write_reg(imx355, IMX355_REG_PLL_VT_MUL, 2,
- imx355->clk_params->pll_vt_mpy);
- if (ret)
- return ret;
- ret = imx355_write_reg(imx355, IMX355_REG_PLL_OP_MUL, 2,
- imx355->clk_params->pll_op_mpy);
- if (ret)
- return ret;
+ cci_write(imx355->regmap, IMX355_REG_EXTCLK_FREQ,
+ imx355->clk_params->extclk_freq, &ret);
+ cci_write(imx355->regmap, IMX355_REG_PLL_VT_MUL,
+ imx355->clk_params->pll_vt_mpy, &ret);
+ cci_write(imx355->regmap, IMX355_REG_PLL_OP_MUL,
+ imx355->clk_params->pll_op_mpy, &ret);
/* set digital gain control to all color mode */
- ret = imx355_write_reg(imx355, IMX355_REG_DPGA_USE_GLOBAL_GAIN, 1, 1);
- if (ret)
- return ret;
+ cci_write(imx355->regmap, IMX355_REG_DPGA_USE_GLOBAL_GAIN, 1, &ret);
/* set line length */
- ret = imx355_write_reg(imx355, IMX355_REG_LLP,
- imx355->hblank->val + imx355->cur_mode->width,
- 2);
- if (ret)
- return ret;
+ cci_write(imx355->regmap, IMX355_REG_LLP,
+ imx355->hblank->val + imx355->cur_mode->width, &ret);
/* Apply customized values from user */
- ret = __v4l2_ctrl_handler_setup(imx355->sd.ctrl_handler);
+ __v4l2_ctrl_handler_setup(imx355->sd.ctrl_handler);
if (ret)
return ret;
- return imx355_write_reg(imx355, IMX355_REG_MODE_SELECT,
- 1, IMX355_MODE_STREAMING);
+ cci_write(imx355->regmap, IMX355_REG_MODE_SELECT, IMX355_MODE_STREAMING,
+ &ret);
+
+ return ret;
}
/* Stop streaming */
static int imx355_stop_streaming(struct imx355 *imx355)
{
- return imx355_write_reg(imx355, IMX355_REG_MODE_SELECT,
- 1, IMX355_MODE_STANDBY);
+ return cci_write(imx355->regmap, IMX355_REG_MODE_SELECT,
+ IMX355_MODE_STANDBY, NULL);
}
static int imx355_set_stream(struct v4l2_subdev *sd, int enable)
@@ -1091,14 +973,14 @@ static int imx355_set_stream(struct v4l2_subdev *sd, int enable)
static int imx355_identify_module(struct imx355 *imx355)
{
int ret;
- u32 val;
+ u64 val;
- ret = imx355_read_reg(imx355, IMX355_REG_CHIP_ID, 2, &val);
+ ret = cci_read(imx355->regmap, IMX355_REG_CHIP_ID, &val, NULL);
if (ret)
return ret;
if (val != IMX355_CHIP_ID) {
- dev_err(imx355->dev, "chip id mismatch: %x!=%x",
+ dev_err(imx355->dev, "chip id mismatch: %x!=%llx",
IMX355_CHIP_ID, val);
return -EIO;
}
@@ -1345,6 +1227,12 @@ static int imx355_probe(struct i2c_client *client)
mutex_init(&imx355->mutex);
+ imx355->regmap = devm_cci_regmap_init_i2c(client, 16);
+ if (IS_ERR(imx355->regmap)) {
+ dev_err(imx355->dev, "Unable to initialize I2C\n");
+ return -ENODEV;
+ }
+
imx355->clk = devm_v4l2_sensor_clk_get(imx355->dev, NULL);
if (IS_ERR(imx355->clk))
return dev_err_probe(imx355->dev, PTR_ERR(imx355->clk),
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread* Re: [PATCH 12/13] media: imx355: Convert to new CCI register access helpers
2026-05-06 18:23 ` [PATCH 12/13] media: imx355: Convert to new CCI register access helpers Dave Stevenson
@ 2026-05-07 14:49 ` Jacopo Mondi
0 siblings, 0 replies; 29+ messages in thread
From: Jacopo Mondi @ 2026-05-07 14:49 UTC (permalink / raw)
To: Dave Stevenson
Cc: Tianshu Qiu, Sakari Ailus, Mauro Carvalho Chehab, linux-media,
linux-kernel, David Heidelberg,
20260414-imx355-24mhz-v1-1-9ae77bc6e7ec
Hi Dave
On Wed, May 06, 2026 at 07:23:50PM +0100, Dave Stevenson wrote:
> Use the new comon CCI register access helpers to replace the private
> register access helpers in the imx355 driver.
>
> Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
> ---
> drivers/media/i2c/Kconfig | 1 +
> drivers/media/i2c/imx355.c | 502 ++++++++++++++++++---------------------------
> 2 files changed, 196 insertions(+), 307 deletions(-)
>
> diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> index 8f2ba4121586..38f23306722c 100644
> --- a/drivers/media/i2c/Kconfig
> +++ b/drivers/media/i2c/Kconfig
> @@ -259,6 +259,7 @@ config VIDEO_IMX335
>
> config VIDEO_IMX355
> tristate "Sony IMX355 sensor support"
> + select V4L2_CCI_I2C
> help
> This is a Video4Linux2 sensor driver for the Sony
> IMX355 camera.
> diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
> index c6fcd649c32a..d0e0e81d1e7c 100644
> --- a/drivers/media/i2c/imx355.c
> +++ b/drivers/media/i2c/imx355.c
> @@ -9,78 +9,80 @@
> #include <linux/module.h>
> #include <linux/of.h>
> #include <linux/pm_runtime.h>
> +#include <linux/regmap.h>
> #include <linux/regulator/consumer.h>
> #include <linux/unaligned.h>
>
> +#include <media/v4l2-cci.h>
> #include <media/v4l2-ctrls.h>
> #include <media/v4l2-device.h>
> #include <media/v4l2-event.h>
> #include <media/v4l2-fwnode.h>
>
> -#define IMX355_REG_MODE_SELECT 0x0100
> +#define IMX355_REG_MODE_SELECT CCI_REG8(0x0100)
> #define IMX355_MODE_STANDBY 0x00
> #define IMX355_MODE_STREAMING 0x01
>
> /* Chip ID */
> -#define IMX355_REG_CHIP_ID 0x0016
> +#define IMX355_REG_CHIP_ID CCI_REG16(0x0016)
> #define IMX355_CHIP_ID 0x0355
>
> /* PLL registers that depend on the external clock frequency */
> -#define IMX355_REG_EXTCLK_FREQ 0x0136
> -#define IMX355_REG_PLL_VT_MUL 0x0306
> -#define IMX355_REG_PLL_OP_MUL 0x030e
> +#define IMX355_REG_EXTCLK_FREQ CCI_REG16(0x0136)
> +#define IMX355_REG_PLL_VT_MUL CCI_REG16(0x0306)
> +#define IMX355_REG_PLL_OP_MUL CCI_REG16(0x030e)
>
> /* V_TIMING internal */
> -#define IMX355_REG_FLL 0x0340
> +#define IMX355_REG_FLL CCI_REG16(0x0340)
> #define IMX355_FLL_MAX 0xffff
> /* Number of lines above frame height that are required. */
> #define IMX355_FLL_OFFSET 20
>
> -#define IMX355_REG_LLP 0x0342
> +#define IMX355_REG_LLP CCI_REG16(0x0342)
> #define IMX355_LLP_MAX 0xffff
>
> -#define IMX355_REG_X_ADD_START 0x0344
> -#define IMX355_REG_Y_ADD_START 0x0346
> -#define IMX355_REG_X_ADD_END 0x0348
> -#define IMX355_REG_Y_ADD_END 0x034a
> -#define IMX355_REG_X_OUT_SIZE 0x034c
> -#define IMX355_REG_Y_OUT_SIZE 0x034e
> +#define IMX355_REG_X_ADD_START CCI_REG16(0x0344)
> +#define IMX355_REG_Y_ADD_START CCI_REG16(0x0346)
> +#define IMX355_REG_X_ADD_END CCI_REG16(0x0348)
> +#define IMX355_REG_Y_ADD_END CCI_REG16(0x034a)
> +#define IMX355_REG_X_OUT_SIZE CCI_REG16(0x034c)
> +#define IMX355_REG_Y_OUT_SIZE CCI_REG16(0x034e)
>
> /* Exposure control */
> -#define IMX355_REG_EXPOSURE 0x0202
> +#define IMX355_REG_EXPOSURE CCI_REG16(0x0202)
> #define IMX355_EXPOSURE_MIN 1
> #define IMX355_EXPOSURE_STEP 1
> #define IMX355_EXPOSURE_DEFAULT 0x0282
>
> /* Analog gain control */
> -#define IMX355_REG_ANALOG_GAIN 0x0204
> +#define IMX355_REG_ANALOG_GAIN CCI_REG16(0x0204)
> #define IMX355_ANA_GAIN_MIN 0
> #define IMX355_ANA_GAIN_MAX 960
> #define IMX355_ANA_GAIN_STEP 1
> #define IMX355_ANA_GAIN_DEFAULT 0
>
> /* Digital gain control */
> -#define IMX355_REG_DPGA_USE_GLOBAL_GAIN 0x3070
> -#define IMX355_REG_DIG_GAIN_GLOBAL 0x020e
> +#define IMX355_REG_DPGA_USE_GLOBAL_GAIN CCI_REG8(0x3070)
> +#define IMX355_REG_DIG_GAIN_GLOBAL CCI_REG16(0x020e)
> #define IMX355_DGTL_GAIN_MIN 256
> #define IMX355_DGTL_GAIN_MAX 4095
> #define IMX355_DGTL_GAIN_STEP 1
> #define IMX355_DGTL_GAIN_DEFAULT 256
>
> /* Test Pattern Control */
> -#define IMX355_REG_TEST_PATTERN 0x0600
> +#define IMX355_REG_TEST_PATTERN CCI_REG8(0x0600)
> #define IMX355_TEST_PATTERN_DISABLED 0
> #define IMX355_TEST_PATTERN_SOLID_COLOR 1
> #define IMX355_TEST_PATTERN_COLOR_BARS 2
> #define IMX355_TEST_PATTERN_GRAY_COLOR_BARS 3
> #define IMX355_TEST_PATTERN_PN9 4
>
> -#define IMX355_REG_BINNING_MODE 0x0900
> -#define IMX355_REG_BINNING_TYPE 0x0901
> -#define IMX355_REG_BINNING_WEIGHTING 0x0902
> +#define IMX355_REG_BINNING_MODE CCI_REG8(0x0900)
> +#define IMX355_REG_BINNING_TYPE CCI_REG8(0x0901)
> +#define IMX355_REG_BINNING_WEIGHTING CCI_REG8(0x0902)
>
> /* Flip Control */
> -#define IMX355_REG_ORIENTATION 0x0101
> +#define IMX355_REG_ORIENTATION CCI_REG8(0x0101)
>
> /* default link frequency and external clock */
> #define IMX355_LINK_FREQ_DEFAULT 360000000LL
> @@ -93,14 +95,9 @@
> #define IMX355_PIXEL_ARRAY_WIDTH 3280
> #define IMX355_PIXEL_ARRAY_HEIGHT 2464
>
> -struct imx355_reg {
> - u16 address;
> - u8 val;
> -};
> -
> struct imx355_reg_list {
> u32 num_of_regs;
> - const struct imx355_reg *regs;
> + const struct cci_reg_sequence *regs;
> };
>
> /* Mode : resolution and related config&values */
> @@ -160,6 +157,7 @@ struct imx355_hwcfg {
> struct imx355 {
> struct device *dev;
> struct clk *clk;
> + struct regmap *regmap;
>
> struct v4l2_subdev sd;
> struct media_pad pad;
> @@ -196,152 +194,147 @@ static const struct regulator_bulk_data imx355_supplies[] = {
> { .supply = "dovdd" },
> };
>
> -static const struct imx355_reg imx355_global_regs[] = {
> - { 0x304e, 0x03 },
> - { 0x4348, 0x16 },
> - { 0x4350, 0x19 },
> - { 0x4408, 0x0a },
> - { 0x440c, 0x0b },
> - { 0x4411, 0x5f },
> - { 0x4412, 0x2c },
> - { 0x4623, 0x00 },
> - { 0x462c, 0x0f },
> - { 0x462d, 0x00 },
> - { 0x462e, 0x00 },
> - { 0x4684, 0x54 },
> - { 0x480a, 0x07 },
> - { 0x4908, 0x07 },
> - { 0x4909, 0x07 },
> - { 0x490d, 0x0a },
> - { 0x491e, 0x0f },
> - { 0x4921, 0x06 },
> - { 0x4923, 0x28 },
> - { 0x4924, 0x28 },
> - { 0x4925, 0x29 },
> - { 0x4926, 0x29 },
> - { 0x4927, 0x1f },
> - { 0x4928, 0x20 },
> - { 0x4929, 0x20 },
> - { 0x492a, 0x20 },
> - { 0x492c, 0x05 },
> - { 0x492d, 0x06 },
> - { 0x492e, 0x06 },
> - { 0x492f, 0x06 },
> - { 0x4930, 0x03 },
> - { 0x4931, 0x04 },
> - { 0x4932, 0x04 },
> - { 0x4933, 0x05 },
> - { 0x595e, 0x01 },
> - { 0x5963, 0x01 },
> - { 0x3030, 0x01 },
> - { 0x3031, 0x01 },
> - { 0x3045, 0x01 },
> - { 0x4010, 0x00 },
> - { 0x4011, 0x00 },
> - { 0x4012, 0x00 },
> - { 0x4013, 0x01 },
> - { 0x68a8, 0xfe },
> - { 0x68a9, 0xff },
> - { 0x6888, 0x00 },
> - { 0x6889, 0x00 },
> - { 0x68b0, 0x00 },
> - { 0x3058, 0x00 },
> - { 0x305a, 0x00 },
> - { 0x0112, 0x0a },
> - { 0x0113, 0x0a },
> - { 0x0114, 0x03 },
> - { 0x0301, 0x05 },
> - { 0x0303, 0x01 },
> - { 0x0305, 0x02 },
> - { 0x030d, 0x02 },
> - { 0x0310, 0x00 },
> - { 0x0220, 0x00 },
> - { 0x0222, 0x01 },
> - { 0x0820, 0x0b },
> - { 0x0821, 0x40 },
> - { 0x3088, 0x04 },
> - { 0x6813, 0x02 },
> - { 0x6835, 0x07 },
> - { 0x6836, 0x01 },
> - { 0x6837, 0x04 },
> - { 0x684d, 0x07 },
> - { 0x684e, 0x01 },
> - { 0x684f, 0x04 },
> +static const struct cci_reg_sequence imx355_global_regs[] = {
> + { CCI_REG8(0x304e), 0x03 },
> + { CCI_REG8(0x4348), 0x16 },
> + { CCI_REG8(0x4350), 0x19 },
> + { CCI_REG8(0x4408), 0x0a },
> + { CCI_REG8(0x440c), 0x0b },
> + { CCI_REG8(0x4411), 0x5f },
> + { CCI_REG8(0x4412), 0x2c },
> + { CCI_REG8(0x4623), 0x00 },
> + { CCI_REG8(0x462c), 0x0f },
> + { CCI_REG8(0x462d), 0x00 },
> + { CCI_REG8(0x462e), 0x00 },
> + { CCI_REG8(0x4684), 0x54 },
> + { CCI_REG8(0x480a), 0x07 },
> + { CCI_REG8(0x4908), 0x07 },
> + { CCI_REG8(0x4909), 0x07 },
> + { CCI_REG8(0x490d), 0x0a },
> + { CCI_REG8(0x491e), 0x0f },
> + { CCI_REG8(0x4921), 0x06 },
> + { CCI_REG8(0x4923), 0x28 },
> + { CCI_REG8(0x4924), 0x28 },
> + { CCI_REG8(0x4925), 0x29 },
> + { CCI_REG8(0x4926), 0x29 },
> + { CCI_REG8(0x4927), 0x1f },
> + { CCI_REG8(0x4928), 0x20 },
> + { CCI_REG8(0x4929), 0x20 },
> + { CCI_REG8(0x492a), 0x20 },
> + { CCI_REG8(0x492c), 0x05 },
> + { CCI_REG8(0x492d), 0x06 },
> + { CCI_REG8(0x492e), 0x06 },
> + { CCI_REG8(0x492f), 0x06 },
> + { CCI_REG8(0x4930), 0x03 },
> + { CCI_REG8(0x4931), 0x04 },
> + { CCI_REG8(0x4932), 0x04 },
> + { CCI_REG8(0x4933), 0x05 },
> + { CCI_REG8(0x595e), 0x01 },
> + { CCI_REG8(0x5963), 0x01 },
> + { CCI_REG8(0x3030), 0x01 },
> + { CCI_REG8(0x3031), 0x01 },
> + { CCI_REG8(0x3045), 0x01 },
> + { CCI_REG8(0x4010), 0x00 },
> + { CCI_REG8(0x4011), 0x00 },
> + { CCI_REG8(0x4012), 0x00 },
> + { CCI_REG8(0x4013), 0x01 },
> + { CCI_REG8(0x68a8), 0xfe },
> + { CCI_REG8(0x68a9), 0xff },
> + { CCI_REG8(0x6888), 0x00 },
> + { CCI_REG8(0x6889), 0x00 },
> + { CCI_REG8(0x68b0), 0x00 },
> + { CCI_REG8(0x3058), 0x00 },
> + { CCI_REG8(0x305a), 0x00 },
> + { CCI_REG8(0x0112), 0x0a },
> + { CCI_REG8(0x0113), 0x0a },
> + { CCI_REG8(0x0114), 0x03 },
> + { CCI_REG8(0x0301), 0x05 },
> + { CCI_REG8(0x0303), 0x01 },
> + { CCI_REG8(0x0305), 0x02 },
> + { CCI_REG8(0x030d), 0x02 },
> + { CCI_REG8(0x0310), 0x00 },
> + { CCI_REG8(0x0220), 0x00 },
> + { CCI_REG8(0x0222), 0x01 },
> + { CCI_REG8(0x0820), 0x0b },
> + { CCI_REG8(0x0821), 0x40 },
> + { CCI_REG8(0x3088), 0x04 },
> + { CCI_REG8(0x6813), 0x02 },
> + { CCI_REG8(0x6835), 0x07 },
> + { CCI_REG8(0x6836), 0x01 },
> + { CCI_REG8(0x6837), 0x04 },
> + { CCI_REG8(0x684d), 0x07 },
> + { CCI_REG8(0x684e), 0x01 },
> + { CCI_REG8(0x684f), 0x04 },
> };
I admit I haven't gone through the registers to check their effective
sizes
>
> -static const struct imx355_reg_list imx355_global_setting = {
> - .num_of_regs = ARRAY_SIZE(imx355_global_regs),
> - .regs = imx355_global_regs,
> +static const struct cci_reg_sequence mode_3268x2448_regs[] = {
> + { CCI_REG8(0x0700), 0x00 },
> + { CCI_REG8(0x0701), 0x10 },
> };
>
> -static const struct imx355_reg mode_3268x2448_regs[] = {
> - { 0x0700, 0x00 },
> - { 0x0701, 0x10 },
> +static const struct cci_reg_sequence mode_3264x2448_regs[] = {
> + { CCI_REG8(0x0700), 0x00 },
> + { CCI_REG8(0x0701), 0x10 },
> };
>
> -static const struct imx355_reg mode_3264x2448_regs[] = {
> - { 0x0700, 0x00 },
> - { 0x0701, 0x10 },
> +static const struct cci_reg_sequence mode_3280x2464_regs[] = {
> + { CCI_REG8(0x0700), 0x00 },
> + { CCI_REG8(0x0701), 0x10 },
> };
>
> -static const struct imx355_reg mode_3280x2464_regs[] = {
> - { 0x0700, 0x00 },
> - { 0x0701, 0x10 },
> +static const struct cci_reg_sequence mode_1940x1096_regs[] = {
> + { CCI_REG8(0x0700), 0x00 },
> + { CCI_REG8(0x0701), 0x10 },
> };
>
> -static const struct imx355_reg mode_1940x1096_regs[] = {
> - { 0x0700, 0x00 },
> - { 0x0701, 0x10 },
> +static const struct cci_reg_sequence mode_1936x1096_regs[] = {
> + { CCI_REG8(0x0700), 0x00 },
> + { CCI_REG8(0x0701), 0x10 },
> };
>
> -static const struct imx355_reg mode_1936x1096_regs[] = {
> - { 0x0700, 0x00 },
> - { 0x0701, 0x10 },
> +static const struct cci_reg_sequence mode_1924x1080_regs[] = {
> + { CCI_REG8(0x0700), 0x00 },
> + { CCI_REG8(0x0701), 0x10 },
> };
>
> -static const struct imx355_reg mode_1924x1080_regs[] = {
> - { 0x0700, 0x00 },
> - { 0x0701, 0x10 },
> +static const struct cci_reg_sequence mode_1920x1080_regs[] = {
> + { CCI_REG8(0x0700), 0x00 },
> + { CCI_REG8(0x0701), 0x10 },
> };
>
> -static const struct imx355_reg mode_1920x1080_regs[] = {
> - { 0x0700, 0x00 },
> - { 0x0701, 0x10 },
> +static const struct cci_reg_sequence mode_1640x1232_regs[] = {
> + { CCI_REG8(0x0700), 0x00 },
> + { CCI_REG8(0x0701), 0x10 },
> };
>
> -static const struct imx355_reg mode_1640x1232_regs[] = {
> - { 0x0700, 0x00 },
> - { 0x0701, 0x10 },
> +static const struct cci_reg_sequence mode_1640x922_regs[] = {
> + { CCI_REG8(0x0700), 0x00 },
> + { CCI_REG8(0x0701), 0x10 },
> };
>
> -static const struct imx355_reg mode_1640x922_regs[] = {
> - { 0x0700, 0x00 },
> - { 0x0701, 0x10 },
> +static const struct cci_reg_sequence mode_1300x736_regs[] = {
> + { CCI_REG8(0x0700), 0x00 },
> + { CCI_REG8(0x0701), 0x10 },
> };
>
> -static const struct imx355_reg mode_1300x736_regs[] = {
> - { 0x0700, 0x00 },
> - { 0x0701, 0x10 },
> +static const struct cci_reg_sequence mode_1296x736_regs[] = {
> + { CCI_REG8(0x0700), 0x00 },
> + { CCI_REG8(0x0701), 0x10 },
> };
>
> -static const struct imx355_reg mode_1296x736_regs[] = {
> - { 0x0700, 0x00 },
> - { 0x0701, 0x10 },
> +static const struct cci_reg_sequence mode_1284x720_regs[] = {
> + { CCI_REG8(0x0700), 0x00 },
> + { CCI_REG8(0x0701), 0x10 },
> };
>
> -static const struct imx355_reg mode_1284x720_regs[] = {
> - { 0x0700, 0x00 },
> - { 0x0701, 0x10 },
> +static const struct cci_reg_sequence mode_1280x720_regs[] = {
> + { CCI_REG8(0x0700), 0x00 },
> + { CCI_REG8(0x0701), 0x10 },
> };
>
> -static const struct imx355_reg mode_1280x720_regs[] = {
> - { 0x0700, 0x00 },
> - { 0x0701, 0x10 },
> -};
> -
> -static const struct imx355_reg mode_820x616_regs[] = {
> - { 0x0700, 0x02 },
> - { 0x0701, 0x78 },
> +static const struct cci_reg_sequence mode_820x616_regs[] = {
> + { CCI_REG8(0x0700), 0x02 },
> + { CCI_REG8(0x0701), 0x78 },
> };
>
> static const char * const imx355_test_pattern_menu[] = {
> @@ -598,78 +591,6 @@ static u32 imx355_get_format_code(struct imx355 *imx355)
> return code;
> }
>
> -/* Read registers up to 4 at a time */
> -static int imx355_read_reg(struct imx355 *imx355, u16 reg, u32 len, u32 *val)
> -{
> - struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
> - struct i2c_msg msgs[2];
> - u8 addr_buf[2];
> - u8 data_buf[4] = { 0 };
> - int ret;
> -
> - if (len > 4)
> - return -EINVAL;
> -
> - put_unaligned_be16(reg, addr_buf);
> - /* Write register address */
> - msgs[0].addr = client->addr;
> - msgs[0].flags = 0;
> - msgs[0].len = ARRAY_SIZE(addr_buf);
> - msgs[0].buf = addr_buf;
> -
> - /* Read data from register */
> - msgs[1].addr = client->addr;
> - msgs[1].flags = I2C_M_RD;
> - msgs[1].len = len;
> - msgs[1].buf = &data_buf[4 - len];
> -
> - ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
> - if (ret != ARRAY_SIZE(msgs))
> - return -EIO;
> -
> - *val = get_unaligned_be32(data_buf);
> -
> - return 0;
> -}
> -
> -/* Write registers up to 4 at a time */
> -static int imx355_write_reg(struct imx355 *imx355, u16 reg, u32 len, u32 val)
> -{
> - struct i2c_client *client = v4l2_get_subdevdata(&imx355->sd);
> - u8 buf[6];
> -
> - if (len > 4)
> - return -EINVAL;
> -
> - put_unaligned_be16(reg, buf);
> - put_unaligned_be32(val << (8 * (4 - len)), buf + 2);
> - if (i2c_master_send(client, buf, len + 2) != len + 2)
> - return -EIO;
> -
> - return 0;
> -}
> -
> -/* Write a list of registers */
> -static int imx355_write_regs(struct imx355 *imx355,
> - const struct imx355_reg *regs, u32 len)
> -{
> - int ret;
> - u32 i;
> -
> - for (i = 0; i < len; i++) {
> - ret = imx355_write_reg(imx355, regs[i].address, 1, regs[i].val);
> - if (ret) {
> - dev_err_ratelimited(imx355->dev,
> - "write reg 0x%4.4x return err %d",
> - regs[i].address, ret);
> -
> - return ret;
> - }
> - }
> -
> - return 0;
> -}
> -
> /* Open sub-device */
> static int imx355_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
> {
> @@ -724,31 +645,31 @@ static int imx355_set_ctrl(struct v4l2_ctrl *ctrl)
> switch (ctrl->id) {
> case V4L2_CID_ANALOGUE_GAIN:
> /* Analog gain = 1024/(1024 - ctrl->val) times */
> - ret = imx355_write_reg(imx355, IMX355_REG_ANALOG_GAIN, 2,
> - ctrl->val);
> + ret = cci_write(imx355->regmap, IMX355_REG_ANALOG_GAIN,
> + ctrl->val, NULL);
> break;
> case V4L2_CID_DIGITAL_GAIN:
> - ret = imx355_write_reg(imx355, IMX355_REG_DIG_GAIN_GLOBAL, 2,
> - ctrl->val);
> + ret = cci_write(imx355->regmap, IMX355_REG_DIG_GAIN_GLOBAL,
> + ctrl->val, NULL);
> break;
> case V4L2_CID_EXPOSURE:
> - ret = imx355_write_reg(imx355, IMX355_REG_EXPOSURE, 2,
> - ctrl->val);
> + ret = cci_write(imx355->regmap, IMX355_REG_EXPOSURE,
> + ctrl->val, NULL);
> break;
> case V4L2_CID_VBLANK:
> /* Update FLL that meets expected vertical blanking */
> - ret = imx355_write_reg(imx355, IMX355_REG_FLL, 2,
> - imx355->cur_mode->height + ctrl->val);
> + ret = cci_write(imx355->regmap, IMX355_REG_FLL,
> + imx355->cur_mode->height + ctrl->val, NULL);
> break;
> case V4L2_CID_TEST_PATTERN:
> - ret = imx355_write_reg(imx355, IMX355_REG_TEST_PATTERN,
> - 2, ctrl->val);
> + ret = cci_write(imx355->regmap, IMX355_REG_TEST_PATTERN,
> + ctrl->val, NULL);
> break;
> case V4L2_CID_HFLIP:
> case V4L2_CID_VFLIP:
> - ret = imx355_write_reg(imx355, IMX355_REG_ORIENTATION, 1,
> - imx355->hflip->val |
> - imx355->vflip->val << 1);
> + ret = cci_write(imx355->regmap, IMX355_REG_ORIENTATION,
> + imx355->hflip->val | imx355->vflip->val << 1,
> + NULL);
> break;
> default:
> ret = -EINVAL;
> @@ -948,103 +869,64 @@ static int imx355_start_streaming(struct imx355 *imx355)
> {
> const struct imx355_reg_list *reg_list;
> const struct imx355_mode *mode;
> - int ret;
> + int ret = 0;
>
> /* Global Setting */
> - reg_list = &imx355_global_setting;
> - ret = imx355_write_regs(imx355, reg_list->regs, reg_list->num_of_regs);
> - if (ret) {
> - dev_err(imx355->dev, "failed to set global settings");
> - return ret;
> - }
> + cci_multi_reg_write(imx355->regmap, imx355_global_regs,
> + ARRAY_SIZE(imx355_global_regs), &ret);
>
> /* Apply default values of current mode */
> mode = imx355->cur_mode;
> reg_list = &mode->reg_list;
> - ret = imx355_write_regs(imx355, reg_list->regs, reg_list->num_of_regs);
> - if (ret) {
> - dev_err(imx355->dev, "failed to set mode");
> - return ret;
> - }
> + cci_multi_reg_write(imx355->regmap, reg_list->regs,
> + reg_list->num_of_regs, &ret);
I wonder if it makes sense to continue if this fails
>
> /* Set readout crop and size registers */
> - ret = imx355_write_reg(imx355, IMX355_REG_X_ADD_START, 2,
> - mode->x_add_start);
> - if (ret)
> - return ret;
> - ret = imx355_write_reg(imx355, IMX355_REG_Y_ADD_START, 2,
> - mode->y_add_start);
> - if (ret)
> - return ret;
> - ret = imx355_write_reg(imx355, IMX355_REG_X_ADD_END, 2,
> - mode->x_add_end);
> - if (ret)
> - return ret;
> - ret = imx355_write_reg(imx355, IMX355_REG_Y_ADD_END, 2,
> - mode->y_add_end);
> - if (ret)
> - return ret;
> - ret = imx355_write_reg(imx355, IMX355_REG_X_OUT_SIZE, 2,
> - mode->width);
> - if (ret)
> - return ret;
> - ret = imx355_write_reg(imx355, IMX355_REG_Y_OUT_SIZE, 2,
> - mode->height);
> - if (ret)
> - return ret;
> -
> - ret = imx355_write_reg(imx355, IMX355_REG_BINNING_MODE, 1,
> - mode->binning_mode == 0x11 ? 0x00 : 0x01);
> - if (ret)
> - return ret;
> - ret = imx355_write_reg(imx355, IMX355_REG_BINNING_TYPE, 1,
> - mode->binning_mode);
> - if (ret)
> - return ret;
> - ret = imx355_write_reg(imx355, IMX355_REG_BINNING_WEIGHTING, 1, 0x00);
> - if (ret)
> - return ret;
> + cci_write(imx355->regmap, IMX355_REG_X_ADD_START, mode->x_add_start,
> + &ret);
> + cci_write(imx355->regmap, IMX355_REG_Y_ADD_START, mode->y_add_start,
> + &ret);
> + cci_write(imx355->regmap, IMX355_REG_X_ADD_END, mode->x_add_end, &ret);
> + cci_write(imx355->regmap, IMX355_REG_Y_ADD_END, mode->y_add_end, &ret);
> + cci_write(imx355->regmap, IMX355_REG_X_OUT_SIZE, mode->width, &ret);
> + cci_write(imx355->regmap, IMX355_REG_Y_OUT_SIZE, mode->height, &ret);
> + cci_write(imx355->regmap, IMX355_REG_BINNING_MODE,
> + mode->binning_mode == 0x11 ? 0x00 : 0x01, &ret);
> + cci_write(imx355->regmap, IMX355_REG_BINNING_TYPE, mode->binning_mode,
> + &ret);
> + cci_write(imx355->regmap, IMX355_REG_BINNING_WEIGHTING, 0x00, &ret);
>
> /* Set PLL registers for the external clock frequency */
> - ret = imx355_write_reg(imx355, IMX355_REG_EXTCLK_FREQ, 2,
> - imx355->clk_params->extclk_freq);
> - if (ret)
> - return ret;
> - ret = imx355_write_reg(imx355, IMX355_REG_PLL_VT_MUL, 2,
> - imx355->clk_params->pll_vt_mpy);
> - if (ret)
> - return ret;
> - ret = imx355_write_reg(imx355, IMX355_REG_PLL_OP_MUL, 2,
> - imx355->clk_params->pll_op_mpy);
> - if (ret)
> - return ret;
> + cci_write(imx355->regmap, IMX355_REG_EXTCLK_FREQ,
> + imx355->clk_params->extclk_freq, &ret);
> + cci_write(imx355->regmap, IMX355_REG_PLL_VT_MUL,
> + imx355->clk_params->pll_vt_mpy, &ret);
> + cci_write(imx355->regmap, IMX355_REG_PLL_OP_MUL,
> + imx355->clk_params->pll_op_mpy, &ret);
>
> /* set digital gain control to all color mode */
> - ret = imx355_write_reg(imx355, IMX355_REG_DPGA_USE_GLOBAL_GAIN, 1, 1);
> - if (ret)
> - return ret;
> + cci_write(imx355->regmap, IMX355_REG_DPGA_USE_GLOBAL_GAIN, 1, &ret);
>
> /* set line length */
> - ret = imx355_write_reg(imx355, IMX355_REG_LLP,
> - imx355->hblank->val + imx355->cur_mode->width,
> - 2);
> - if (ret)
> - return ret;
> + cci_write(imx355->regmap, IMX355_REG_LLP,
> + imx355->hblank->val + imx355->cur_mode->width, &ret);
>
> /* Apply customized values from user */
> - ret = __v4l2_ctrl_handler_setup(imx355->sd.ctrl_handler);
> + __v4l2_ctrl_handler_setup(imx355->sd.ctrl_handler);
This now looks a bit weird
/* set line length */
cci_write(imx355->regmap, IMX355_REG_LLP,
imx355->hblank->val + imx355->cur_mode->width, &ret);
/* Apply customized values from user */
__v4l2_ctrl_handler_setup(imx355->sd.ctrl_handler);
if (ret)
return ret;
> if (ret)
> return ret;
>
> - return imx355_write_reg(imx355, IMX355_REG_MODE_SELECT,
> - 1, IMX355_MODE_STREAMING);
> + cci_write(imx355->regmap, IMX355_REG_MODE_SELECT, IMX355_MODE_STREAMING,
> + &ret);
> +
> + return ret;
> }
>
> /* Stop streaming */
> static int imx355_stop_streaming(struct imx355 *imx355)
> {
> - return imx355_write_reg(imx355, IMX355_REG_MODE_SELECT,
> - 1, IMX355_MODE_STANDBY);
> + return cci_write(imx355->regmap, IMX355_REG_MODE_SELECT,
> + IMX355_MODE_STANDBY, NULL);
> }
>
> static int imx355_set_stream(struct v4l2_subdev *sd, int enable)
> @@ -1091,14 +973,14 @@ static int imx355_set_stream(struct v4l2_subdev *sd, int enable)
> static int imx355_identify_module(struct imx355 *imx355)
> {
> int ret;
> - u32 val;
> + u64 val;
>
> - ret = imx355_read_reg(imx355, IMX355_REG_CHIP_ID, 2, &val);
> + ret = cci_read(imx355->regmap, IMX355_REG_CHIP_ID, &val, NULL);
> if (ret)
> return ret;
>
> if (val != IMX355_CHIP_ID) {
> - dev_err(imx355->dev, "chip id mismatch: %x!=%x",
> + dev_err(imx355->dev, "chip id mismatch: %x!=%llx",
> IMX355_CHIP_ID, val);
> return -EIO;
> }
> @@ -1345,6 +1227,12 @@ static int imx355_probe(struct i2c_client *client)
>
> mutex_init(&imx355->mutex);
>
> + imx355->regmap = devm_cci_regmap_init_i2c(client, 16);
> + if (IS_ERR(imx355->regmap)) {
> + dev_err(imx355->dev, "Unable to initialize I2C\n");
> + return -ENODEV;
> + }
> +
> imx355->clk = devm_v4l2_sensor_clk_get(imx355->dev, NULL);
> if (IS_ERR(imx355->clk))
> return dev_err_probe(imx355->dev, PTR_ERR(imx355->clk),
>
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH 13/13] media: imx355: Support 2 lane readout.
2026-05-06 18:23 [PATCH 00/13] media/imx355: General code cleanups, and adding support for 2 lane operation Dave Stevenson
` (11 preceding siblings ...)
2026-05-06 18:23 ` [PATCH 12/13] media: imx355: Convert to new CCI register access helpers Dave Stevenson
@ 2026-05-06 18:23 ` Dave Stevenson
12 siblings, 0 replies; 29+ messages in thread
From: Dave Stevenson @ 2026-05-06 18:23 UTC (permalink / raw)
To: Tianshu Qiu, Sakari Ailus, Mauro Carvalho Chehab
Cc: linux-media, linux-kernel, David Heidelberg,
20260414-imx355-24mhz-v1-1-9ae77bc6e7ec, Dave Stevenson
The sensor supports 2 or 4 lane readout, but the driver only allowed
for 4 lanes. Add 2 lane support.
The clock tree was set to use single PLL mode to feed both IOP (MIPI)
and IVT (Pixel array).
2 lane mode supports a MIPI link frequency of up to 445MHz (890Mbit/s)
cf 360MHz (720Mbit/s) for 4lane, but that requires switching to dual
PLL mode as the rates can't be achieved with simple divisors.
The LLP values are extended for each mode to account for the increased
time per line over the MIPI link.
Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
---
drivers/media/i2c/imx355.c | 135 ++++++++++++++++++++++++++++-----------------
1 file changed, 84 insertions(+), 51 deletions(-)
diff --git a/drivers/media/i2c/imx355.c b/drivers/media/i2c/imx355.c
index d0e0e81d1e7c..fa1d1c86d5b0 100644
--- a/drivers/media/i2c/imx355.c
+++ b/drivers/media/i2c/imx355.c
@@ -27,10 +27,13 @@
#define IMX355_REG_CHIP_ID CCI_REG16(0x0016)
#define IMX355_CHIP_ID 0x0355
+#define IMX355_REG_LANE_SEL CCI_REG8(0x0114)
+
/* PLL registers that depend on the external clock frequency */
#define IMX355_REG_EXTCLK_FREQ CCI_REG16(0x0136)
#define IMX355_REG_PLL_VT_MUL CCI_REG16(0x0306)
#define IMX355_REG_PLL_OP_MUL CCI_REG16(0x030e)
+#define IMX355_REG_PLL_MODE CCI_REG8(0x0310)
/* V_TIMING internal */
#define IMX355_REG_FLL CCI_REG16(0x0340)
@@ -77,6 +80,8 @@
#define IMX355_TEST_PATTERN_GRAY_COLOR_BARS 3
#define IMX355_TEST_PATTERN_PN9 4
+#define IMX355_REG_REQ_LINK_BIT_RATE CCI_REG16(0x0820)
+
#define IMX355_REG_BINNING_MODE CCI_REG8(0x0900)
#define IMX355_REG_BINNING_TYPE CCI_REG8(0x0901)
#define IMX355_REG_BINNING_WEIGHTING CCI_REG8(0x0902)
@@ -85,10 +90,10 @@
#define IMX355_REG_ORIENTATION CCI_REG8(0x0101)
/* default link frequency and external clock */
-#define IMX355_LINK_FREQ_DEFAULT 360000000LL
+#define IMX355_LINK_FREQ_4LANE 360000000LL
+#define IMX355_LINK_FREQ_2LANE 445000000LL
-/* number of data lanes */
-#define IMX355_DATA_LANES 4
+#define IMX355_PIXEL_RATE 288000000
#define IMX355_PIXEL_ARRAY_TOP 0
#define IMX355_PIXEL_ARRAY_LEFT 0
@@ -110,8 +115,8 @@ struct imx355_mode {
/* V-timing */
u32 fll_def;
- /* H-timing */
- u32 llp;
+ /* H-timing - values for 4 lane and 2 lane */
+ u32 llp[2];
/* Default register values */
struct imx355_reg_list reg_list;
@@ -125,33 +130,38 @@ struct imx355_mode {
struct imx355_clk_params {
u32 ext_clk;
- u16 extclk_freq; /* External clock (MHz) in 8.8 fixed point) */
- u16 pll_vt_mpy; /* VT system PLL multiplier */
- u16 pll_op_mpy; /* OP system PLL multiplier */
+ u16 extclk_freq; /* External clock (MHz) in 8.8 fixed point) */
+ u16 pll_vt_mpy[2]; /* VT system PLL multiplier */
+ u16 pll_op_mpy[2]; /* OP system PLL multiplier */
};
/*
- * All modes use the same PLL dividers (PREPLLCK_VT_DIV=2, PREPLLCK_OP_DIV=2),
- * so the multipliers are adjusted to produce the same VCO frequencies:
- * VT VCO = 1152 MHz, OP VCO = 720 MHz
+ * For backwards compatibility, 4 lane mode uses the single PLL clock tree
+ * where only IOP matters. MIPI rate is 360Mhz (720Mbit/s), and pixel rate is
+ * 288MPix/s.
+ * 2 lane mode has a maximum MIPI rate of 445MHz (890Mbit/s) which requires
+ * switching to dual PLL mode if the pixel rate is to be kept the same.
+ *
+ * Multipliers are specified separately for 4 lane and 2 lane modes.
*/
static const struct imx355_clk_params imx355_clk_params[] = {
{
.ext_clk = 19200000,
- .extclk_freq = 0x1333, /* 19.2 MHz */
- .pll_vt_mpy = 120, /* 19.2 / 2 * 120 = 1152 MHz */
- .pll_op_mpy = 75, /* 19.2 / 2 * 75 = 720 MHz */
+ .extclk_freq = 0x1333,
+ .pll_vt_mpy = { 0, 75 },
+ .pll_op_mpy = { 75, 93 },
},
{
.ext_clk = 24000000,
- .extclk_freq = 0x1800, /* 24.0 MHz */
- .pll_vt_mpy = 96, /* 24.0 / 2 * 96 = 1152 MHz */
- .pll_op_mpy = 60, /* 24.0 / 2 * 60 = 720 MHz */
+ .extclk_freq = 0x1800,
+ .pll_vt_mpy = { 0, 60 },
+ .pll_op_mpy = { 60, 74 },
},
};
struct imx355_hwcfg {
unsigned long link_freq_bitmap;
+ unsigned int num_lanes;
};
struct imx355 {
@@ -247,16 +257,12 @@ static const struct cci_reg_sequence imx355_global_regs[] = {
{ CCI_REG8(0x305a), 0x00 },
{ CCI_REG8(0x0112), 0x0a },
{ CCI_REG8(0x0113), 0x0a },
- { CCI_REG8(0x0114), 0x03 },
{ CCI_REG8(0x0301), 0x05 },
{ CCI_REG8(0x0303), 0x01 },
{ CCI_REG8(0x0305), 0x02 },
{ CCI_REG8(0x030d), 0x02 },
- { CCI_REG8(0x0310), 0x00 },
{ CCI_REG8(0x0220), 0x00 },
{ CCI_REG8(0x0222), 0x01 },
- { CCI_REG8(0x0820), 0x0b },
- { CCI_REG8(0x0821), 0x40 },
{ CCI_REG8(0x3088), 0x04 },
{ CCI_REG8(0x6813), 0x02 },
{ CCI_REG8(0x6835), 0x07 },
@@ -349,17 +355,25 @@ static const char * const imx355_test_pattern_menu[] = {
* When adding more than the one below, make sure the disallowed ones will
* actually be disabled in the LINK_FREQ control.
*/
-static const s64 link_freq_menu_items[] = {
- IMX355_LINK_FREQ_DEFAULT,
+static const s64 link_freq_menu_items_4lane[] = {
+ IMX355_LINK_FREQ_4LANE,
};
+static const s64 link_freq_menu_items_2lane[] = {
+ IMX355_LINK_FREQ_2LANE,
+};
+
+/* Avoid the two arrays getting out of sync */
+static_assert(ARRAY_SIZE(link_freq_menu_items_4lane) ==
+ ARRAY_SIZE(link_freq_menu_items_2lane));
+
/* Mode configs */
static const struct imx355_mode supported_modes[] = {
{
.width = 3280,
.height = 2464,
.fll_def = 2615,
- .llp = 3672,
+ .llp = { 3672, 5942 },
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_3280x2464_regs),
.regs = mode_3280x2464_regs,
@@ -374,7 +388,7 @@ static const struct imx355_mode supported_modes[] = {
.width = 3268,
.height = 2448,
.fll_def = 2615,
- .llp = 3672,
+ .llp = { 3672, 5942 },
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_3268x2448_regs),
.regs = mode_3268x2448_regs,
@@ -389,7 +403,7 @@ static const struct imx355_mode supported_modes[] = {
.width = 3264,
.height = 2448,
.fll_def = 2615,
- .llp = 3672,
+ .llp = { 3672, 5942 },
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_3264x2448_regs),
.regs = mode_3264x2448_regs,
@@ -404,7 +418,7 @@ static const struct imx355_mode supported_modes[] = {
.width = 1940,
.height = 1096,
.fll_def = 1306,
- .llp = 3672,
+ .llp = { 3672, 5942 },
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1940x1096_regs),
.regs = mode_1940x1096_regs,
@@ -419,7 +433,7 @@ static const struct imx355_mode supported_modes[] = {
.width = 1936,
.height = 1096,
.fll_def = 1306,
- .llp = 3672,
+ .llp = { 3672, 5942 },
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1936x1096_regs),
.regs = mode_1936x1096_regs,
@@ -434,7 +448,7 @@ static const struct imx355_mode supported_modes[] = {
.width = 1924,
.height = 1080,
.fll_def = 1306,
- .llp = 3672,
+ .llp = { 3672, 5942 },
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1924x1080_regs),
.regs = mode_1924x1080_regs,
@@ -449,7 +463,7 @@ static const struct imx355_mode supported_modes[] = {
.width = 1920,
.height = 1080,
.fll_def = 1306,
- .llp = 3672,
+ .llp = { 3672, 5942 },
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1920x1080_regs),
.regs = mode_1920x1080_regs,
@@ -464,7 +478,7 @@ static const struct imx355_mode supported_modes[] = {
.width = 1640,
.height = 1232,
.fll_def = 1306,
- .llp = 1836,
+ .llp = { 1836, 2970 },
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1640x1232_regs),
.regs = mode_1640x1232_regs,
@@ -479,7 +493,7 @@ static const struct imx355_mode supported_modes[] = {
.width = 1640,
.height = 922,
.fll_def = 1306,
- .llp = 1836,
+ .llp = { 1836, 2970 },
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1640x922_regs),
.regs = mode_1640x922_regs,
@@ -494,7 +508,7 @@ static const struct imx355_mode supported_modes[] = {
.width = 1300,
.height = 736,
.fll_def = 1306,
- .llp = 1836,
+ .llp = { 1836, 2970 },
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1300x736_regs),
.regs = mode_1300x736_regs,
@@ -509,7 +523,7 @@ static const struct imx355_mode supported_modes[] = {
.width = 1296,
.height = 736,
.fll_def = 1306,
- .llp = 1836,
+ .llp = { 1836, 2970 },
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1296x736_regs),
.regs = mode_1296x736_regs,
@@ -524,7 +538,7 @@ static const struct imx355_mode supported_modes[] = {
.width = 1284,
.height = 720,
.fll_def = 1306,
- .llp = 1836,
+ .llp = { 1836, 2970 },
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1284x720_regs),
.regs = mode_1284x720_regs,
@@ -539,7 +553,7 @@ static const struct imx355_mode supported_modes[] = {
.width = 1280,
.height = 720,
.fll_def = 1306,
- .llp = 1836,
+ .llp = { 1836, 2970 },
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_1280x720_regs),
.regs = mode_1280x720_regs,
@@ -554,7 +568,7 @@ static const struct imx355_mode supported_modes[] = {
.width = 820,
.height = 616,
.fll_def = 652,
- .llp = 3672,
+ .llp = { 3672, 5942 },
.reg_list = {
.num_of_regs = ARRAY_SIZE(mode_820x616_regs),
.regs = mode_820x616_regs,
@@ -804,7 +818,8 @@ imx355_set_pad_format(struct v4l2_subdev *sd,
__v4l2_ctrl_modify_range(imx355->vblank, IMX355_FLL_OFFSET,
height, 1, vblank_def);
__v4l2_ctrl_s_ctrl(imx355->vblank, vblank_def);
- h_blank = mode->llp - imx355->cur_mode->width;
+ h_blank = mode->llp[imx355->hwcfg->num_lanes == 4 ? 0 : 1] -
+ imx355->cur_mode->width;
/*
* Currently hblank is not changeable.
* So FPS control is done only by vblank.
@@ -869,6 +884,7 @@ static int imx355_start_streaming(struct imx355 *imx355)
{
const struct imx355_reg_list *reg_list;
const struct imx355_mode *mode;
+ int lane_idx = imx355->hwcfg->num_lanes == 4 ? 0 : 1;
int ret = 0;
/* Global Setting */
@@ -900,9 +916,19 @@ static int imx355_start_streaming(struct imx355 *imx355)
cci_write(imx355->regmap, IMX355_REG_EXTCLK_FREQ,
imx355->clk_params->extclk_freq, &ret);
cci_write(imx355->regmap, IMX355_REG_PLL_VT_MUL,
- imx355->clk_params->pll_vt_mpy, &ret);
+ imx355->clk_params->pll_vt_mpy[lane_idx], &ret);
cci_write(imx355->regmap, IMX355_REG_PLL_OP_MUL,
- imx355->clk_params->pll_op_mpy, &ret);
+ imx355->clk_params->pll_op_mpy[lane_idx], &ret);
+ cci_write(imx355->regmap, IMX355_REG_PLL_MODE, lane_idx ? 0x01 : 0x00,
+ &ret);
+
+ /* Set MIPI configuration */
+ cci_write(imx355->regmap, IMX355_REG_LANE_SEL,
+ imx355->hwcfg->num_lanes - 1, &ret);
+
+ cci_write(imx355->regmap, IMX355_REG_REQ_LINK_BIT_RATE,
+ (imx355->link_freq->qmenu_int[imx355->link_freq->val] *
+ imx355->hwcfg->num_lanes * 2) / 1000000, &ret);
/* set digital gain control to all color mode */
cci_write(imx355->regmap, IMX355_REG_DPGA_USE_GLOBAL_GAIN, 1, &ret);
@@ -1072,8 +1098,8 @@ static int imx355_init_controls(struct imx355 *imx355)
s64 exposure_max;
s64 vblank_def;
s64 hblank;
- u64 pixel_rate;
const struct imx355_mode *mode;
+ const s64 *link_freq_menu;
u32 max;
int ret;
@@ -1083,19 +1109,21 @@ static int imx355_init_controls(struct imx355 *imx355)
return ret;
ctrl_hdlr->lock = &imx355->mutex;
- max = ARRAY_SIZE(link_freq_menu_items) - 1;
+
+ link_freq_menu = imx355->hwcfg->num_lanes == 4 ?
+ link_freq_menu_items_4lane :
+ link_freq_menu_items_2lane;
+ max = ARRAY_SIZE(link_freq_menu_items_4lane) - 1;
imx355->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, &imx355_ctrl_ops,
V4L2_CID_LINK_FREQ, max, 0,
- link_freq_menu_items);
+ link_freq_menu);
if (imx355->link_freq)
imx355->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
- /* pixel_rate = link_freq * 2 * nr_of_lanes / bits_per_sample */
- pixel_rate = IMX355_LINK_FREQ_DEFAULT * 2 * 4;
- do_div(pixel_rate, 10);
/* By default, PIXEL_RATE is read only */
v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops, V4L2_CID_PIXEL_RATE,
- pixel_rate, pixel_rate, 1, pixel_rate);
+ IMX355_PIXEL_RATE, IMX355_PIXEL_RATE, 1,
+ IMX355_PIXEL_RATE);
/* Initialize vblank/hblank/exposure parameters based on current mode */
mode = imx355->cur_mode;
@@ -1105,7 +1133,7 @@ static int imx355_init_controls(struct imx355 *imx355)
IMX355_FLL_MAX - mode->height,
1, vblank_def);
- hblank = mode->llp - mode->width;
+ hblank = mode->llp[imx355->hwcfg->num_lanes == 4 ? 0 : 1] - mode->width;
imx355->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx355_ctrl_ops,
V4L2_CID_HBLANK, hblank, hblank,
1, hblank);
@@ -1192,13 +1220,18 @@ static struct imx355_hwcfg *imx355_get_hwcfg(struct device *dev)
if (!cfg)
goto out_err;
- if (bus_cfg.bus.mipi_csi2.num_data_lanes != IMX355_DATA_LANES)
+ if (bus_cfg.bus.mipi_csi2.num_data_lanes != 2 &&
+ bus_cfg.bus.mipi_csi2.num_data_lanes != 4)
goto out_err;
+ cfg->num_lanes = bus_cfg.bus.mipi_csi2.num_data_lanes;
+
ret = v4l2_link_freq_to_bitmap(dev, bus_cfg.link_frequencies,
bus_cfg.nr_of_link_frequencies,
- link_freq_menu_items,
- ARRAY_SIZE(link_freq_menu_items),
+ cfg->num_lanes == 4 ?
+ link_freq_menu_items_4lane :
+ link_freq_menu_items_2lane,
+ ARRAY_SIZE(link_freq_menu_items_4lane),
&cfg->link_freq_bitmap);
if (ret)
goto out_err;
--
2.34.1
^ permalink raw reply related [flat|nested] 29+ messages in thread