aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-5.15/950-0817-media-i2c-imx258-Add-support-for-24MHz-clock.patch
diff options
context:
space:
mode:
authorÁlvaro Fernández Rojas <noltari@gmail.com>2022-05-16 23:40:32 +0200
committerÁlvaro Fernández Rojas <noltari@gmail.com>2022-05-17 15:11:22 +0200
commit20ea6adbf199097c4f5f591ffee088340630dae4 (patch)
treed6719d95e136611a1c25bbf7789652d6d402779d /target/linux/bcm27xx/patches-5.15/950-0817-media-i2c-imx258-Add-support-for-24MHz-clock.patch
parentbca05bd072180dc38ef740b37ded9572a6db1981 (diff)
downloadupstream-20ea6adbf199097c4f5f591ffee088340630dae4.tar.gz
upstream-20ea6adbf199097c4f5f591ffee088340630dae4.tar.bz2
upstream-20ea6adbf199097c4f5f591ffee088340630dae4.zip
bcm27xx: add support for linux v5.15
Build system: x86_64 Build-tested: bcm2708, bcm2709, bcm2710, bcm2711 Run-tested: bcm2708/RPiB+, bcm2709/RPi3B, bcm2710/RPi3B, bcm2711/RPi4B Signed-off-by: Marty Jones <mj8263788@gmail.com> Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Diffstat (limited to 'target/linux/bcm27xx/patches-5.15/950-0817-media-i2c-imx258-Add-support-for-24MHz-clock.patch')
-rw-r--r--target/linux/bcm27xx/patches-5.15/950-0817-media-i2c-imx258-Add-support-for-24MHz-clock.patch286
1 files changed, 286 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.15/950-0817-media-i2c-imx258-Add-support-for-24MHz-clock.patch b/target/linux/bcm27xx/patches-5.15/950-0817-media-i2c-imx258-Add-support-for-24MHz-clock.patch
new file mode 100644
index 0000000000..35df2d7cbb
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.15/950-0817-media-i2c-imx258-Add-support-for-24MHz-clock.patch
@@ -0,0 +1,286 @@
+From 08f30518ef7619a6d24b39c367bffb30ebf7196d Mon Sep 17 00:00:00 2001
+From: Dave Stevenson <dave.stevenson@raspberrypi.com>
+Date: Wed, 16 Jun 2021 13:08:00 +0100
+Subject: [PATCH] media: i2c: imx258: Add support for 24MHz clock
+
+There's no reason why the clock must be 19.2MHz and nothing
+else (indeed this isn't even a frequency listed in the datasheet),
+so add support for 24MHz as well.
+The PLL settings result in slightly different link frequencies,
+so parameterise those.
+
+Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
+---
+ drivers/media/i2c/imx258.c | 141 +++++++++++++++++++++++++++++--------
+ 1 file changed, 111 insertions(+), 30 deletions(-)
+
+--- a/drivers/media/i2c/imx258.c
++++ b/drivers/media/i2c/imx258.c
+@@ -77,9 +77,6 @@
+ #define REG_CONFIG_MIRROR_VFLIP 0x02
+ #define REG_CONFIG_FLIP_TEST_PATTERN 0x02
+
+-/* Input clock frequency in Hz */
+-#define IMX258_INPUT_CLOCK_FREQ 19200000
+-
+ struct imx258_reg {
+ u16 address;
+ u8 val;
+@@ -92,6 +89,7 @@ struct imx258_reg_list {
+
+ /* Link frequency config */
+ struct imx258_link_freq_config {
++ u64 link_frequency;
+ u32 pixels_per_line;
+
+ /* PLL registers for this link frequency */
+@@ -116,7 +114,9 @@ struct imx258_mode {
+ };
+
+ /* 4208x3120 needs 1267Mbps/lane, 4 lanes */
+-static const struct imx258_reg mipi_data_rate_1267mbps[] = {
++static const struct imx258_reg mipi_1267mbps_19_2mhz[] = {
++ { 0x0136, 0x13 },
++ { 0x0137, 0x33 },
+ { 0x0301, 0x05 },
+ { 0x0303, 0x02 },
+ { 0x0305, 0x03 },
+@@ -134,7 +134,29 @@ static const struct imx258_reg mipi_data
+ { 0x0823, 0xCC },
+ };
+
+-static const struct imx258_reg mipi_data_rate_640mbps[] = {
++static const struct imx258_reg mipi_1272mbps_24mhz[] = {
++ { 0x0136, 0x18 },
++ { 0x0137, 0x00 },
++ { 0x0301, 0x05 },
++ { 0x0303, 0x02 },
++ { 0x0305, 0x04 },
++ { 0x0306, 0x00 },
++ { 0x0307, 0xD4 },
++ { 0x0309, 0x0A },
++ { 0x030B, 0x01 },
++ { 0x030D, 0x02 },
++ { 0x030E, 0x00 },
++ { 0x030F, 0xD8 },
++ { 0x0310, 0x00 },
++ { 0x0820, 0x13 },
++ { 0x0821, 0x4C },
++ { 0x0822, 0xCC },
++ { 0x0823, 0xCC },
++};
++
++static const struct imx258_reg mipi_640mbps_19_2mhz[] = {
++ { 0x0136, 0x13 },
++ { 0x0137, 0x33 },
+ { 0x0301, 0x05 },
+ { 0x0303, 0x02 },
+ { 0x0305, 0x03 },
+@@ -152,9 +174,27 @@ static const struct imx258_reg mipi_data
+ { 0x0823, 0x00 },
+ };
+
++static const struct imx258_reg mipi_642mbps_24mhz[] = {
++ { 0x0136, 0x18 },
++ { 0x0137, 0x00 },
++ { 0x0301, 0x05 },
++ { 0x0303, 0x02 },
++ { 0x0305, 0x04 },
++ { 0x0306, 0x00 },
++ { 0x0307, 0x6B },
++ { 0x0309, 0x0A },
++ { 0x030B, 0x01 },
++ { 0x030D, 0x02 },
++ { 0x030E, 0x00 },
++ { 0x030F, 0xD8 },
++ { 0x0310, 0x00 },
++ { 0x0820, 0x0A },
++ { 0x0821, 0x00 },
++ { 0x0822, 0x00 },
++ { 0x0823, 0x00 },
++};
++
+ static const struct imx258_reg mode_4208x3120_regs[] = {
+- { 0x0136, 0x13 },
+- { 0x0137, 0x33 },
+ { 0x3051, 0x00 },
+ { 0x3052, 0x00 },
+ { 0x4E21, 0x14 },
+@@ -268,8 +308,6 @@ static const struct imx258_reg mode_4208
+ };
+
+ static const struct imx258_reg mode_2104_1560_regs[] = {
+- { 0x0136, 0x13 },
+- { 0x0137, 0x33 },
+ { 0x3051, 0x00 },
+ { 0x3052, 0x00 },
+ { 0x4E21, 0x14 },
+@@ -383,8 +421,6 @@ static const struct imx258_reg mode_2104
+ };
+
+ static const struct imx258_reg mode_1048_780_regs[] = {
+- { 0x0136, 0x13 },
+- { 0x0137, 0x33 },
+ { 0x3051, 0x00 },
+ { 0x3052, 0x00 },
+ { 0x4E21, 0x14 },
+@@ -531,10 +567,6 @@ static const char * const imx258_supply_
+
+ #define IMX258_NUM_SUPPLIES ARRAY_SIZE(imx258_supply_name)
+
+-/* Configurations for supported link frequencies */
+-#define IMX258_LINK_FREQ_634MHZ 633600000ULL
+-#define IMX258_LINK_FREQ_320MHZ 320000000ULL
+-
+ enum {
+ IMX258_LINK_FREQ_1267MBPS,
+ IMX258_LINK_FREQ_640MBPS,
+@@ -553,25 +585,55 @@ static u64 link_freq_to_pixel_rate(u64 f
+ }
+
+ /* Menu items for LINK_FREQ V4L2 control */
+-static const s64 link_freq_menu_items[] = {
++/* Configurations for supported link frequencies */
++#define IMX258_LINK_FREQ_634MHZ 633600000ULL
++#define IMX258_LINK_FREQ_320MHZ 320000000ULL
++
++static const s64 link_freq_menu_items_19_2[] = {
+ IMX258_LINK_FREQ_634MHZ,
+ IMX258_LINK_FREQ_320MHZ,
+ };
+
++/* Configurations for supported link frequencies */
++#define IMX258_LINK_FREQ_636MHZ 636000000ULL
++#define IMX258_LINK_FREQ_321MHZ 321000000ULL
++
++static const s64 link_freq_menu_items_24[] = {
++ IMX258_LINK_FREQ_636MHZ,
++ IMX258_LINK_FREQ_321MHZ,
++};
++
+ /* Link frequency configs */
+-static const struct imx258_link_freq_config link_freq_configs[] = {
++static const struct imx258_link_freq_config link_freq_configs_19_2[] = {
++ [IMX258_LINK_FREQ_1267MBPS] = {
++ .pixels_per_line = IMX258_PPL_DEFAULT,
++ .reg_list = {
++ .num_of_regs = ARRAY_SIZE(mipi_1267mbps_19_2mhz),
++ .regs = mipi_1267mbps_19_2mhz,
++ }
++ },
++ [IMX258_LINK_FREQ_640MBPS] = {
++ .pixels_per_line = IMX258_PPL_DEFAULT,
++ .reg_list = {
++ .num_of_regs = ARRAY_SIZE(mipi_640mbps_19_2mhz),
++ .regs = mipi_640mbps_19_2mhz,
++ }
++ },
++};
++
++static const struct imx258_link_freq_config link_freq_configs_24[] = {
+ [IMX258_LINK_FREQ_1267MBPS] = {
+ .pixels_per_line = IMX258_PPL_DEFAULT,
+ .reg_list = {
+- .num_of_regs = ARRAY_SIZE(mipi_data_rate_1267mbps),
+- .regs = mipi_data_rate_1267mbps,
++ .num_of_regs = ARRAY_SIZE(mipi_1272mbps_24mhz),
++ .regs = mipi_1272mbps_24mhz,
+ }
+ },
+ [IMX258_LINK_FREQ_640MBPS] = {
+ .pixels_per_line = IMX258_PPL_DEFAULT,
+ .reg_list = {
+- .num_of_regs = ARRAY_SIZE(mipi_data_rate_640mbps),
+- .regs = mipi_data_rate_640mbps,
++ .num_of_regs = ARRAY_SIZE(mipi_642mbps_24mhz),
++ .regs = mipi_642mbps_24mhz,
+ }
+ },
+ };
+@@ -630,6 +692,9 @@ struct imx258 {
+ /* Current mode */
+ const struct imx258_mode *cur_mode;
+
++ const struct imx258_link_freq_config *link_freq_configs;
++ const s64 *link_freq_menu_items;
++
+ /*
+ * Mutex for serialized access:
+ * Protect sensor module set pad format and start/stop streaming safely.
+@@ -958,7 +1023,7 @@ static int imx258_set_pad_format(struct
+ imx258->cur_mode = mode;
+ __v4l2_ctrl_s_ctrl(imx258->link_freq, mode->link_freq_index);
+
+- link_freq = link_freq_menu_items[mode->link_freq_index];
++ link_freq = imx258->link_freq_menu_items[mode->link_freq_index];
+ pixel_rate = link_freq_to_pixel_rate(link_freq);
+ __v4l2_ctrl_s_ctrl_int64(imx258->pixel_rate, pixel_rate);
+ /* Update limits and set FPS to default */
+@@ -972,7 +1037,7 @@ static int imx258_set_pad_format(struct
+ vblank_def);
+ __v4l2_ctrl_s_ctrl(imx258->vblank, vblank_def);
+ h_blank =
+- link_freq_configs[mode->link_freq_index].pixels_per_line
++ imx258->link_freq_configs[mode->link_freq_index].pixels_per_line
+ - imx258->cur_mode->width;
+ __v4l2_ctrl_modify_range(imx258->hblank, h_blank,
+ h_blank, 1, h_blank);
+@@ -992,7 +1057,7 @@ static int imx258_start_streaming(struct
+
+ /* Setup PLL */
+ link_freq_index = imx258->cur_mode->link_freq_index;
+- reg_list = &link_freq_configs[link_freq_index].reg_list;
++ reg_list = &imx258->link_freq_configs[link_freq_index].reg_list;
+ ret = imx258_write_regs(imx258, reg_list->regs, reg_list->num_of_regs);
+ if (ret) {
+ dev_err(&client->dev, "%s failed to set plls\n", __func__);
+@@ -1210,15 +1275,17 @@ static int imx258_init_controls(struct i
+ imx258->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr,
+ &imx258_ctrl_ops,
+ V4L2_CID_LINK_FREQ,
+- ARRAY_SIZE(link_freq_menu_items) - 1,
++ ARRAY_SIZE(link_freq_menu_items_19_2) - 1,
+ 0,
+- link_freq_menu_items);
++ imx258->link_freq_menu_items);
+
+ if (imx258->link_freq)
+ imx258->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+- pixel_rate_max = link_freq_to_pixel_rate(link_freq_menu_items[0]);
+- pixel_rate_min = link_freq_to_pixel_rate(link_freq_menu_items[1]);
++ pixel_rate_max =
++ link_freq_to_pixel_rate(imx258->link_freq_menu_items[0]);
++ pixel_rate_min =
++ link_freq_to_pixel_rate(imx258->link_freq_menu_items[1]);
+ /* By default, PIXEL_RATE is read only */
+ imx258->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &imx258_ctrl_ops,
+ V4L2_CID_PIXEL_RATE,
+@@ -1346,11 +1413,25 @@ static int imx258_probe(struct i2c_clien
+ "no clock provided, using clock-frequency property\n");
+
+ device_property_read_u32(&client->dev, "clock-frequency", &val);
++ } else if (IS_ERR(imx258->clk)) {
++ return dev_err_probe(&client->dev, PTR_ERR(imx258->clk),
++ "error getting clock\n");
+ } else {
+ val = clk_get_rate(imx258->clk);
+ }
+- if (val != IMX258_INPUT_CLOCK_FREQ) {
+- dev_err(&client->dev, "input clock frequency not supported\n");
++
++ switch (val) {
++ case 19200000:
++ imx258->link_freq_configs = link_freq_configs_19_2;
++ imx258->link_freq_menu_items = link_freq_menu_items_19_2;
++ break;
++ case 24000000:
++ imx258->link_freq_configs = link_freq_configs_24;
++ imx258->link_freq_menu_items = link_freq_menu_items_24;
++ break;
++ default:
++ dev_err(&client->dev, "input clock frequency of %u not supported\n",
++ val);
+ return -EINVAL;
+ }
+