diff --git a/drivers/media/i2c/ov05c10.c b/drivers/media/i2c/ov05c10.c index 47a7aae69d0e..bd83455e92fa 100644 --- a/drivers/media/i2c/ov05c10.c +++ b/drivers/media/i2c/ov05c10.c @@ -64,6 +64,7 @@ static const char *const ov05c10_test_pattern_menu[] = { "Color Bar", }; static const s64 ov05c10_link_freq_menu_items[] = { + 900000000ULL, 480000000ULL, }; @@ -115,6 +116,155 @@ static const struct cci_reg_sequence ov05c10_trigger[] = { { CCI_REG8(0x01), 0x01 }, }; +static const struct cci_reg_sequence mode_2888_1808_30fps[] = { + { CCI_REG8(0xfd), 0x00 }, + { CCI_REG8(0x20), 0x00 }, + { CCI_REG8(0xfd), 0x00 }, + { CCI_REG8(0x20), 0x0b }, + { CCI_REG8(0xc1), 0x09 }, + { CCI_REG8(0x21), 0x06 }, + { CCI_REG8(0x14), 0x78 }, + { CCI_REG8(0xe7), 0x03 }, + { CCI_REG8(0xe7), 0x00 }, + { CCI_REG8(0x21), 0x00 }, + //19.2MHz + { CCI_REG8(0x14), 0x96 }, + { CCI_REG8(0x1b), 0xbb }, + + { CCI_REG8(0xfd), 0x01 }, + { CCI_REG8(0x03), 0x00 }, + { CCI_REG8(0x04), 0x06 }, + { CCI_REG8(0x05), 0x06 }, // VTS, for 30.5 fps - from 20251015 James + { CCI_REG8(0x06), 0xf4 }, // VTS, for 30.5 fps - from 20251015 James + { CCI_REG8(0x07), 0x08 }, + { CCI_REG8(0x1b), 0x01 }, + { CCI_REG8(0x24), 0xff }, + { CCI_REG8(0x42), 0x5d }, + { CCI_REG8(0x43), 0x08 }, + { CCI_REG8(0x44), 0x81 }, + { CCI_REG8(0x46), 0x5f }, + { CCI_REG8(0x48), 0x18 }, + { CCI_REG8(0x49), 0x04 }, + { CCI_REG8(0x5c), 0x18 }, + { CCI_REG8(0x5e), 0x13 }, + { CCI_REG8(0x70), 0x15 }, + { CCI_REG8(0x77), 0x35 }, + { CCI_REG8(0x79), 0x00 }, + { CCI_REG8(0x7b), 0x08 }, + { CCI_REG8(0x7d), 0x08 }, + { CCI_REG8(0x7e), 0x08 }, + { CCI_REG8(0x7f), 0x08 }, + { CCI_REG8(0x90), 0x37 }, + { CCI_REG8(0x91), 0x05 }, + { CCI_REG8(0x92), 0x18 }, + { CCI_REG8(0x93), 0x27 }, + { CCI_REG8(0x94), 0x05 }, + { CCI_REG8(0x95), 0x38 }, + { CCI_REG8(0x9b), 0x00 }, + { CCI_REG8(0x9c), 0x06 }, + { CCI_REG8(0x9d), 0x28 }, + { CCI_REG8(0x9e), 0x06 }, + { CCI_REG8(0xb2), 0x0d }, // 0f;V1.13 + { CCI_REG8(0xb3), 0x29 }, + { CCI_REG8(0xbf), 0x3c }, + { CCI_REG8(0xc2), 0x04 }, + { CCI_REG8(0xc4), 0x00 }, + { CCI_REG8(0xca), 0x20 }, + { CCI_REG8(0xcb), 0x20 }, + { CCI_REG8(0xcc), 0x28 }, + { CCI_REG8(0xcd), 0x28 }, + { CCI_REG8(0xce), 0x20 }, + { CCI_REG8(0xcf), 0x20 }, + { CCI_REG8(0xd0), 0x2a }, + { CCI_REG8(0xd1), 0x2a }, + + { CCI_REG8(0xfd), 0x0f }, + { CCI_REG8(0x00), 0x00 }, + { CCI_REG8(0x01), 0xa0 }, + { CCI_REG8(0x02), 0x48 }, + { CCI_REG8(0x07), 0x8e }, //V1.13 + { CCI_REG8(0x08), 0x70 }, + { CCI_REG8(0x09), 0x01 }, + { CCI_REG8(0x0b), 0x40 }, + { CCI_REG8(0x0d), 0x07 }, + { CCI_REG8(0x11), 0x33 }, + { CCI_REG8(0x12), 0x77 }, + { CCI_REG8(0x13), 0x66 }, + { CCI_REG8(0x14), 0x65 }, + { CCI_REG8(0x15), 0x37 }, + { CCI_REG8(0x16), 0xbf }, + { CCI_REG8(0x17), 0xff }, + { CCI_REG8(0x18), 0xff }, + { CCI_REG8(0x19), 0x12 }, + { CCI_REG8(0x1a), 0x10 }, + { CCI_REG8(0x1c), 0x77 }, + { CCI_REG8(0x1d), 0x77 }, + { CCI_REG8(0x20), 0x0f }, + { CCI_REG8(0x21), 0x0f }, + { CCI_REG8(0x22), 0x0f }, + { CCI_REG8(0x23), 0x0f }, + { CCI_REG8(0x2b), 0x20 }, + { CCI_REG8(0x2c), 0x20 }, + { CCI_REG8(0x2d), 0x04 }, + { CCI_REG8(0xfd), 0x03 }, + { CCI_REG8(0x9d), 0x0f }, + { CCI_REG8(0x9f), 0x40 }, + { CCI_REG8(0xfd), 0x00 }, + { CCI_REG8(0x20), 0x1b }, + { CCI_REG8(0xfd), 0x04 }, + { CCI_REG8(0x19), 0x60 }, + { CCI_REG8(0xfd), 0x02 }, + { CCI_REG8(0x75), 0x05 }, + { CCI_REG8(0x7f), 0x06 }, + { CCI_REG8(0x9a), 0x03 }, + { CCI_REG8(0xa1), 0x01 }, // GRBG github:75 + { CCI_REG8(0xa2), 0x07 }, + { CCI_REG8(0xa3), 0x10 }, + { CCI_REG8(0xa5), 0x02 }, + { CCI_REG8(0xa6), 0x0b }, // hsize[11:8] + { CCI_REG8(0xa7), 0x48 }, // hsize[7:0] + + { CCI_REG8(0xfd), 0x07 }, + { CCI_REG8(0x42), 0x00 }, + { CCI_REG8(0x43), 0x80 }, + { CCI_REG8(0x44), 0x00 }, + { CCI_REG8(0x45), 0x80 }, + { CCI_REG8(0x46), 0x00 }, + { CCI_REG8(0x47), 0x80 }, + { CCI_REG8(0x48), 0x00 }, + { CCI_REG8(0x49), 0x80 }, + { CCI_REG8(0x00), 0xf7 }, + { CCI_REG8(0xfd), 0x00 }, + { CCI_REG8(0xe7), 0x03 }, + { CCI_REG8(0xe7), 0x00 }, + { CCI_REG8(0xfd), 0x00 }, + { CCI_REG8(0x8e), 0x0b }, // hsize[11:8] + { CCI_REG8(0x8f), 0x48 }, // hsize[7:0] + { CCI_REG8(0x93), 0x18 }, + { CCI_REG8(0x94), 0xff }, + { CCI_REG8(0x95), 0xbd }, + { CCI_REG8(0x96), 0x1a }, + { CCI_REG8(0x98), 0x04 }, + { CCI_REG8(0x99), 0x08 }, + { CCI_REG8(0x9b), 0x10 }, + { CCI_REG8(0x9c), 0x3f }, + { CCI_REG8(0xa1), 0x05 }, + { CCI_REG8(0xa4), 0x2f }, + { CCI_REG8(0xc0), 0x0c }, + { CCI_REG8(0xc1), 0x08 }, + { CCI_REG8(0xc2), 0x00 }, + { CCI_REG8(0xb6), 0x20 }, + { CCI_REG8(0xbb), 0x80 }, + { CCI_REG8(0xfd), 0x00 }, + { CCI_REG8(0xa0), 0x00 }, // disable MIPI + { CCI_REG8(0xfd), 0x01 }, + { CCI_REG8(0x33), 0x03 }, + { CCI_REG8(0x01), 0x02 }, + { CCI_REG8(0xfd), 0x00 }, + { CCI_REG8(0x20), 0x1f }, + { CCI_REG8(0xfd), 0x01 }, +}; + //2800X1576_2lane_raw10_Mclk19.2M_pclk96M_30fps static const struct cci_reg_sequence mode_2800_1576_30fps[] = { { CCI_REG8(0xfd), 0x00 }, @@ -269,6 +419,20 @@ static const struct cci_reg_sequence mode_2800_1576_30fps[] = { }; static const struct ov05c10_mode supported_modes[] = { + { + .width = 2888, + .height = 1808, + .hts = 1608, + .vts_def = 3720, + .vts_min = 3720, + .code = MEDIA_BUS_FMT_SGRBG10_1X10, + .fps = 30, + .reg_list = { + .num_of_regs = ARRAY_SIZE(mode_2888_1808_30fps), + .regs = mode_2888_1808_30fps, + }, + .link_freq_index = 0, + }, { .width = 2800, .height = 1576, @@ -281,7 +445,7 @@ static const struct ov05c10_mode supported_modes[] = { .num_of_regs = ARRAY_SIZE(mode_2800_1576_30fps), .regs = mode_2800_1576_30fps, }, - .link_freq_index = 0, + .link_freq_index = 1, }, }; @@ -304,7 +468,9 @@ struct ov05c10 { struct clk *img_clk; struct regulator *avdd; + struct regulator *dvdd; struct gpio_desc *reset; + struct mutex mutex; }; static int ov05c10_test_pattern(struct ov05c10 *ov05c10, u32 pattern) @@ -366,7 +532,7 @@ static int ov05c10_set_ctrl(struct v4l2_ctrl *ctrl) ret = cci_write(ov05c10->regmap, REG_PAGE_FLAG, PAGE_1, NULL); if (ret) { - dev_err(&client->dev, "failed to set ctrl"); + dev_err(&client->dev, "failed to set ctrl\n"); goto err; } @@ -531,7 +697,7 @@ static int ov05c10_stop_streaming(struct ov05c10 *ov05c10) ret = cci_multi_reg_write(ov05c10->regmap, ov05c10_soft_standby, ARRAY_SIZE(ov05c10_soft_standby), NULL); if (ret < 0) - dev_err(&client->dev, "failed to stop stream"); + dev_err(&client->dev, "failed to stop stream\n"); pm_runtime_put(&client->dev); return ret; @@ -683,8 +849,8 @@ static int ov05c10_init_state(struct v4l2_subdev *sd, .pad = 0, .format = { .code = MEDIA_BUS_FMT_SGRBG10_1X10, - .width = 2800, - .height = 1576, + .width = 2888, + .height = 1808, }, }; @@ -821,11 +987,19 @@ static int ov05c10_get_pm_resources(struct device *dev) "failed to get avdd regulator\n"); } + ov05c10->dvdd = devm_regulator_get_optional(dev, "dvdd"); + if (IS_ERR(ov05c10->dvdd)) { + ret = PTR_ERR(ov05c10->dvdd); + ov05c10->dvdd = NULL; + if (ret != -ENODEV) + return dev_err_probe(dev, ret, + "failed to get dvdd regulator\n"); + } + ov05c10->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(ov05c10->reset)) return dev_err_probe(dev, PTR_ERR(ov05c10->reset), "failed to get reset gpio\n"); - return 0; } @@ -840,6 +1014,9 @@ static int ov05c10_power_off(struct device *dev) if (ov05c10->avdd) regulator_disable(ov05c10->avdd); + if (ov05c10->dvdd) + regulator_disable(ov05c10->dvdd); + clk_disable_unprepare(ov05c10->img_clk); return 0; @@ -866,6 +1043,15 @@ static int ov05c10_power_on(struct device *dev) } } + if (ov05c10->dvdd) { + ret = regulator_enable(ov05c10->dvdd); + if (ret < 0) { + dev_err(dev, "failed to enable dvdd: %d", ret); + clk_disable_unprepare(ov05c10->img_clk); + return ret; + } + } + if (ov05c10->reset) { gpiod_set_value_cansleep(ov05c10->reset, 0); /* 5ms to wait ready after XSHUTDN assert */ diff --git a/patch/v6.17/0004-media-ipu-bridge-Add-linkfreq-ov05c10-sensor.patch b/patch/v6.17/0004-media-ipu-bridge-Add-linkfreq-ov05c10-sensor.patch new file mode 100644 index 000000000000..834dcf776f76 --- /dev/null +++ b/patch/v6.17/0004-media-ipu-bridge-Add-linkfreq-ov05c10-sensor.patch @@ -0,0 +1,13 @@ +diff --git a/drivers/media/pci/intel/ipu-bridge.c b/drivers/media/pci/intel/ipu-bridge.c +index 4e579352ab2c..5147c052d53b 100644 +--- a/drivers/media/pci/intel/ipu-bridge.c ++++ b/drivers/media/pci/intel/ipu-bridge.c +@@ -79,6 +79,8 @@ static const struct ipu_sensor_config ipu_supported_sensors[] = { + IPU_SENSOR_CONFIG("OVTI02C1", 1, 400000000), + /* Omnivision OV02E10 */ + IPU_SENSOR_CONFIG("OVTI02E1", 1, 360000000), ++ /* Omnivision ov05c10 */ ++ IPU_SENSOR_CONFIG("OVTI05C1", 2, 480000000, 900000000), + /* Omnivision OV08A10 */ + IPU_SENSOR_CONFIG("OVTI08A1", 1, 500000000), + /* Omnivision OV08x40 */ diff --git a/patch/v6.17/0005-platform-x86-int3472-handshake-delay-ov05c10-sensor.patch b/patch/v6.17/0005-platform-x86-int3472-handshake-delay-ov05c10-sensor.patch new file mode 100644 index 000000000000..c7c62a5ddbb3 --- /dev/null +++ b/patch/v6.17/0005-platform-x86-int3472-handshake-delay-ov05c10-sensor.patch @@ -0,0 +1,13 @@ +diff --git a/drivers/platform/x86/intel/int3472/discrete.c b/drivers/platform/x86/intel/int3472/discrete.c +index bdfb8a800c54..52fafdefb317 100644 +--- a/drivers/platform/x86/intel/int3472/discrete.c ++++ b/drivers/platform/x86/intel/int3472/discrete.c +@@ -339,7 +339,7 @@ static int skl_int3472_handle_gpio_resources(struct acpi_resource *ares, + case INT3472_GPIO_TYPE_HANDSHAKE: + /* Setups using a handshake pin need 25 ms enable delay */ + ret = skl_int3472_register_regulator(int3472, gpio, +- 25 * USEC_PER_MSEC, ++ 50 * USEC_PER_MSEC, // Himax needs 50 ms + con_id, NULL); + if (ret) + err_msg = "Failed to map handshake to sensor\n";