All of lore.kernel.org
 help / color / mirror / Atom feed
From: Krzysztof Kozlowski <krzk@kernel.org>
To: Philippe Baetens <philippebaetens@gmail.com>,
	mchehab@kernel.org, robh@kernel.org, conor+dt@kernel.org,
	krzk+dt@kernel.org
Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org,
	devicetree@vger.kernel.org
Subject: Re: [PATCH v3 2/2] Add a driver for the NIR-enhanced Mira220 1600x1400 global shutter image sensor.
Date: Wed, 2 Jul 2025 09:13:36 +0200	[thread overview]
Message-ID: <5cba2560-075c-4cd3-998e-30bd4ebb1d8b@kernel.org> (raw)
In-Reply-To: <aGP7j-8Beu-ekPT1@raspberrypi>

On 01/07/2025 17:15, Philippe Baetens wrote:
> This driver implements 12b, 10b and 8b RAW RGB color format.
> The output datarate is
> 1500Mbit/s, 2 lane. Framerate is up to 90 fps.
> Note: this sensor does not support analog gain.
> 
> Signed-off-by: philippe baetens <philippebaetens@gmail.com>
> ---
> Changes in v3:
> 	- Add people to mailing list
> 	- Improve commit description
> Changes in v2:
> 	- Fix checkpatch warnings

Subject: missing prefixes
Subject: no full stop, this is not a sentence. Look at git log how this
is created.

> ---
>  drivers/media/i2c/Kconfig   |   39 +
>  drivers/media/i2c/Makefile  |    3 +
>  drivers/media/i2c/mira220.c | 1973 +++++++++++++++++++++++++++++++++++
>  3 files changed, 2015 insertions(+)
>  create mode 100644 drivers/media/i2c/mira220.c
> 
> diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig
> index e68202954..0267f2440 100644
> --- a/drivers/media/i2c/Kconfig
> +++ b/drivers/media/i2c/Kconfig
> @@ -127,6 +127,31 @@ config VIDEO_HI847
>            To compile this driver as a module, choose M here: the
>            module will be called hi847.
>  
> +config VIDEO_PONCHA110

What is this?

> +	tristate "ams PONCHA110 sensor support"
> +	depends on I2C && VIDEO_DEV
> +	select MEDIA_CONTROLLER
> +	select VIDEO_V4L2_SUBDEV_API
> +	select V4L2_FWNODE
> +	help
> +	  This is a Video4Linux2 sensor driver for the ams
> +	  PONCHA110 camera.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called poncha110.
> +
> +config VIDEO_PONCHA110COLOR

Hm?

> +	tristate "ams PONCHA110COLOR sensor support"
> +	depends on I2C && VIDEO_DEV
> +	select MEDIA_CONTROLLER
> +	select VIDEO_V4L2_SUBDEV_API
> +	select V4L2_FWNODE
> +	help
> +	  This is a Video4Linux2 sensor driver for the ams
> +	  PONCHA110 camera.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called poncha110.
>  config VIDEO_IMX208
>  	tristate "Sony IMX208 sensor support"
>  	help
> @@ -269,6 +294,20 @@ config VIDEO_IMX415
>  config VIDEO_MAX9271_LIB
>  	tristate
>  
> +config VIDEO_MIRA220
> +	tristate "ams MIRA220 sensor support"
> +	depends on I2C && VIDEO_DEV
> +	select MEDIA_CONTROLLER
> +	select VIDEO_V4L2_SUBDEV_API
> +	select V4L2_CCI_I2C
> +	select V4L2_FWNODE
> +	help
> +	  This is a Video4Linux2 sensor driver for the ams
> +	  MIRA220 camera.
> +
> +	  To compile this driver as a module, choose M here: the
> +	  module will be called mira220.
> +
>  config VIDEO_MT9M001
>  	tristate "mt9m001 support"
>  	help
> diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile
> index 5873d2943..3b5e9d242 100644
> --- a/drivers/media/i2c/Makefile
> +++ b/drivers/media/i2c/Makefile
> @@ -45,6 +45,8 @@ obj-$(CONFIG_VIDEO_HI556) += hi556.o
>  obj-$(CONFIG_VIDEO_HI846) += hi846.o
>  obj-$(CONFIG_VIDEO_HI847) += hi847.o
>  obj-$(CONFIG_VIDEO_I2C) += video-i2c.o
> +obj-$(CONFIG_VIDEO_PONCHA110)	+= poncha110.o
> +obj-$(CONFIG_VIDEO_PONCHA110COLOR)	+= poncha110color.o

What?


...

> +
> +struct mira220 {

Type declarations go before variable definitions.

> +	struct v4l2_subdev sd;
> +	struct media_pad pad;
> +
> +	struct v4l2_mbus_framefmt fmt;
> +
> +	struct clk *xclk; /* system clock to MIRA220 */
> +	u32 xclk_freq;
> +
> +	struct regulator_bulk_data supplies[MIRA220_NUM_SUPPLIES];
> +
> +	struct v4l2_ctrl_handler ctrl_handler;
> +	struct v4l2_ctrl *pixel_rate;
> +	struct v4l2_ctrl *vflip;
> +	struct v4l2_ctrl *hflip;
> +	struct v4l2_ctrl *vblank;
> +	struct v4l2_ctrl *hblank;
> +	struct v4l2_ctrl *exposure;
> +	struct v4l2_ctrl *gain;
> +
> +	/* Current mode */
> +	const struct mira220_mode *mode;
> +
> +	struct mutex mutex; //comment
> +	/* mutex ensures correct initialization */
> +
> +	struct regmap *regmap;
> +};
> +
> +static inline struct mira220 *to_mira220(struct v4l2_subdev *_sd)
> +{
> +	return container_of(_sd, struct mira220, sd);
> +}
> +
> +/* Power/clock management functions */
> +static int mira220_power_on(struct device *dev)
> +{
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct v4l2_subdev *sd = i2c_get_clientdata(client);
> +	struct mira220 *mira220 = to_mira220(sd);
> +	int ret = -EINVAL;
> +
> +	ret = regulator_bulk_enable(MIRA220_NUM_SUPPLIES, mira220->supplies);
> +	if (ret) {
> +		dev_err(&client->dev, "%s: failed to enable regulators\n",
> +			__func__);
> +		goto reg_off;
> +	}
> +	ret = clk_prepare_enable(mira220->xclk);
> +	if (ret) {
> +		dev_err(&client->dev, "%s: failed to enable clock\n", __func__);
> +		goto clk_off;
> +	}
> +	fsleep(MIRA220_XCLR_MIN_DELAY_US);

No. Look at your probe code, this makes no sense.

> +
> +	return 0;
> +
> +clk_off:
> +	clk_disable_unprepare(mira220->xclk);
> +reg_off:
> +	ret = regulator_bulk_disable(MIRA220_NUM_SUPPLIES, mira220->supplies);

So you return 0 on error?
Why are you disabling regulators which were not enabled? This is wrong -
bug.

> +	return ret;
> +}
> +
> +static int mira220_power_off(struct device *dev)
> +{
> +	struct i2c_client *client = to_i2c_client(dev);
> +	struct v4l2_subdev *sd = i2c_get_clientdata(client);
> +	struct mira220 *mira220 = to_mira220(sd);
> +	(void)mira220;
> +
> +	clk_disable_unprepare(mira220->xclk);
> +	regulator_bulk_disable(MIRA220_NUM_SUPPLIES, mira220->supplies);
> +
> +	return 0;
> +}
> +


...

