From: Alexander Stein <alexander.stein@ew.tq-group.com>
To: Spencer Hill <shill@d3engineering.com>
Cc: linux-media@vger.kernel.org,
Mauro Carvalho Chehab <mchehab@kernel.org>,
shill@d3engineering.com
Subject: Re: [PATCH 1/2] media: i2c: Add driver for Sony IMX728
Date: Fri, 28 Jun 2024 08:24:11 +0200 [thread overview]
Message-ID: <2701531.q0ZmV6gNhb@steina-w> (raw)
In-Reply-To: <Zn2xyPB3rDvSqssS@D3418SH-L.d3.local>
Hi,
Am Donnerstag, 27. Juni 2024, 20:39:04 CEST schrieb Spencer Hill:
> On Thu, Jun 27, 2024 at 04:03:36PM +0200, Alexander Stein wrote:
> > Hi Spencer,
> >
> > thanks for the patch.
> >
> > Just having a glimpse and giving some feedback.
> >
> > Am Mittwoch, 26. Juni 2024, 23:15:28 CEST schrieb Spencer Hill:
> > > Add a driver for the Sony IMX728 image sensor.
> > >
> > > Signed-off-by: Spencer Hill <shill@d3engineering.com>
> > > ---
> > > drivers/media/i2c/Kconfig | 11 +
> > > drivers/media/i2c/Makefile | 1 +
> > > drivers/media/i2c/imx728.c | 1167 ++++++++++++
> > > drivers/media/i2c/imx728.h | 3458 ++++++++++++++++++++++++++++++++++++
> > > 4 files changed, 4637 insertions(+)
> > > create mode 100644 drivers/media/i2c/imx728.c
> > > create mode 100644 drivers/media/i2c/imx728.h
> > >
> > > diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> > > index c6d3ee472d81..46b6463c558a 100644
> > > --- a/drivers/media/i2c/Kconfig
> > > +++ b/drivers/media/i2c/Kconfig
> > > @@ -233,6 +233,17 @@ config VIDEO_IMX415
> > > To compile this driver as a module, choose M here: the
> > > module will be called imx415.
> > >
> > > +config VIDEO_IMX728
> > > + tristate "Sony IMX728 sensor support"
> > > + depends on OF_GPIO
> > > + select V4L2_CCI_I2C
> > > + help
> > > + This is a Video4Linux2 sensor driver for the Sony
> > > + IMX728 camera.
> > > +
> > > + To compile this driver as a module, choose M here: the
> > > + module will be called imx728.
> > > +
> > > config VIDEO_MAX9271_LIB
> > > tristate
> > >
> > > diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
> > > index dfbe6448b549..1188420ee1b4 100644
> > > --- a/drivers/media/i2c/Makefile
> > > +++ b/drivers/media/i2c/Makefile
> > > @@ -56,6 +56,7 @@ obj-$(CONFIG_VIDEO_IMX335) += imx335.o
> > > obj-$(CONFIG_VIDEO_IMX355) += imx355.o
> > > obj-$(CONFIG_VIDEO_IMX412) += imx412.o
> > > obj-$(CONFIG_VIDEO_IMX415) += imx415.o
> > > +obj-$(CONFIG_VIDEO_IMX728) += imx728.o
> > > obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
> > > obj-$(CONFIG_VIDEO_ISL7998X) += isl7998x.o
> > > obj-$(CONFIG_VIDEO_KS0127) += ks0127.o
> > > diff --git a/drivers/media/i2c/imx728.c b/drivers/media/i2c/imx728.c
> > > new file mode 100644
> > > index 000000000000..b23359133a22
> > > --- /dev/null
> > > +++ b/drivers/media/i2c/imx728.c
> > > @@ -0,0 +1,1167 @@
> [snip]
> > > +{
> > > + int ret;
> > > +
> > > + ret = regmap_multi_reg_write(imx728->regmap, regs, nr_regs);
> > > + if (ret < 0)
> > > + dev_err(imx728->dev,
> > > + "%s: failed to write reg table (%d)!\n", __func__, ret);
> > > + return ret;
> > > +}
> > > +
> > > +static int imx728_wait_for_state(struct imx728 *imx728, enum imx728_sensor_state state)
> > > +{
> > > + int ret, i;
> > > + u32 val;
> > > +
> > > + for (i = 0; i < 50; i++) {
> > > + ret = imx728_read(imx728, 0x2CAC, &val, 1);
> >
> > Please add proper register defines using CCI_REG* macros.
> >
>
> Is using those macros in place in these functions OK?
List the registers on top of file, see for example imx415.c or imx290.c
>
> > > + if (ret == 0 && val == state) {
> > > + dev_info(imx728->dev, "%s: Enter state %u\n", __func__, val);
> > > + return 0;
> > > + }
> > > + usleep_range(1000, 10000);
> > > + }
> > > +
> > > + return -EBUSY;
> > > +}
> > > +
> > > +static void imx728_init_formats(struct v4l2_subdev_state *state)
> > > +{
> > > + struct v4l2_mbus_framefmt *format;
> > > +
> > > + format = v4l2_subdev_state_get_format(state, 0, 0);
> > > + format->code = imx728_mbus_formats[0];
> > > + format->width = imx728_framesizes[0].width;
> > > + format->height = imx728_framesizes[0].height;
> > > + format->field = V4L2_FIELD_NONE;
> > > + format->colorspace = V4L2_COLORSPACE_SMPTE170M;
> >
> > Are you sure about this colorspace? I would have expected
> > V4L2_COLORSPACE_RAW, but I don't know any details on this hardware.
> >
> > Also set ycbcr_enc, quantization and xfer_func.
> >
>
> V4L2_COLORSPACE_RAW is probably more correct.
> I am not sure what would be correct for the ycbcr_enc, similar drivers
> seem to use V4L2_YCBCR_ENC_601, would that be correct here?
AFAICS V4L2_MAP_YCBCR_ENC_DEFAULT() converts V4L2_COLORSPACE_RAW to
V4L2_YCBCR_ENC_601, so yes this seems correct. For the others use
V4L2_XFER_FUNC_NONE and V4L2_QUANTIZATION_DEFAULT.
> > > +}
> > > +
> > > +static int _imx728_set_routing(struct v4l2_subdev *sd,
> > > + struct v4l2_subdev_state *state)
> >
> > Why this special variant with a underscore? Just move the code
> > into imx728_set_routing.
> >
>
> I will put this into the other function.
>
> [snip]
> > > +
> > > +static int imx728_powerup_to_standby(struct imx728 *imx728)
> > > +{
> > > + int ret;
> > > +
> > > + dev_info(imx728->dev, "powerup -> standby...");
> > > +
> > > + ret = imx728_reset(imx728);
> > > + if (ret) {
> > > + dev_err(imx728->dev, "Error resetting: %i", ret);
> > > + return ret;
> > > + }
> > > +
> > > + ret = imx728_wait_for_state(imx728, IMX728_SENSOR_STATE_SLEEP);
> > > + if (ret < 0) {
> > > + dev_err(imx728->dev, "Could not transition to Sleep state!");
> > > + return ret;
> > > + }
> > > +
> > > + ret = imx728_write(imx728, 0x1B20, imx728->clk_rate / 1000000, 1);
> > > + if (ret < 0) {
> > > + dev_err(imx728->dev, "Couldn't write INCK frequency!");
> > > + return ret;
> > > + }
> > > +
> > > + ret = imx728_write(imx728, 0x1B1C, 0x1, 1);
> > > + if (ret < 0) {
> > > + dev_err(imx728->dev, "Couldn't write INCK frequency!");
> >
> > Error message doesn't seem to match. This is a fixed write, independent from any frequency.
> >
>
> This write is the enable flag for the configured INCK frequency. By
> default the sensor ignores the user configured frequency until this is
> set.
Okay, I see. But if you use a sequence of cci_write() calls you can instead
raise an error message on call site, see imx290_set_clock() for that.
> > > + return ret;
> > > + }
> > > +
> > > + ret = imx728_write(imx728, 0x1B05, 0xFF, 1);
> > > + if (ret < 0) {
> > > + dev_err(imx728->dev, "Couldn't write to CK_SLEEP!");
> > > + return ret;
> > > + }
> > > +
> > > + ret = imx728_wait_for_state(imx728, IMX728_SENSOR_STATE_STANDBY);
> > > + if (ret < 0) {
> > > + dev_err(imx728->dev, "Couldn't transition from Sleep to Standby state!");
> > > + return ret;
> > > + }
> > > +
> > > + ret = imx728_write(imx728, 0xFFFF, IMX728_REMAP_MODE_STANDBY, 1);
> > > + if (ret < 0) {
> > > + dev_err(imx728->dev, "Couldn't write regmap mode!");
> > > + return ret;
> > > + }
> > > +
> > > + return 0;
> > > +}
> > > +
> [snip]
> > > diff --git a/drivers/media/i2c/imx728.h b/drivers/media/i2c/imx728.h
> > > new file mode 100644
> > > index 000000000000..6f320214b780
> > > --- /dev/null
> > > +++ b/drivers/media/i2c/imx728.h
> >
> > There is only a single user of this header, move this into the c file.
> >
>
> I will combine these two files.
>
> > > @@ -0,0 +1,3458 @@
> > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > +/*
> > > + * Sony IMX728 CMOS Image Sensor Driver
> > > + *
> > > + * Copyright (c) 2024 Define Design Deploy Corp
> > > + */
> > > +
> > > +#include <linux/types.h>
> > > +
> > > +#define IMX728_OUT_WIDTH 3840
> > > +#define IMX728_OUT_HEIGHT 2160
> > > +
> > > +#define IMX728_FRAMERATE_MAX 30
> > > +#define IMX728_FRAMERATE_DEFAULT 30
> > > +#define IMX728_FRAMERATE_MIN 10
> > > +
> > > +#define IMX728_PIXEL_RATE 225504000
> > > +#define IMX728_LINK_FREQ 800000000
> > > +
> > > +#define IMX728_EXPOSURE_DEFAULT 10000
> > > +
> > > +#define IMX728_PM_IDLE_TIMEOUT 1000
> > > +
> > > +
> > > +#define IMX728_REG_CTRL_POINT_X(i) (0xA198 + (i) * 8)
> > > +#define IMX728_REG_CTRL_POINT_Y(i) (IMX728_REG_CTRL_POINT_X(i) + 4)
> > > +
> > > +enum imx728_sensor_state {
> > > + IMX728_SENSOR_STATE_SLEEP = 0x02,
> > > + IMX728_SENSOR_STATE_STANDBY = 0x04,
> > > + IMX728_SENSOR_STATE_STREAMING = 0x10,
> > > + IMX728_SENSOR_STATE_SAFE = 0x20,
> > > +};
> > > +
> > > +
> > > +enum imx728_remap_mode_id {
> > > + IMX728_REMAP_MODE_STANDBY = 0x00,
> > > + IMX728_REMAP_MODE_STANDBY_PIXEL_SHADING_COMPENSATION = 0x01,
> > > + IMX728_REMAP_MODE_STANDBY_SPOT_PIXEL_COMPENSATION = 0x02,
> > > + IMX728_REMAP_MODE_STREAMING = 0x04,
> > > + IMX728_REMAP_MODE_STREAMING_PIXEL_SHADING_COMPENSATION = 0x05,
> > > + IMX728_REMAP_MODE_STREAMING_SPOT_PIXEL_COMPENSATION = 0x06,
> > > + IMX728_REMAP_MODE_SLEEP = 0x20,
> > > +};
> > > +
> > > +enum imx728_drive_mode {
> > > + IMX728_MODE_3856x2176_45_4LANE_RAW10 = 0x01,
> > > + IMX728_MODE_3856x2176_45_4LANE_RAW12 = 0x02,
> > > + IMX728_MODE_3856x2176_45_4LANE_RAW16 = 0x03,
> > > + IMX728_MODE_3856x2176_45_4LANE_RAW20 = 0x04,
> > > + IMX728_MODE_3856x2176_45_4LANE_RAW12_HDR = 0x05,
> > > + IMX728_MODE_3856x2176_40_4LANE_RAW10 = 0x11,
> > > + IMX728_MODE_3856x2176_40_4LANE_RAW12 = 0x12,
> > > + IMX728_MODE_3856x2176_40_4LANE_RAW16 = 0x13,
> > > + IMX728_MODE_3856x2176_40_4LANE_RAW20 = 0x14,
> > > + IMX728_MODE_3856x2176_40_4LANE_RAW12_HDR = 0x16,
> > > +};
> > > +
> > > +enum imx728_awbmode {
> > > + IMX728_AWBMODE_ATW = 0,
> > > + IMX728_AWBMODE_ALL_PULL_IN = 1,
> > > + IMX728_AWBMODE_USER_PRESET = 2,
> > > + IMX728_AWBMODE_FULL_MWB = 3,
> > > + IMX728_AWBMODE_HOLD = 4,
> > > +};
> > > +
> > > +enum imx728_img_raw_mode {
> > > + IMX728_IMG_MODE_LINEAR = 0x0,
> > > + IMX728_IMG_MODE_LI = 0x1,
> > > + IMX728_IMG_MODE_HDR = 0x2,
> > > + IMX728_IMG_MODE_LI_HDR = 0x3,
> > > +};
> > > +
> > > +enum imx728_aemode {
> > > + IMX728_AEMODE_AE_AUTO = 0,
> > > + IMX728_AEMODE_AE_HOLD = 1,
> > > + IMX728_AEMODE_SCALE_ME = 2,
> > > + IMX728_AEMODE_FULL_ME = 3,
> > > +};
> > > +
> > > +enum imx728_fme_shtval_unit {
> > > + IMX728_FME_SHTVAL_UNIT_LINES = 1,
> > > + IMX728_FME_SHTVAL_UNIT_MICROSECONDS = 3,
> > > + IMX728_FME_SHTVAL_UNIT_FRAMES = 4,
> > > +};
> > > +
> > > +enum imx728_linear_raw_sel {
> > > + IMX728_RAW_SEL_SP1H = 0x0,
> > > + IMX728_RAW_SEL_SP1L = 0x1,
> > > + IMX728_RAW_SEL_SP1EC = 0x2,
> > > + IMX728_RAW_SEL_SP2 = 0x3,
> > > + IMX728_RAW_SEL_SP1VS = 0x4
> > > +};
> > > +
> > > +enum imx728_binn_avg {
> > > + IMX728_BINN_SIMPLE_AVG,
> > > + IMX728_BINN_WEIGHTED_AVG,
> > > +};
> > > +
> > > +struct imx728_ctrl {
> > > + struct v4l2_ctrl_handler handler;
> > > + struct v4l2_ctrl *wdr;
> > > + struct v4l2_ctrl *exposure;
> > > + struct v4l2_ctrl *again;
> > > + struct v4l2_ctrl *h_flip;
> > > + struct v4l2_ctrl *v_flip;
> > > + struct v4l2_ctrl *pg_mode;
> > > + struct v4l2_ctrl *pixel_rate;
> > > + struct v4l2_ctrl *link_freq;
> > > +};
> > > +
> > > +struct imx728_ctrl_point {
> >
> > What does ctrl_point mean? What is x and y?
> >
>
> Control points are used internally by the sensor to adjust how the HDR
> data from the sensor is compressed into the output bit depth. The values
> used were provided by Sony.
>
> > > + int x, y;
> > > +};
> > > +
> > > +/*
> > > + * struct imx728 - imx728 device structure
> > > + * @dev: Device handle
> > > + * @clk: Pointer to imx728 clock
> > > + * @client: Pointer to I2C client
> > > + * @regmap: Pointer to regmap structure
> > > + * @xclr_gpio: Pointer to XCLR gpio
> > > + * @subdev: V4L2 subdevice structure
> > > + * @format: V4L2 media bus frame format structure
> > > + * (width and height are in sync with the compose rect)
> > > + * @pad: Media pad structure
> > > + * @ctrl: imx728 control structure
> > > + * @clk_rate: Frequency of imx728 clock
> > > + * @lock: Mutex structure for V4L2 ctrl handler
> > > + * @streaming: Flag to store streaming on/off status
> > > + */
> > > +struct imx728 {
> > > + struct device *dev;
> > > +
> > > + struct clk *clk;
> > > + struct i2c_client *client;
> > > + struct regmap *regmap;
> > > + struct gpio_desc *xclr_gpio;
> > > +
> > > + struct v4l2_subdev subdev;
> > > + struct v4l2_mbus_framefmt format;
> > > + struct media_pad pad;
> > > +
> > > + struct imx728_ctrl ctrl;
> > > +
> > > + unsigned long clk_rate;
> > > + u32 fps;
> > > +
> > > + struct mutex lock;
> > > + bool streaming;
> > > +};
> > > +
> > > +static const struct v4l2_area imx728_framesizes[] = {
> > > + {
> > > + .width = IMX728_OUT_WIDTH,
> > > + .height = IMX728_OUT_HEIGHT,
> > > + },
> >
> > Are you sure this is the only supported resolution? I would prefer using
> > actual numbers here.
> >
>
> This is not the only supported resolution by the sensor, however it is
> the only resolution that I have a configuration for at the moment. I
> will remove the defines and switch to actual numbers to make supporting
> other resolutions easier in the future.
Nice, thanks.
Best regards,
Alexander
> > > +};
> > > +
> > > +static const u32 imx728_mbus_formats[] = {
> > > + MEDIA_BUS_FMT_SRGGB10_1X10,
> > > +};
> > > +
> > > +static const s64 imx728_link_freq_menu[] = {
> > > + IMX728_LINK_FREQ,
> > > +};
> > > +
> > > +static const struct regmap_config imx728_regmap_config = {
> > > + .reg_bits = 16,
> > > + .val_bits = 8,
> > > +};
> > > +
> > > +static const char *const imx728_ctrl_pg_qmenu[] = {
> > > + "Disabled",
> > > + "Horizontal Color Bars",
> > > + "Vertical Color Bars",
> > > +};
> > > +
> > > +static struct imx728_ctrl_point imx728_hdr_20bit[] = {
> > > + {0, 0},
> > > + {1566 >> 4, 938},
> > > + {105740 >> 4, 1863},
> > > + {387380 >> 4, 2396},
> > > + {3818601 >> 4, 3251},
> > > + {16777215 >> 4, 4095},
> > > + {-1, -1}
> > > +};
> > > +
> > > +static const struct reg_sequence imx728_3840x2160[] = {
> >
> > Please use struct cci_reg_sequence.
> >
> > Best regards,
> > Alexander
> >
>
> I will change this.
>
> > > + {0xFFFF, 0x00, 1000},
> > > + {0x1749, 0x01},
> > > + {0x174B, 0x01},
> > > [snip]
> > > +};
> > > --
> > > 2.40.1
> > >
> > > Please be aware that this email includes email addresses outside of the organization.
> > >
> > >
> >
> >
> > --
> > TQ-Systems GmbH | Mühlstraße 2, Gut Delling | 82229 Seefeld, Germany
> > Amtsgericht München, HRB 105018
> > Geschäftsführer: Detlef Schneider, Rüdiger Stahl, Stefan Schneider
> > http://www.tq-group.com/
> >
> >
> Please be aware that this email includes email addresses outside of the organization.
>
>
--
TQ-Systems GmbH | Mühlstraße 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht München, HRB 105018
Geschäftsführer: Detlef Schneider, Rüdiger Stahl, Stefan Schneider
http://www.tq-group.com/
next prev parent reply other threads:[~2024-06-28 6:24 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-26 21:15 [PATCH 0/2] media: i2c: Add driver for Sony IMX728 Spencer Hill
2024-06-26 21:15 ` [PATCH 1/2] " Spencer Hill
2024-06-27 6:57 ` Krzysztof Kozlowski
2024-06-27 17:50 ` Spencer Hill
2024-06-27 14:03 ` Alexander Stein
2024-06-27 18:39 ` Spencer Hill
2024-06-28 6:24 ` Alexander Stein [this message]
2024-06-27 15:39 ` Dave Stevenson
2024-06-27 19:58 ` Spencer Hill
2024-06-26 21:15 ` [PATCH 2/2] media: dt-bindings: Add " Spencer Hill
2024-06-27 6:51 ` Krzysztof Kozlowski
2024-06-27 16:30 ` Spencer Hill
2024-06-27 6:52 ` Krzysztof Kozlowski
2024-06-27 17:11 ` Spencer Hill
2024-06-27 13:38 ` Alexander Stein
2024-06-27 17:33 ` Spencer Hill
2024-06-28 6:11 ` Alexander Stein
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=2701531.q0ZmV6gNhb@steina-w \
--to=alexander.stein@ew.tq-group.com \
--cc=linux-media@vger.kernel.org \
--cc=mchehab@kernel.org \
--cc=shill@d3engineering.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox