From: Alexander Stein <alexander.stein@ew.tq-group.com>
To: Dave Stevenson <dave.stevenson@raspberrypi.com>
Cc: paul.j.murphy@intel.com, daniele.alessandrelli@intel.com,
linux-media@vger.kernel.org, sakari.ailus@iki.fi,
jacopo@jmondi.org,
Dave Stevenson <dave.stevenson@raspberrypi.com>
Subject: Re: [PATCH v2 15/16] media: i2c: ov9282: Add support for 8bit readout
Date: Tue, 01 Nov 2022 12:58:27 +0100 [thread overview]
Message-ID: <3198230.aeNJFYEL58@steina-w> (raw)
In-Reply-To: <20221028160902.2696973-16-dave.stevenson@raspberrypi.com>
Hello Dave,
Am Freitag, 28. Oktober 2022, 18:09:01 CET schrieb Dave Stevenson:
> The sensor supports 8 or 10 bit readout modes, but the
> driver only supported 10 bit.
>
> Add 8 bit readout.
>
> Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
> ---
> drivers/media/i2c/ov9282.c | 95 +++++++++++++++++++++++++++++++-------
> 1 file changed, 78 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/media/i2c/ov9282.c b/drivers/media/i2c/ov9282.c
> index c169b532ec8b..e2a98f480b58 100644
> --- a/drivers/media/i2c/ov9282.c
> +++ b/drivers/media/i2c/ov9282.c
> @@ -21,6 +21,10 @@
> #define OV9282_MODE_STANDBY 0x00
> #define OV9282_MODE_STREAMING 0x01
>
> +#define OV9282_REG_PLL_CTRL_0D 0x030d
> +#define OV9282_PLL_CTRL_0D_RAW8 0x60
> +#define OV9282_PLL_CTRL_0D_RAW10 0x50
> +
> #define OV9282_REG_TIMING_HTS 0x380c
> #define OV9282_TIMING_HTS_MAX 0x7fff
>
> @@ -48,6 +52,10 @@
> /* Group hold register */
> #define OV9282_REG_HOLD 0x3308
>
> +#define OV9282_REG_ANA_CORE_2 0x3662
> +#define OV9282_ANA_CORE2_RAW8 0x07
> +#define OV9282_ANA_CORE2_RAW10 0x05
> +
> #define OV9282_REG_TIMING_FORMAT_1 0x3820
> #define OV9282_REG_TIMING_FORMAT_2 0x3821
> #define OV9282_FLIP_BIT BIT(2)
> @@ -63,8 +71,10 @@
> #define OV9282_NUM_DATA_LANES 2
>
> /* Pixel rate */
> -#define OV9282_PIXEL_RATE (OV9282_LINK_FREQ * 2 * \
> - OV9282_NUM_DATA_LANES / 10)
> +#define OV9282_PIXEL_RATE_10BIT (OV9282_LINK_FREQ * 2 * \
> + OV9282_NUM_DATA_LANES / 10)
> +#define OV9282_PIXEL_RATE_8BIT (OV9282_LINK_FREQ * 2 * \
> + OV9282_NUM_DATA_LANES / 8)
>
> /*
> * OV9282 native and active pixel array size.
> @@ -140,6 +150,7 @@ struct ov9282_mode {
> * @again_ctrl: Pointer to analog gain control
> * @vblank: Vertical blanking in lines
> * @cur_mode: Pointer to current selected sensor mode
> + * @code: Mbus code currently selected
> * @mutex: Mutex for serializing sensor controls
> * @streaming: Flag indicating streaming state
> */
> @@ -158,9 +169,11 @@ struct ov9282 {
> struct v4l2_ctrl *exp_ctrl;
> struct v4l2_ctrl *again_ctrl;
> };
> + struct v4l2_ctrl *pixel_rate;
> u32 vblank;
> bool noncontinuous_clock;
> const struct ov9282_mode *cur_mode;
> + u32 code;
> struct mutex mutex;
> bool streaming;
> };
> @@ -178,7 +191,6 @@ static const s64 link_freq[] = {
> */
> static const struct ov9282_reg common_regs[] = {
> {0x0302, 0x32},
> - {0x030d, 0x50},
> {0x030e, 0x02},
> {0x3001, 0x00},
> {0x3004, 0x00},
> @@ -516,19 +528,29 @@ static int ov9282_write_regs(struct ov9282 *ov9282,
> * ov9282_update_controls() - Update control ranges based on streaming mode
> * @ov9282: pointer to ov9282 device
> * @mode: pointer to ov9282_mode sensor mode
> + * @fmt: pointer to the requested mode
> *
> * Return: 0 if successful, error code otherwise.
> */
> static int ov9282_update_controls(struct ov9282 *ov9282,
> - const struct ov9282_mode *mode)
> + const struct ov9282_mode *mode,
> + const struct v4l2_subdev_format
*fmt)
> {
> u32 hblank_min;
> + s64 pixel_rate;
> int ret;
>
> ret = __v4l2_ctrl_s_ctrl(ov9282->link_freq_ctrl, mode-
>link_freq_idx);
> if (ret)
> return ret;
>
> + pixel_rate = (fmt->format.code == MEDIA_BUS_FMT_Y10_1X10) ?
> + OV9282_PIXEL_RATE_10BIT : OV9282_PIXEL_RATE_8BIT;
> + ret = __v4l2_ctrl_modify_range(ov9282->pixel_rate, pixel_rate,
> + pixel_rate, 1, pixel_rate);
> + if (ret)
> + return ret;
> +
> hblank_min = mode->hblank_min[ov9282->noncontinuous_clock ? 0 : 1];
> ret = __v4l2_ctrl_modify_range(ov9282->hblank_ctrl, hblank_min,
> OV9282_TIMING_HTS_MAX -
mode->width, 1,
> @@ -698,10 +720,16 @@ static int ov9282_enum_mbus_code(struct v4l2_subdev
> *sd, struct v4l2_subdev_state *sd_state,
> struct v4l2_subdev_mbus_code_enum
*code)
> {
> - if (code->index > 0)
> + switch (code->index) {
> + case 0:
> + code->code = MEDIA_BUS_FMT_Y10_1X10;
> + break;
> + case 1:
> + code->code = MEDIA_BUS_FMT_Y8_1X8;
> + break;
> + default:
> return -EINVAL;
> -
> - code->code = MEDIA_BUS_FMT_Y10_1X10;
> + }
>
> return 0;
> }
> @@ -721,7 +749,8 @@ static int ov9282_enum_frame_size(struct v4l2_subdev
> *sd, if (fsize->index >= ARRAY_SIZE(supported_modes))
> return -EINVAL;
>
> - if (fsize->code != MEDIA_BUS_FMT_Y10_1X10)
> + if (fsize->code != MEDIA_BUS_FMT_Y10_1X10 &&
> + fsize->code != MEDIA_BUS_FMT_Y8_1X8)
> return -EINVAL;
>
> fsize->min_width = supported_modes[fsize->index].width;
> @@ -737,15 +766,17 @@ static int ov9282_enum_frame_size(struct v4l2_subdev
> *sd, * from selected sensor mode
> * @ov9282: pointer to ov9282 device
> * @mode: pointer to ov9282_mode sensor mode
> + * @code: mbus code to be stored
> * @fmt: V4L2 sub-device format need to be filled
> */
> static void ov9282_fill_pad_format(struct ov9282 *ov9282,
> const struct ov9282_mode *mode,
> + u32 code,
> struct v4l2_subdev_format *fmt)
> {
> fmt->format.width = mode->width;
> fmt->format.height = mode->height;
> - fmt->format.code = MEDIA_BUS_FMT_Y10_1X10;
> + fmt->format.code = code;
> fmt->format.field = V4L2_FIELD_NONE;
> fmt->format.colorspace = V4L2_COLORSPACE_RAW;
> fmt->format.ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT;
> @@ -775,7 +806,8 @@ static int ov9282_get_pad_format(struct v4l2_subdev *sd,
> framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
> fmt->format = *framefmt;
> } else {
> - ov9282_fill_pad_format(ov9282, ov9282->cur_mode, fmt);
> + ov9282_fill_pad_format(ov9282, ov9282->cur_mode, ov9282-
>code,
> + fmt);
> }
>
> mutex_unlock(&ov9282->mutex);
> @@ -797,6 +829,7 @@ static int ov9282_set_pad_format(struct v4l2_subdev *sd,
> {
> struct ov9282 *ov9282 = to_ov9282(sd);
> const struct ov9282_mode *mode;
> + u32 code;
> int ret = 0;
>
> mutex_lock(&ov9282->mutex);
> @@ -806,7 +839,12 @@ static int ov9282_set_pad_format(struct v4l2_subdev
> *sd, width, height,
> fmt->format.width,
> fmt->format.height);
> - ov9282_fill_pad_format(ov9282, mode, fmt);
> + if (fmt->format.code == MEDIA_BUS_FMT_Y8_1X8)
> + code = MEDIA_BUS_FMT_Y8_1X8;
> + else
> + code = MEDIA_BUS_FMT_Y10_1X10;
> +
> + ov9282_fill_pad_format(ov9282, mode, code, fmt);
>
> if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
> struct v4l2_mbus_framefmt *framefmt;
> @@ -814,9 +852,11 @@ static int ov9282_set_pad_format(struct v4l2_subdev
> *sd, framefmt = v4l2_subdev_get_try_format(sd, sd_state, fmt->pad);
> *framefmt = fmt->format;
> } else {
> - ret = ov9282_update_controls(ov9282, mode);
> - if (!ret)
> + ret = ov9282_update_controls(ov9282, mode, fmt);
> + if (!ret) {
> ov9282->cur_mode = mode;
> + ov9282->code = code;
> + }
> }
>
> mutex_unlock(&ov9282->mutex);
> @@ -838,7 +878,8 @@ static int ov9282_init_pad_cfg(struct v4l2_subdev *sd,
> struct v4l2_subdev_format fmt = { 0 };
>
> fmt.which = sd_state ? V4L2_SUBDEV_FORMAT_TRY :
V4L2_SUBDEV_FORMAT_ACTIVE;
> - ov9282_fill_pad_format(ov9282, &supported_modes[DEFAULT_MODE],
&fmt);
> + ov9282_fill_pad_format(ov9282, &supported_modes[DEFAULT_MODE],
> + ov9282->code, &fmt);
>
> return ov9282_set_pad_format(sd, sd_state, &fmt);
> }
> @@ -903,7 +944,17 @@ static int ov9282_get_selection(struct v4l2_subdev *sd,
> */
> static int ov9282_start_streaming(struct ov9282 *ov9282)
> {
> + const struct ov9282_reg bitdepth_regs[2][2] = {
> + {
> + {OV9282_REG_PLL_CTRL_0D,
OV9282_PLL_CTRL_0D_RAW10},
> + {OV9282_REG_ANA_CORE_2, OV9282_ANA_CORE2_RAW10},
> + }, {
> + {OV9282_REG_PLL_CTRL_0D,
OV9282_PLL_CTRL_0D_RAW8},
> + {OV9282_REG_ANA_CORE_2, OV9282_ANA_CORE2_RAW8},
> + }
> + };
> const struct ov9282_reg_list *reg_list;
> + int bitdepth_index;
> int ret;
>
> /* Write common registers */
> @@ -914,6 +965,13 @@ static int ov9282_start_streaming(struct ov9282
> *ov9282) return ret;
> }
>
> + bitdepth_index = ov9282->code == MEDIA_BUS_FMT_Y10_1X10 ? 0 : 1;
> + ret = ov9282_write_regs(ov9282, bitdepth_regs[bitdepth_index], 2);
> + if (ret) {
> + dev_err(ov9282->dev, "fail to write bitdepth regs");
> + return ret;
> + }
> +
> /* Write sensor mode registers */
> reg_list = &ov9282->cur_mode->reg_list;
> ret = ov9282_write_regs(ov9282, reg_list->regs, reg_list-
>num_of_regs);
> @@ -1235,9 +1293,11 @@ static int ov9282_init_controls(struct ov9282
> *ov9282) 0, 1, 1, 1);
>
> /* Read only controls */
> - v4l2_ctrl_new_std(ctrl_hdlr, &ov9282_ctrl_ops, V4L2_CID_PIXEL_RATE,
> - OV9282_PIXEL_RATE, OV9282_PIXEL_RATE, 1,
> - OV9282_PIXEL_RATE);
> + ov9282->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, &ov9282_ctrl_ops,
> + V4L2_CID_PIXEL_RATE,
> +
OV9282_PIXEL_RATE_10BIT,
> +
OV9282_PIXEL_RATE_10BIT, 1,
> +
OV9282_PIXEL_RATE_10BIT);
>
> ov9282->link_freq_ctrl = v4l2_ctrl_new_int_menu(ctrl_hdlr,
>
&ov9282_ctrl_ops,
> @@ -1319,6 +1379,7 @@ static int ov9282_probe(struct i2c_client *client)
>
> /* Set default mode to first mode */
> ov9282->cur_mode = &supported_modes[DEFAULT_MODE];
> + ov9282->code = MEDIA_BUS_FMT_Y10_1X10;
> ov9282->vblank = ov9282->cur_mode->vblank;
>
> ret = ov9282_init_controls(ov9282);
Using this series I was able to do some camera playback on LVDS display on
imx8mm based platform (TQMa8MxML). My command was 'gst-launch-1.0 v4l2src
device=/dev/video0 ! video/x-
raw,format=GRAY8,bpp=8,width=1280,height=720,framerate=30/1 ! videoconvert !
waylandsink'
But due to SW colorspace conversion this is awfully slow.
Using a testsink I get about 72FPS on 1280x720 for GREY. Is this to be
expected?
I used 'gst-launch-1.0 v4l2src device=/dev/video0 ! video/x-
raw,format=GRAY8,bpp=8,width=1280,height=720,framerate=30/1 ! fpsdisplaysink
video-sink="testsink" text-overlay=false silent=false sync=false -v' for that.
Apparently gstreamer does not support Y10. Do you have a different way
toactually use Y10?
Thanks
Alexander
next prev parent reply other threads:[~2022-11-01 11:59 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-28 16:08 [PATCH v2 00/16] Updates to ov9282 sensor driver Dave Stevenson
2022-10-28 16:08 ` [PATCH v2 01/16] media: i2c: ov9282: Remove duplication of registers Dave Stevenson
2022-10-28 16:08 ` [PATCH v2 02/16] media: i2c: ov9282: Split registers into common and mode specific Dave Stevenson
2022-10-28 16:08 ` [PATCH v2 03/16] media: i2c: ov9282: Remove format code from the mode Dave Stevenson
2022-10-28 16:08 ` [PATCH v2 04/16] media: i2c: ov9282: Remove pixel rate from mode definition Dave Stevenson
2022-10-28 16:08 ` [PATCH v2 05/16] media: i2c: ov9281: Support more than 1 mode Dave Stevenson
2022-10-31 10:17 ` Jacopo Mondi
2022-11-01 10:12 ` Sakari Ailus
2022-11-01 11:31 ` Dave Stevenson
2022-10-28 16:08 ` [PATCH v2 06/16] media: i2c: ov9282: Correct HTS register for configured pixel rate Dave Stevenson
2022-10-31 10:12 ` Jacopo Mondi
2022-10-28 16:08 ` [PATCH v2 07/16] media: i2c: ov9282: Reduce vblank_min values based on testing Dave Stevenson
2022-10-31 10:15 ` Jacopo Mondi
2022-10-28 16:08 ` [PATCH v2 08/16] media: i2c: ov9282: Add selection for CSI2 clock mode Dave Stevenson
2022-10-28 16:08 ` [PATCH v2 09/16] media: i2c: ov9282: Add the properties from fwnode Dave Stevenson
2022-10-28 16:08 ` [PATCH v2 10/16] media: i2c: ov9282: Action CID_VBLANK when set Dave Stevenson
2022-10-28 16:08 ` [PATCH v2 11/16] media: i2c: ov9282: Add HFLIP and VFLIP support Dave Stevenson
2022-10-31 10:41 ` Jacopo Mondi
2022-10-28 16:08 ` [PATCH v2 12/16] media: i2c: ov9282: Make V4L2_CID_HBLANK r/w Dave Stevenson
2022-10-28 16:08 ` [PATCH v2 13/16] media: i2c: ov9282: Add selection API calls for cropping info Dave Stevenson
2022-10-28 16:09 ` [PATCH v2 14/16] media: i2c: ov9282: Add support for 1280x800 and 640x400 modes Dave Stevenson
2022-10-31 10:28 ` Jacopo Mondi
2022-10-31 12:09 ` Dave Stevenson
2022-11-01 9:44 ` Jacopo Mondi
2022-10-28 16:09 ` [PATCH v2 15/16] media: i2c: ov9282: Add support for 8bit readout Dave Stevenson
2022-10-31 10:54 ` Jacopo Mondi
2022-11-01 11:58 ` Alexander Stein [this message]
2022-11-01 13:47 ` Dave Stevenson
2022-11-01 15:04 ` Alexander Stein
2022-11-01 18:20 ` Dave Stevenson
2022-11-01 20:37 ` Kieran Bingham
2022-11-03 8:49 ` Alexander Stein
2022-11-03 9:53 ` Kieran Bingham
2022-11-03 10:57 ` Alexander Stein
2022-11-03 9:09 ` Alexander Stein
2022-11-03 13:05 ` Dave Stevenson
2022-11-04 7:55 ` Alexander Stein
2022-11-04 11:04 ` Dave Stevenson
2022-10-28 16:09 ` [PATCH v2 16/16] media: i2c: ov9282: Support event handlers Dave Stevenson
2022-10-31 10:55 ` Jacopo Mondi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3198230.aeNJFYEL58@steina-w \
--to=alexander.stein@ew.tq-group.com \
--cc=daniele.alessandrelli@intel.com \
--cc=dave.stevenson@raspberrypi.com \
--cc=jacopo@jmondi.org \
--cc=linux-media@vger.kernel.org \
--cc=paul.j.murphy@intel.com \
--cc=sakari.ailus@iki.fi \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.