> +
> +static int mira220_probe(struct i2c_client *client)
> +{
> +	struct device *dev = &client->dev;
> +	struct mira220 *mira220;
> +	int ret;
> +
> +	mira220 = devm_kzalloc(&client->dev, sizeof(*mira220), GFP_KERNEL);
> +	if (!mira220)
> +		return -ENOMEM;
> +
> +	v4l2_i2c_subdev_init(&mira220->sd, client, &mira220_subdev_ops);
> +	mira220->sd.internal_ops = &mira220_internal_ops;
> +
> +	mira220->regmap = devm_cci_regmap_init_i2c(client, 16);
> +	if (IS_ERR(mira220->regmap))
> +		return dev_err_probe(dev, PTR_ERR(mira220->regmap),
> +				     "failed to initialize CCI\n");

Blank line

> +	/* Get system clock (xclk) */
> +	mira220->xclk = devm_clk_get(dev, NULL);
> +	if (IS_ERR(mira220->xclk)) {
> +		dev_err(dev, "failed to get xclk\n");
> +		return PTR_ERR(mira220->xclk);

Syntax is: return dev_err_probe()

> +	}
> +	mira220->xclk_freq = clk_get_rate(mira220->xclk);
> +	if (mira220->xclk_freq != MIRA220_SUPPORTED_XCLK_FREQ) {
> +		dev_err(dev, "xclk frequency not supported: %d Hz\n",
> +			mira220->xclk_freq);
> +		return -EINVAL;

return dev_err_probe

> +	}
> +
> +	ret = mira220_get_regulators(mira220);
> +	if (ret) {
> +		dev_err(dev, "failed to get regulators\n");
> +		return ret;

Same

> +	}
> +
> +	fsleep(10000);

Uh... Why? This sleep makes no sense at all.

> +
> +	// The sensor must be powered for mira220_identify_module()
> +	// to be able to read the CHIP_ID register
> +
> +	 ret = mira220_power_on(dev);
> +	if (ret)
> +		return ret;

You just slept here!

> +
> +	fsleep(100000);

Oh... so entire probe is delayed by 100 ms + 10 ms (!!!). This is just
some arbitrary and not suspicious delay. Maybe you miss regulator ramps,
but 100 ms here is just wrong.

> +
> +	ret = mira220_identify_module(mira220);
> +	if (ret)
> +		goto error_power_off;
> +
> +	/* Set default mode to max resolution */
> +	mira220->mode = &supported_modes[0];
> +
> +	ret = mira220_init_controls(mira220);
> +	if (ret)
> +		goto error_power_off;
> +
> +	/* Initialize subdev */
> +	mira220->sd.internal_ops = &mira220_internal_ops;
> +	mira220->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
> +		V4L2_SUBDEV_FL_HAS_EVENTS;
> +	mira220->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
> +
> +	/* Initialize source pads */
> +	mira220->pad.flags = MEDIA_PAD_FL_SOURCE;
> +
> +	ret = media_entity_pads_init(&mira220->sd.entity, 1, &mira220->pad);
> +	if (ret) {
> +		dev_err_probe(dev, ret, "failed to init entity pads\n");
> +		goto error_handler_free;
> +	}
> +
> +	mira220->sd.state_lock = mira220->ctrl_handler.lock;
> +	ret = v4l2_subdev_init_finalize(&mira220->sd);
> +	if (ret < 0) {
> +		dev_err_probe(dev, ret, "subdev init error\n");
> +		goto error_media_entity;
> +	}
> +
> +	ret = v4l2_async_register_subdev_sensor(&mira220->sd);
> +	if (ret < 0) {
> +		dev_err_probe(dev, ret,
> +			      "failed to register sensor sub-device\n");
> +		goto error_subdev_cleanup;
> +	}
> +
> +	/* Enable runtime PM and turn off the device */
> +	pm_runtime_set_active(dev);
> +	pm_runtime_enable(dev);
> +	pm_runtime_idle(dev);
> +
> +	return 0;
> +
> +error_subdev_cleanup:
> +	v4l2_subdev_cleanup(&mira220->sd);
> +
> +error_media_entity:
> +	media_entity_cleanup(&mira220->sd.entity);
> +
> +error_handler_free:
> +	mira220_free_controls(mira220);
> +
> +error_power_off:
> +	mira220_power_off(dev);
> +
> +	return ret;
> +}
> +
> +static void mira220_remove(struct i2c_client *client)
> +{
> +	struct v4l2_subdev *sd = i2c_get_clientdata(client);
> +	struct mira220 *mira220 = to_mira220(sd);
> +
> +	v4l2_async_unregister_subdev(sd);
> +	media_entity_cleanup(&sd->entity);
> +	mira220_free_controls(mira220);
> +
> +	pm_runtime_disable(&client->dev);
> +	if (!pm_runtime_status_suspended(&client->dev))
> +		mira220_power_off(&client->dev);
> +	pm_runtime_set_suspended(&client->dev);
> +}
> +
> +static const struct dev_pm_ops mira220_pm_ops = {
> +		SET_RUNTIME_PM_OPS(mira220_power_off, mira220_power_on, NULL)
> +};
> +
> +static const struct of_device_id mira220_dt_ids[] = {
> +	{ .compatible = "ams,mira220" },
> +	{ /* sentinel */ } };

}; is always in new line.

> +MODULE_DEVICE_TABLE(of, mira220_dt_ids);
> +



Best regards,
Krzysztof

      reply	other threads:[~2025-07-02  7:13 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-07-01 15:15 [PATCH v3 2/2] Add a driver for the NIR-enhanced Mira220 1600x1400 global shutter image sensor Philippe Baetens
2025-07-02  7:13 ` Krzysztof Kozlowski [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=5cba2560-075c-4cd3-998e-30bd4ebb1d8b@kernel.org \
    --to=krzk@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=mchehab@kernel.org \
    --cc=philippebaetens@gmail.com \
    --cc=robh@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 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.