From c3de70f4153b43a7bac761712358b2d55fcbf589 Mon Sep 17 00:00:00 2001 From: Jacobe Zang Date: Wed, 21 Aug 2024 19:46:34 +0800 Subject: [PATCH] media: i2c: os08a10: add 4k@30fps config as default for 2-lanes Signed-off-by: Jacobe Zang Change-Id: Iae229323ff7c2eb9e2f4089ac7985f7d85c3d845 --- .../rockchip/rk3588s-khadas-edge2-camera.dtsi | 8 +- drivers/media/i2c/os08a10.c | 275 +++++++++++++++++- 2 files changed, 266 insertions(+), 17 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2-camera.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2-camera.dtsi index 57961730b50ee..cbc28f7e96848 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2-camera.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2-camera.dtsi @@ -24,7 +24,7 @@ mipi_in_dcphy2: endpoint@2 { reg = <2>; remote-endpoint = <&os08a10b_out0>; - data-lanes = <1 2 3 4>; + data-lanes = <1 2>; }; }; port@1 { @@ -63,7 +63,7 @@ mipi_in_dcphy3: endpoint@2 { reg = <2>; remote-endpoint = <&os08a10f_out1>; - data-lanes = <1 2 3 4>; + data-lanes = <1 2>; }; }; port@1 { @@ -184,7 +184,7 @@ port { os08a10b_out0: endpoint { remote-endpoint = <&mipi_in_dcphy2>; - data-lanes = <1 2 3 4>; + data-lanes = <1 2>; }; }; }; @@ -252,7 +252,7 @@ port { os08a10f_out1: endpoint { remote-endpoint = <&mipi_in_dcphy3>; - data-lanes = <1 2 3 4>; + data-lanes = <1 2>; }; }; }; diff --git a/drivers/media/i2c/os08a10.c b/drivers/media/i2c/os08a10.c index ce34c33409960..61a742677d0e2 100644 --- a/drivers/media/i2c/os08a10.c +++ b/drivers/media/i2c/os08a10.c @@ -88,7 +88,8 @@ #define OS08A10_REG_VALUE_16BIT 2 #define OS08A10_REG_VALUE_24BIT 3 -#define OS08A10_LANES 4 +#define OS08A10_4LANES 4 +#define OS08A10_2LANES 2 #define OS08A10_BITS_PER_SAMPLE 10 #define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default" @@ -359,6 +360,203 @@ static const struct regval os08a10_global_regs[] = { {REG_NULL, 0x00}, }; +static const struct regval os08a10_global_regs_2lane[] = { + {0x0100, 0x00}, + {0x0103, 0x01}, + {0x0303, 0x01}, + {0x0305, 0x5a}, + {0x0306, 0x00}, + {0x0308, 0x03}, + {0x0309, 0x04}, + {0x032a, 0x00}, + {0x300f, 0x11}, + {0x3010, 0x01}, + {0x3011, 0x04}, + {0x3012, 0x21}, + {0x3016, 0xf0}, + {0x301e, 0x98}, + {0x3031, 0xa9}, + {0x3103, 0x92}, + {0x3104, 0x01}, + {0x3106, 0x10}, + {0x3400, 0x04}, + {0x3025, 0x03}, + {0x3425, 0x01}, + {0x3428, 0x01}, + {0x3406, 0x08}, + {0x3408, 0x03}, + {0x340c, 0xff}, + {0x340d, 0xff}, + {0x031e, 0x09}, + {0x3501, 0x08}, + {0x3502, 0xe5}, + {0x3505, 0x83}, + {0x3508, 0x00}, + {0x3509, 0x80}, + {0x350a, 0x04}, + {0x350b, 0x00}, + {0x350c, 0x00}, + {0x350d, 0x80}, + {0x350e, 0x04}, + {0x350f, 0x00}, + {0x3600, 0x00}, + {0x3603, 0x2c}, + {0x3605, 0x50}, + {0x3609, 0xb5}, + {0x3610, 0x39}, + {0x360c, 0x01}, + {0x3628, 0xa4}, + {0x362d, 0x10}, + {0x3660, 0x43}, + {0x3661, 0x06}, + {0x3662, 0x00}, + {0x3663, 0x28}, + {0x3664, 0x0d}, + {0x366a, 0x38}, + {0x366b, 0xa0}, + {0x366d, 0x00}, + {0x366e, 0x00}, + {0x3680, 0x00}, + {0x36c0, 0x00}, + {0x3701, 0x02}, + {0x373b, 0x02}, + {0x373c, 0x02}, + {0x3736, 0x02}, + {0x3737, 0x02}, + {0x3705, 0x00}, + {0x3706, 0x39}, + {0x370a, 0x00}, + {0x370b, 0x98}, + {0x3709, 0x49}, + {0x3714, 0x21}, + {0x371c, 0x00}, + {0x371d, 0x08}, + {0x3740, 0x1b}, + {0x3741, 0x04}, + {0x375e, 0x0b}, + {0x3760, 0x10}, + {0x3776, 0x10}, + {0x3781, 0x02}, + {0x3782, 0x04}, + {0x3783, 0x02}, + {0x3784, 0x08}, + {0x3785, 0x08}, + {0x3788, 0x01}, + {0x3789, 0x01}, + {0x3797, 0x04}, + {0x3762, 0x11}, + {0x3800, 0x00}, + {0x3801, 0x00}, + {0x3802, 0x00}, + {0x3803, 0x0c}, + {0x3804, 0x0e}, + {0x3805, 0xff}, + {0x3806, 0x08}, + {0x3807, 0x6f}, + {0x3808, 0x0f}, + {0x3809, 0x00}, + {0x380a, 0x08}, + {0x380b, 0x70}, + {0x380c, 0x08}, + {0x380d, 0x18}, + {0x380e, 0x09}, + {0x380f, 0x0a}, + {0x3813, 0x10}, + {0x3814, 0x01}, + {0x3815, 0x01}, + {0x3816, 0x01}, + {0x3817, 0x01}, + {0x381c, 0x00}, + {0x3820, 0x00}, + {0x3821, 0x04}, + {0x3823, 0x08}, + {0x3826, 0x00}, + {0x3827, 0x08}, + {0x382d, 0x08}, + {0x3832, 0x02}, + {0x3833, 0x00}, + {0x383c, 0x48}, + {0x383d, 0xff}, + {0x3d85, 0x0b}, + {0x3d84, 0x40}, + {0x3d8c, 0x63}, + {0x3d8d, 0xd7}, + {0x4000, 0xf8}, + {0x4001, 0x2b}, + {0x4004, 0x00}, + {0x4005, 0x40}, + {0x400a, 0x01}, + {0x400f, 0xa0}, + {0x4010, 0x12}, + {0x4018, 0x00}, + {0x4008, 0x02}, + {0x4009, 0x0d}, + {0x401a, 0x58}, + {0x4050, 0x00}, + {0x4051, 0x01}, + {0x4028, 0x2f}, + {0x4052, 0x00}, + {0x4053, 0x80}, + {0x4054, 0x00}, + {0x4055, 0x80}, + {0x4056, 0x00}, + {0x4057, 0x80}, + {0x4058, 0x00}, + {0x4059, 0x80}, + {0x430b, 0xff}, + {0x430c, 0xff}, + {0x430d, 0x00}, + {0x430e, 0x00}, + {0x4501, 0x18}, + {0x4502, 0x00}, + {0x4643, 0x00}, + {0x4640, 0x01}, + {0x4641, 0x04}, + {0x4800, 0x64}, + {0x4809, 0x2b}, + {0x4813, 0x90}, + {0x4817, 0x04}, + {0x4833, 0x18}, + {0x4837, 0x0b}, + {0x483b, 0x00}, + {0x484b, 0x03}, + {0x4850, 0x7c}, + {0x4852, 0x06}, + {0x4856, 0x58}, + {0x4857, 0xaa}, + {0x4862, 0x0a}, + {0x4869, 0x18}, + {0x486a, 0xaa}, + {0x486e, 0x03}, + {0x486f, 0x55}, + {0x4875, 0xf0}, + {0x5000, 0x89}, + {0x5001, 0x42}, + {0x5004, 0x40}, + {0x5005, 0x00}, + {0x5180, 0x00}, + {0x5181, 0x10}, + {0x580b, 0x03}, + {0x4d00, 0x03}, + {0x4d01, 0xc9}, + {0x4d02, 0xbc}, + {0x4d03, 0xc6}, + {0x4d04, 0x4a}, + {0x4d05, 0x25}, + {REG_NULL, 0x00}, +}; + +static const struct regval os08a10_3840x2160_regs_2lane[] = { + {0x4700, 0x2b}, + {0x4e00, 0x2b}, + {0x3501, 0x09}, + {0x3502, 0x01}, + {0x0100, 0x01}, + {0x0100, 0x01}, + {0x0100, 0x01}, + {0x0100, 0x01}, + {REG_NULL, 0x00}, +}; /* * Xclk 24Mhz * Pclk 210Mhz @@ -405,6 +603,22 @@ static const struct os08a10_mode supported_modes_4lane[] = { }, }; +static const struct os08a10_mode supported_modes_2lane[] = { + { + .width = 3840, + .height = 2160, + .max_fps = { + .numerator = 10000, + .denominator = 300000, + }, + .exp_def = 0x08f6-8, + .hts_def = 0x898 * 2, + .vts_def = 0x08f6, + .reg_list = os08a10_3840x2160_regs_2lane, + .hdr_mode = NO_HDR, + }, +}; + static const struct os08a10_mode *supported_modes; static const s64 link_freq_menu_items[] = { @@ -945,12 +1159,20 @@ static int os08a10_s_power(struct v4l2_subdev *sd, int on) pm_runtime_put_noidle(&client->dev); goto unlock_and_return; } - - ret = os08a10_write_array(os08a10->client, os08a10_global_regs); - if (ret) { - v4l2_err(sd, "could not set init registers\n"); - pm_runtime_put_noidle(&client->dev); - goto unlock_and_return; + if(os08a10->lane_num == 4){ + ret = os08a10_write_array(os08a10->client, os08a10_global_regs); + if (ret) { + v4l2_err(sd, "could not set init registers\n"); + pm_runtime_put_noidle(&client->dev); + goto unlock_and_return; + } + } else if (os08a10->lane_num == 2) { + ret = os08a10_write_array(os08a10->client, os08a10_global_regs_2lane); + if (ret) { + v4l2_err(sd, "could not set init registers\n"); + pm_runtime_put_noidle(&client->dev); + goto unlock_and_return; + } } os08a10->power_on = true; @@ -1110,9 +1332,31 @@ static int os08a10_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id, struct v4l2_mbus_config *config) { - config->type = V4L2_MBUS_CSI2_DPHY; - config->bus.mipi_csi2.num_data_lanes = OS08A10_LANES; + struct os08a10 *os08a10 = to_os08a10(sd); + struct device *dev = &os08a10->client->dev; + struct device_node *endpoint; + struct fwnode_handle *fwnode; + int rval; + endpoint = of_graph_get_next_endpoint(dev->of_node, NULL); + if (!endpoint) { + dev_err(dev, "Failed to get endpoint\n"); + return -EINVAL; + } + fwnode = of_fwnode_handle(endpoint); + rval = fwnode_property_read_u32_array(fwnode, "data-lanes", NULL, 0); + if (rval <= 0) { + dev_warn(dev, " Get mipi lane num failed!\n"); + return -1; + } + + os08a10->lane_num = rval; + config->type = V4L2_MBUS_CSI2_DPHY; + if (4 == os08a10->lane_num) { + config->bus.mipi_csi2.num_data_lanes = OS08A10_4LANES; + } else { + config->bus.mipi_csi2.num_data_lanes = OS08A10_2LANES; + } return 0; } @@ -1364,16 +1608,21 @@ static int os08a10_parse_of(struct os08a10 *os08a10) os08a10->cur_mode = &supported_modes_4lane[0]; supported_modes = supported_modes_4lane; os08a10->cfg_num = ARRAY_SIZE(supported_modes_4lane); - - /* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */ os08a10->pixel_rate = MIPI_FREQ * 2U * os08a10->lane_num / 8U; - dev_info(dev, "lane_num(%d) pixel_rate(%u)\n", - os08a10->lane_num, os08a10->pixel_rate); + } else if (2 == os08a10->lane_num) { + os08a10->cur_mode = &supported_modes_2lane[0]; + supported_modes = supported_modes_2lane; + os08a10->cfg_num = ARRAY_SIZE(supported_modes_2lane); + os08a10->pixel_rate = MIPI_FREQ * 2U * os08a10->lane_num / 4U; } else { dev_err(dev, "unsupported lane_num(%d)\n", os08a10->lane_num); return -1; } + /* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */ + dev_info(dev, "lane_num(%d) pixel_rate(%u)\n", + os08a10->lane_num, os08a10->pixel_rate); + return 0; }