| From 9f6a310ab3b466940c0a15260987d4cfe868a79a Mon Sep 17 00:00:00 2001 |
| From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> |
| Date: Fri, 12 Jun 2020 15:53:52 +0200 |
| Subject: [PATCH] media: i2c: imx290: Add RAW12 mode support |
| |
| Commit c566ac01ceaa02450acc155201772c0623530e76 upstream. |
| |
| IMX290 is capable of outputting frames in both Raw Bayer (packed) 10 and |
| 12 bit formats. Since the driver already supports RAW10 mode, let's add |
| the missing RAW12 mode as well. |
| |
| Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> |
| Signed-off-by: Andrey Konovalov <andrey.konovalov@linaro.org> |
| Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> |
| Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> |
| --- |
| drivers/media/i2c/imx290.c | 36 +++++++++++++++++++++++++++++++++--- |
| 1 file changed, 33 insertions(+), 3 deletions(-) |
| |
| --- a/drivers/media/i2c/imx290.c |
| +++ b/drivers/media/i2c/imx290.c |
| @@ -67,6 +67,7 @@ struct imx290 { |
| struct clk *xclk; |
| struct regmap *regmap; |
| u8 nlanes; |
| + u8 bpp; |
| |
| struct v4l2_subdev sd; |
| struct v4l2_fwnode_endpoint ep; |
| @@ -86,10 +87,12 @@ struct imx290 { |
| |
| struct imx290_pixfmt { |
| u32 code; |
| + u8 bpp; |
| }; |
| |
| static const struct imx290_pixfmt imx290_formats[] = { |
| - { MEDIA_BUS_FMT_SRGGB10_1X10 }, |
| + { MEDIA_BUS_FMT_SRGGB10_1X10, 10 }, |
| + { MEDIA_BUS_FMT_SRGGB12_1X12, 12 }, |
| }; |
| |
| static const struct regmap_config imx290_regmap_config = { |
| @@ -257,6 +260,18 @@ static const struct imx290_regval imx290 |
| { 0x300b, 0x00}, |
| }; |
| |
| +static const struct imx290_regval imx290_12bit_settings[] = { |
| + { 0x3005, 0x01 }, |
| + { 0x3046, 0x01 }, |
| + { 0x3129, 0x00 }, |
| + { 0x317c, 0x00 }, |
| + { 0x31ec, 0x0e }, |
| + { 0x3441, 0x0c }, |
| + { 0x3442, 0x0c }, |
| + { 0x300a, 0xf0 }, |
| + { 0x300b, 0x00 }, |
| +}; |
| + |
| /* supported link frequencies */ |
| #define FREQ_INDEX_1080P 0 |
| #define FREQ_INDEX_720P 1 |
| @@ -478,7 +493,12 @@ static int imx290_set_ctrl(struct v4l2_c |
| } else { |
| imx290_write_reg(imx290, IMX290_PGCTRL, 0x00); |
| msleep(10); |
| - imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW, 0x3c); |
| + if (imx290->bpp == 10) |
| + imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW, |
| + 0x3c); |
| + else /* 12 bits per pixel */ |
| + imx290_write_reg(imx290, IMX290_BLKLEVEL_LOW, |
| + 0xf0); |
| imx290_write_reg(imx290, IMX290_BLKLEVEL_HIGH, 0x00); |
| } |
| break; |
| @@ -550,7 +570,7 @@ static u64 imx290_calc_pixel_rate(struct |
| |
| /* pixel rate = link_freq * 2 * nr_of_lanes / bits_per_sample */ |
| pixel_rate = link_freq * 2 * nlanes; |
| - do_div(pixel_rate, 10); |
| + do_div(pixel_rate, imx290->bpp); |
| return pixel_rate; |
| } |
| |
| @@ -587,6 +607,7 @@ static int imx290_set_fmt(struct v4l2_su |
| } else { |
| format = &imx290->current_format; |
| imx290->current_mode = mode; |
| + imx290->bpp = imx290_formats[i].bpp; |
| |
| if (imx290->link_freq) |
| __v4l2_ctrl_s_ctrl(imx290->link_freq, |
| @@ -629,6 +650,15 @@ static int imx290_write_current_format(s |
| if (ret < 0) { |
| dev_err(imx290->dev, "Could not set format registers\n"); |
| return ret; |
| + } |
| + break; |
| + case MEDIA_BUS_FMT_SRGGB12_1X12: |
| + ret = imx290_set_register_array(imx290, imx290_12bit_settings, |
| + ARRAY_SIZE( |
| + imx290_12bit_settings)); |
| + if (ret < 0) { |
| + dev_err(imx290->dev, "Could not set format registers\n"); |
| + return ret; |
| } |
| break; |
| default: |