From: Dave Stevenson <dave.stevenson@raspberrypi.com>
To: Alexander Stein <alexander.stein@ew.tq-group.com>
Cc: Manivannan Sadhasivam <mani@kernel.org>,
Mauro Carvalho Chehab <mchehab@kernel.org>,
Rob Herring <robh+dt@kernel.org>,
Krzysztof Kozlowski <krzysztof.kozlowski+dt@linaro.org>,
Shawn Guo <shawnguo@kernel.org>,
Sascha Hauer <s.hauer@pengutronix.de>,
Fabio Estevam <festevam@gmail.com>,
Laurent Pinchart <laurent.pinchart@ideasonboard.com>,
Pengutronix Kernel Team <kernel@pengutronix.de>,
linux-media@vger.kernel.org, devicetree@vger.kernel.org
Subject: Re: [PATCH 2/2] media: i2c: imx290: Add support for imx327 variant
Date: Fri, 3 Feb 2023 11:38:37 +0000 [thread overview]
Message-ID: <CAPY8ntAEJeXGoN=8yAD5rSC4TKftzhJ2a8c898uaLD0bCZfHCQ@mail.gmail.com> (raw)
In-Reply-To: <4778564.GXAFRqVoOG@steina-w>
On Fri, 3 Feb 2023 at 11:10, Alexander Stein
<alexander.stein@ew.tq-group.com> wrote:
>
> Hi Dave,
>
> Am Freitag, 3. Februar 2023, 11:55:55 CET schrieb Dave Stevenson:
> > Hi Alexander
> >
> > On Fri, 3 Feb 2023 at 10:24, Alexander Stein
> >
> > <alexander.stein@ew.tq-group.com> wrote:
> > > Both sensors are quite similar. Their specs only differ regarding LVDS
> > > and parallel output but are identical regarding MIPI-CSI-2 interface.
> > > But they use a different init setting of hard-coded values, taken from
> > > the datasheet.
> > >
> > > Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
> > > ---
> > >
> > > drivers/media/i2c/imx290.c | 88 +++++++++++++++++++++++++++++++++-----
> > > 1 file changed, 77 insertions(+), 11 deletions(-)
> > >
> > > diff --git a/drivers/media/i2c/imx290.c b/drivers/media/i2c/imx290.c
> > > index e642e1df520d..337252b2ec15 100644
> > > --- a/drivers/media/i2c/imx290.c
> > > +++ b/drivers/media/i2c/imx290.c
> > > @@ -164,6 +164,36 @@
> > >
> > > #define CLK_74_25 1
> > > #define NUM_CLK 2
> > >
> > > +enum imx290_model {
> > > + IMX290,
> > > + IMX290_MONO,
> > > + IMX327,
> > > +};
> > > +
> > > +struct imx290_device_data {
> > > + enum imx290_model model;
> > > + const char *name;
> > > + u8 mono;
> > > +};
> > > +
> > > +static const struct imx290_device_data imx290_models[] = {
> > > + [IMX290] = {
> > > + .model = IMX290,
> > > + .name = "imx290",
> > > + .mono = 0,
> > > + },
> > > + [IMX290_MONO] = {
> > > + .model = IMX290_MONO,
> > > + .name = "imx290-mono",
> > > + .mono = 1,
> > > + },
> > > + [IMX327] = {
> > > + .model = IMX327,
> > > + .name = "imx327",
> > > + .mono = 0,
> > > + },
> > > +};
> > > +
> > >
> > > struct imx290_regval {
> > >
> > > u32 reg;
> > > u32 val;
> > >
> > > @@ -210,9 +240,9 @@ struct imx290 {
> > >
> > > struct device *dev;
> > > struct clk *xclk;
> > > struct regmap *regmap;
> > >
> > > + const struct imx290_device_data *devdata;
> > >
> > > u32 xclk_freq;
> > > u8 nlanes;
> > >
> > > - u8 mono;
> > >
> > > struct v4l2_subdev sd;
> > > struct media_pad pad;
> > >
> > > @@ -240,7 +270,7 @@ static inline struct imx290 *to_imx290(struct
> > > v4l2_subdev *_sd)>
> > > * Modes and formats
> > > */
> > >
> > > -static const struct imx290_regval imx290_global_init_settings[] = {
> > > +static const struct imx290_regval imx290_global_init_settings_290[] = {
> > >
> > > { IMX290_WINWV_OB, 12 },
> > > { IMX290_WINPH, 0 },
> > > { IMX290_WINPV, 0 },
> > >
> > > @@ -292,6 +322,23 @@ static const struct imx290_regval
> > > imx290_global_init_settings[] = {>
> > > { IMX290_REG_8BIT(0x33b3), 0x04 },
> > >
> > > };
> > >
> > > +static const struct imx290_regval imx290_global_init_settings_327[] = {
> > > + { IMX290_WINWV_OB, 12 },
> > > + { IMX290_WINPH, 0 },
> > > + { IMX290_WINPV, 0 },
> > > + { IMX290_WINWH, 1948 },
> > > + { IMX290_WINWV, 1097 },
> > > + { IMX290_XSOUTSEL, IMX290_XSOUTSEL_XVSOUTSEL_VSYNC |
> > > + IMX290_XSOUTSEL_XHSOUTSEL_HSYNC },
> > > + { IMX290_REG_8BIT(0x3011), 0x0A },
> >
> > What datasheet are you working from? Mine (2019/03/25) has a
> > correction listed at v0.3 of:
> > Register 3011h setting 0Ah -> 02h
>
> I've got a v0.2 (2017/05/25). As you have v0.3 I am not really surprised you
> have different/additional values.
Revision history appears to be
0.1 2017/02/23
0.2 2017/05/25
0.3 2017/09/04
E17Z06 2017/12/18
E17Z06A81 2018/02/01
E1706B93 2019/03/25
so you are a way behind.
>
> > > + { IMX290_REG_8BIT(0x3012), 0x64 },
> > > + { IMX290_REG_8BIT(0x3013), 0x00 },
> > > + { IMX290_REG_8BIT(0x309e), 0x4A },
> > > + { IMX290_REG_8BIT(0x309f), 0x4A },
> >
> > 309e/f undocumented in my datasheet beyond "default value 5Ah, set to
> > "4Ah"". Not documented in imx290 or imx462 datasheets either. I'll read it
> > back from IMX290 and IMX462 when I get to the office and see if 0x4a is the
> > default anyway, in which case it can be generic.
I can't read back from my IMX290LLR as Vision Components use a
secondary MCU to stop you reading registers.
IMX462LQR default 0x5a 0x5a :-(
> Exactly, they are not documented at all, just marked red indicating it's
> different from reset default.
>
> > > + { IMX290_REG_8BIT(0x3128), 0x04 },
> >
> > Correction v0.3 - register address 3128h deleted.
> >
> > > + { IMX290_REG_8BIT(0x313b), 0x41 },
> >
> > Correction v0.3 - Register address 313Bh setting 41h -> 61h.
IMX462LQR default 0x51
> >
> >
> > I'll check the defaults on imx290 and imx462, because there is no harm
> > in adding those register writes if they happen to be the defaults.
> > There is also a fair amount of duplication between
> > imx290_global_init_settings_290 and imx290_global_init_settings_327 -
> > it'd be nice to reduce it down to the minimum set of diffs.
>
> Thanks, I'll update to the values you provided and split the common settings.
So annoyingly that does mean we need a sensor specific table, but I
think it is only 3 registers (0x309e, 0x309ef, and 0x313b). None of
those need to be set for IMX290 or 462.
Dave
> > > +};
> > > +
> > >
> > > static const struct imx290_regval imx290_37_125mhz_clock[] = {
> > >
> > > { IMX290_EXTCK_FREQ, 0x2520 },
> > > { IMX290_INCKSEL7, 0x49 },
> > >
> > > @@ -558,7 +605,7 @@ imx290_format_info(const struct imx290 *imx290, u32
> > > code)>
> > > for (i = 0; i < ARRAY_SIZE(imx290_formats); ++i) {
> > >
> > > const struct imx290_format_info *info =
> > > &imx290_formats[i];
> > >
> > > - if (info->code[imx290->mono] == code)
> > > + if (info->code[imx290->devdata->mono] == code)
> > >
> > > return info;
> > >
> > > }
> > >
> > > @@ -957,11 +1004,27 @@ static int imx290_start_streaming(struct imx290
> > > *imx290,>
> > > struct v4l2_subdev_state *state)
> > >
> > > {
> > >
> > > const struct v4l2_mbus_framefmt *format;
> > >
> > > + const struct imx290_regval *regs;
> > > + unsigned int reg_num;
> > >
> > > int ret;
> > >
> > > + switch (imx290->devdata->model) {
> > > + case IMX290:
> > > + case IMX290_MONO:
> > > + regs = imx290_global_init_settings_290;
> > > + reg_num = ARRAY_SIZE(imx290_global_init_settings_290);
> > > + break;
> > > + case IMX327:
> > > + regs = imx290_global_init_settings_327;
> > > + reg_num = ARRAY_SIZE(imx290_global_init_settings_327);
> > > + break;
> > > + default:
> > > + dev_err(imx290->dev, "Invalid model: %u\n",
> > > imx290->devdata->model); + return -EINVAL;
> > > + }
> > > +
> > >
> > > /* Set init register settings */
> > >
> > > - ret = imx290_set_register_array(imx290,
> > > imx290_global_init_settings, -
> > > ARRAY_SIZE(imx290_global_init_settings)); + ret =
> > > imx290_set_register_array(imx290, regs, reg_num);
> > >
> > > if (ret < 0) {
> > >
> > > dev_err(imx290->dev, "Could not set init registers\n");
> > > return ret;
> > >
> > > @@ -1072,7 +1135,7 @@ static int imx290_enum_mbus_code(struct v4l2_subdev
> > > *sd,>
> > > if (code->index >= ARRAY_SIZE(imx290_formats))
> > >
> > > return -EINVAL;
> > >
> > > - code->code = imx290_formats[code->index].code[imx290->mono];
> > > + code->code =
> > > imx290_formats[code->index].code[imx290->devdata->mono];>
> > > return 0;
> > >
> > > }
> > >
> > > @@ -1114,7 +1177,7 @@ static int imx290_set_fmt(struct v4l2_subdev *sd,
> > >
> > > fmt->format.height = mode->height;
> > >
> > > if (!imx290_format_info(imx290, fmt->format.code))
> > >
> > > - fmt->format.code = imx290_formats[0].code[imx290->mono];
> > > + fmt->format.code =
> > > imx290_formats[0].code[imx290->devdata->mono];>
> > > fmt->format.field = V4L2_FIELD_NONE;
> > > fmt->format.colorspace = V4L2_COLORSPACE_RAW;
> > >
> > > @@ -1422,8 +1485,9 @@ static s64 imx290_check_link_freqs(const struct
> > > imx290 *imx290,>
> > > }
> > >
> > > static const struct of_device_id imx290_of_match[] = {
> > >
> > > - { .compatible = "sony,imx290" },
> > > - { .compatible = "sony,imx290-mono", .data = (void *)1 },
> > > + { .compatible = "sony,imx290", .data = &imx290_models[IMX290] },
> > > + { .compatible = "sony,imx290-mono", .data =
> > > &imx290_models[IMX290_MONO] }, + { .compatible = "sony,imx327",
> > > .data = &imx290_models[IMX327] },
> > Based on Laurent's requests my parent to this set will be switching to
> > imx290 (as legacy), imx290lqr and imx290llr as the compatible strings.
> > imx327 ought to follow the same pattern.
>
> Okay thanks. I'll update to imx327lqr as well. Put me on CC so I'll notice the
> update & conflict.
>
> Best regards,
> Alexander
>
> > Dave
> >
> > > { /* sentinel */ }
> > >
> > > };
> > > MODULE_DEVICE_TABLE(of, imx290_of_match);
> > >
> > > @@ -1441,8 +1505,7 @@ static int imx290_parse_dt(struct imx290 *imx290)
> > >
> > > s64 fq;
> > >
> > > match = i2c_of_match_device(imx290_of_match, client);
> > >
> > > - if (match)
> > > - imx290->mono = match->data ? 1 : 0;
> > > + imx290->devdata = match->data;
> > >
> > > endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(imx290->dev),
> > > NULL);
> > > if (!endpoint) {
> > >
> > > @@ -1561,6 +1624,9 @@ static int imx290_probe(struct i2c_client *client)
> > >
> > > if (ret)
> > >
> > > goto err_pm;
> > >
> > > + v4l2_i2c_subdev_set_name(&imx290->sd, client,
> > > + imx290->devdata->name, NULL);
> > > +
> > >
> > > /*
> > >
> > > * Finally, register the V4L2 subdev. This must be done after
> > > * initializing everything as the subdev can be used immediately
> > > after
> > >
> > > --
> > > 2.34.1
>
>
>
>
prev parent reply other threads:[~2023-02-03 11:38 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-02-03 10:24 [PATCH 0/2] media: i2c: imx290: imx327 support Alexander Stein
2023-02-03 10:24 ` [PATCH 1/2] media: dt-bindings: media: i2c: Add imx327 version to IMX327 bindings Alexander Stein
2023-02-03 10:28 ` Krzysztof Kozlowski
2023-02-03 10:24 ` [PATCH 2/2] media: i2c: imx290: Add support for imx327 variant Alexander Stein
2023-02-03 10:55 ` Dave Stevenson
2023-02-03 11:10 ` Alexander Stein
2023-02-03 11:38 ` Dave Stevenson [this message]
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='CAPY8ntAEJeXGoN=8yAD5rSC4TKftzhJ2a8c898uaLD0bCZfHCQ@mail.gmail.com' \
--to=dave.stevenson@raspberrypi.com \
--cc=alexander.stein@ew.tq-group.com \
--cc=devicetree@vger.kernel.org \
--cc=festevam@gmail.com \
--cc=kernel@pengutronix.de \
--cc=krzysztof.kozlowski+dt@linaro.org \
--cc=laurent.pinchart@ideasonboard.com \
--cc=linux-media@vger.kernel.org \
--cc=mani@kernel.org \
--cc=mchehab@kernel.org \
--cc=robh+dt@kernel.org \
--cc=s.hauer@pengutronix.de \
--cc=shawnguo@kernel.org \
/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;
as well as URLs for NNTP newsgroup(s).