From: jacopo mondi <jacopo@jmondi.org>
To: Sakari Ailus <sakari.ailus@iki.fi>
Cc: Jacopo Mondi <jacopo+renesas@jmondi.org>,
linux-media@vger.kernel.org, linux-renesas-soc@vger.kernel.org
Subject: Re: [RFC] v4l: i2c: ov7670: Implement mbus configuration
Date: Wed, 29 Nov 2017 12:25:37 +0100 [thread overview]
Message-ID: <20171129112537.GC17767@w540> (raw)
In-Reply-To: <20171129110648.vkqj2ijnryuhl4dq@valkosipuli.retiisi.org.uk>
Hi Sakari,
thanks for the reply
On Wed, Nov 29, 2017 at 01:06:49PM +0200, Sakari Ailus wrote:
> On Wed, Nov 29, 2017 at 01:04:30PM +0200, Sakari Ailus wrote:
> > Hi Jacopo,
> >
> > On Mon, Nov 27, 2017 at 11:26:53AM +0100, Jacopo Mondi wrote:
> > > ov7670 currently supports configuration of a few parameters only through
> > > platform data. Implement media bus configuration by parsing DT properties
> > > at probe() time and opportunely configure REG_COM10 during s_format().
> > >
> > > Signed-off-by: Jacopo Mondi <jacopo+renesas@jmondi.org>
> > >
> > > ---
> > >
> > > Hi linux-media,
> > > I'm using this sensor to test the CEU driver I have submitted some time ago
> > > and I would like to change synchronization signal polarities to test them in
> > > combination with that driver.
> > >
> > > So I added support for retrieving some properties listed in the device tree
> > > bindings documentation from sensor's DT node and made a patch, BUT I'm
> > > slightly confused about this (and that's why this is an RFC).
> > >
> > > I did a grep for "sync-active" in drivers/media/i2c/ and no sensor driver
> > > implements any property parsing, so I guess I'm doing something wrong here.
> >
> > :-)
> >
> > The standard properties are parsed in the V4L2 fwnode framework, and
> > gathered to v4l2_fwnode_endpoint struct for drivers to use. Please see e.g.
> > the smiapp driver how to do this.
> >
> > You'll still need to parse device specific properties in the driver.
I totally misinterpreted this!
My understanding was that v4l2_fwnode_endpoint_parse() was supposed to
be used to parse the -remote- endpoint configuration, so that a
platform driver would know how the sensor is configured and adjust its
settings accordingly (and eventually configure the remote endpoint with
s_mbus_confi()).
Instead, if I got this right, -both- sensor and platform parse
their own endpoints, and they don't care how the remote is configured
because of, as you said, wirings..
I'm going to re-submit this using the v4l2_fwnode framework utilities
in the sensor driver!
Thanks for the clarification
j
> >
> > >
> > > I thought that maybe sensor media bus configuration should come from the
> > > platform driver, through the s_mbus_config() operation in v4l2_subdev_video_ops,
>
> It's specified in the sensor's local endpoint. The corresponding
> configuration needs to be present in the remote endpoint. These are not
> necessarily always the same due to e.g. wiring.
>
> > > but that's said to be deprecated. So maybe is the framework providing support
> > > for parsing those properties? Another grep there and I found only v4l2-fwnode.c
> > > has support for parsing serial/parallel bus properties, but my understanding is
> > > that those functions are meant to be used by the platform driver when
> > > parsing the remote fw node.
> > >
> > > So please help me out here: where should I implement media bus configuration
> > > for sensor drivers?
> > >
> > > Thanks
> > > j
> > >
> > > PS: being this just an RFC I have not updated dt bindings, and only
> > > compile-tested the patch
> > >
> > > ---
> > > drivers/media/i2c/ov7670.c | 108 ++++++++++++++++++++++++++++++++++++++++++---
> > > 1 file changed, 101 insertions(+), 7 deletions(-)
> > >
> > > diff --git a/drivers/media/i2c/ov7670.c b/drivers/media/i2c/ov7670.c
> > > index e88549f..7e2de7e 100644
> > > --- a/drivers/media/i2c/ov7670.c
> > > +++ b/drivers/media/i2c/ov7670.c
> > > @@ -88,6 +88,7 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
> > > #define REG_COM10 0x15 /* Control 10 */
> > > #define COM10_HSYNC 0x40 /* HSYNC instead of HREF */
> > > #define COM10_PCLK_HB 0x20 /* Suppress PCLK on horiz blank */
> > > +#define COM10_PCLK_REV 0x10 /* Latch data on PCLK rising edge */
> > > #define COM10_HREF_REV 0x08 /* Reverse HREF */
> > > #define COM10_VS_LEAD 0x04 /* VSYNC on clock leading edge */
> > > #define COM10_VS_NEG 0x02 /* VSYNC negative */
> > > @@ -233,6 +234,7 @@ struct ov7670_info {
> > > struct clk *clk;
> > > struct gpio_desc *resetb_gpio;
> > > struct gpio_desc *pwdn_gpio;
> > > + unsigned int mbus_config; /* Media bus configuration flags */
> > > int min_width; /* Filter out smaller sizes */
> > > int min_height; /* Filter out smaller sizes */
> > > int clock_speed; /* External clock speed (MHz) */
> > > @@ -985,7 +987,7 @@ static int ov7670_set_fmt(struct v4l2_subdev *sd,
> > > struct ov7670_format_struct *ovfmt;
> > > struct ov7670_win_size *wsize;
> > > struct ov7670_info *info = to_state(sd);
> > > - unsigned char com7;
> > > + unsigned char com7, com10;
> > > int ret;
> > >
> > > if (format->pad)
> > > @@ -1021,6 +1023,9 @@ static int ov7670_set_fmt(struct v4l2_subdev *sd,
> > > ret = 0;
> > > if (wsize->regs)
> > > ret = ov7670_write_array(sd, wsize->regs);
> > > + if (ret)
> > > + return ret;
> > > +
> > > info->fmt = ovfmt;
> > >
> > > /*
> > > @@ -1033,8 +1038,26 @@ static int ov7670_set_fmt(struct v4l2_subdev *sd,
> > > * to write it unconditionally, and that will make the frame
> > > * rate persistent too.
> > > */
> > > - if (ret == 0)
> > > - ret = ov7670_write(sd, REG_CLKRC, info->clkrc);
> > > + ret = ov7670_write(sd, REG_CLKRC, info->clkrc);
> > > + if (ret)
> > > + return ret;
> > > +
> > > + /* Configure the media bus after the image format */
> > > + com10 = 0;
> > > + if (info->mbus_config & V4L2_MBUS_VSYNC_ACTIVE_LOW)
> > > + com10 |= COM10_VS_NEG;
> > > + if (info->mbus_config & V4L2_MBUS_HSYNC_ACTIVE_LOW)
> > > + com10 |= COM10_HS_NEG;
> > > + if (info->mbus_config & V4L2_MBUS_PCLK_SAMPLE_RISING)
> > > + com10 |= COM10_PCLK_REV;
> > > + if (info->pclk_hb_disable)
> > > + com10 |= COM10_PCLK_HB;
> > > +
> > > + if (com10)
> > > + ret = ov7670_write(sd, REG_COM10, com10);
> > > + if (ret)
> > > + return ret;
> > > +
> > > return 0;
> > > }
> > >
> > > @@ -1572,6 +1595,29 @@ static int ov7670_init_gpio(struct i2c_client *client, struct ov7670_info *info)
> > > return 0;
> > > }
> > >
> > > +/**
> > > + * ov7670_parse_dt_prop() - parse property "prop_name" in OF node
> > > + *
> > > + * @return The property value or < 0 if property not present
> > > + * or wrongly specified.
> > > + */
> > > +static int ov7670_parse_dt_prop(struct device *dev, char *prop_name)
> > > +{
> > > + struct device_node *np = dev->of_node;
> > > + u32 prop_val;
> > > + int ret;
> > > +
> > > + ret = of_property_read_u32(np, prop_name, &prop_val);
> > > + if (ret) {
> > > + if (ret != -EINVAL)
> > > + dev_err(dev, "Unable to parse property %s: %d\n",
> > > + prop_name, ret);
> > > + return ret;
> > > + }
> > > +
> > > + return prop_val;
> > > +}
> > > +
> > > static int ov7670_probe(struct i2c_client *client,
> > > const struct i2c_device_id *id)
> > > {
> > > @@ -1587,7 +1633,58 @@ static int ov7670_probe(struct i2c_client *client,
> > > v4l2_i2c_subdev_init(sd, client, &ov7670_ops);
> > >
> > > info->clock_speed = 30; /* default: a guess */
> > > - if (client->dev.platform_data) {
> > > +
> > > + if (IS_ENABLED(CONFIG_OF) && client->dev.of_node) {
> > > + /*
> > > + * Parse OF properties to initialize media bus configuration.
> > > + *
> > > + * Use sensor's default configuration if a property is not
> > > + * specified (ret == -EINVAL):
> > > + */
> > > + info->mbus_config = 0;
> > > +
> > > + ret = ov7670_parse_dt_prop(&client->dev, "hsync-active");
> > > + if (ret < 0 && ret != -EINVAL)
> > > + return ret;
> > > + else if (ret == 0)
> > > + info->mbus_config |= V4L2_MBUS_HSYNC_ACTIVE_LOW;
> > > + else
> > > + info->mbus_config |= V4L2_MBUS_HSYNC_ACTIVE_HIGH;
> > > +
> > > + ret = ov7670_parse_dt_prop(&client->dev, "vsync-active");
> > > + if (ret < 0 && ret != -EINVAL)
> > > + return ret;
> > > + else if (ret == 0)
> > > + info->mbus_config |= V4L2_MBUS_VSYNC_ACTIVE_LOW;
> > > + else
> > > + info->mbus_config |= V4L2_MBUS_VSYNC_ACTIVE_HIGH;
> > > +
> > > + ret = ov7670_parse_dt_prop(&client->dev, "pclk-sample");
> > > + if (ret < 0 && ret != -EINVAL)
> > > + return ret;
> > > + else if (ret > 0)
> > > + info->mbus_config |= V4L2_MBUS_PCLK_SAMPLE_RISING;
> > > + else
> > > + info->mbus_config |= V4L2_MBUS_PCLK_SAMPLE_FALLING;
> > > +
> > > + ret = ov7670_parse_dt_prop(&client->dev,
> > > + "ov7670,pclk-hb-disable");
> > > + if (ret < 0 && ret != -EINVAL)
> > > + return ret;
> > > + else if (ret > 0)
> > > + info->pclk_hb_disable = true;
> > > + else
> > > + info->pclk_hb_disable = false;
> > > +
> > > + ret = ov7670_parse_dt_prop(&client->dev, "ov7670,pll-bypass");
> > > + if (ret < 0 && ret != -EINVAL)
> > > + return ret;
> > > + else if (ret > 0)
> > > + info->pll_bypass = true;
> > > + else
> > > + info->pll_bypass = false;
> > > +
> > > + } else if (client->dev.platform_data) {
> > > struct ov7670_config *config = client->dev.platform_data;
> > >
> > > /*
> > > @@ -1649,9 +1746,6 @@ static int ov7670_probe(struct i2c_client *client,
> > > tpf.denominator = 30;
> > > info->devtype->set_framerate(sd, &tpf);
> > >
> > > - if (info->pclk_hb_disable)
> > > - ov7670_write(sd, REG_COM10, COM10_PCLK_HB);
> > > -
> > > v4l2_ctrl_handler_init(&info->hdl, 10);
> > > v4l2_ctrl_new_std(&info->hdl, &ov7670_ctrl_ops,
> > > V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
> > > --
> > > 2.7.4
> > >
> >
> > --
> > Sakari Ailus
> > e-mail: sakari.ailus@iki.fi
>
> --
> Sakari Ailus
> e-mail: sakari.ailus@iki.fi
prev parent reply other threads:[~2017-11-29 11:25 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-11-27 10:26 [RFC] v4l: i2c: ov7670: Implement mbus configuration Jacopo Mondi
2017-11-29 11:04 ` Sakari Ailus
2017-11-29 11:06 ` Sakari Ailus
2017-11-29 11:25 ` jacopo mondi [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=20171129112537.GC17767@w540 \
--to=jacopo@jmondi.org \
--cc=jacopo+renesas@jmondi.org \
--cc=linux-media@vger.kernel.org \
--cc=linux-renesas-soc@vger.kernel.org \
--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.