Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions arch/arm64/boot/dts/rockchip/rk3588s-khadas-edge2-camera.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -184,7 +184,7 @@
port {
os08a10b_out0: endpoint {
remote-endpoint = <&mipi_in_dcphy2>;
data-lanes = <1 2 3 4>;
data-lanes = <1 2>;
};
};
};
Expand Down Expand Up @@ -252,7 +252,7 @@
port {
os08a10f_out1: endpoint {
remote-endpoint = <&mipi_in_dcphy3>;
data-lanes = <1 2 3 4>;
data-lanes = <1 2>;
};
};
};
Expand Down
275 changes: 262 additions & 13 deletions drivers/media/i2c/os08a10.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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[] = {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down