From: Sakari Ailus <sakari.ailus@linux.intel.com>
To: robh+dt@kernel.org, linux-media@vger.kernel.org,
devicetree@vger.kernel.org, peter.griffin@linaro.org,
dave.stevenson@raspberrypi.com, ezequiel@collabora.com
Subject: Re: [PATCH v3 2/2] media: i2c: Add driver for Sony IMX219 sensor
Date: Mon, 20 Jan 2025 10:59:44 +0000 [thread overview]
Message-ID: <Z44soIWngnmCjoe6@kekkonen.localdomain> (raw)
In-Reply-To: <20200110200915.22575-3-andrey.konovalov@linaro.org>
Hi Dave,
On Fri, Jan 10, 2020 at 11:09:15PM +0300, Andrey Konovalov wrote:
> +/* Power/clock management functions */
> +static int imx219_power_on(struct device *dev)
> +{
> + struct i2c_client *client = to_i2c_client(dev);
> + struct v4l2_subdev *sd = i2c_get_clientdata(client);
> + struct imx219 *imx219 = to_imx219(sd);
> + int ret;
> +
> + ret = regulator_bulk_enable(IMX219_NUM_SUPPLIES,
> + imx219->supplies);
> + if (ret) {
> + dev_err(&client->dev, "%s: failed to enable regulators\n",
> + __func__);
> + return ret;
> + }
> +
> + ret = clk_prepare_enable(imx219->xclk);
> + if (ret) {
> + dev_err(&client->dev, "%s: failed to enable clock\n",
> + __func__);
> + goto reg_off;
> + }
> +
> + gpiod_set_value_cansleep(imx219->reset_gpio, 1);
> + msleep(IMX219_XCLR_DELAY_MS);
> +
> + return 0;
> +reg_off:
> + regulator_bulk_disable(IMX219_NUM_SUPPLIES, imx219->supplies);
> + return ret;
> +}
> +
> +static int imx219_power_off(struct device *dev)
> +{
> + struct i2c_client *client = to_i2c_client(dev);
> + struct v4l2_subdev *sd = i2c_get_clientdata(client);
> + struct imx219 *imx219 = to_imx219(sd);
> +
> + gpiod_set_value_cansleep(imx219->reset_gpio, 0);
The polarity of the reset GPIO appears to be wrong above. Given it works
somewhere (arch/arm64/boot/dts/ti/k3-am62x-sk-csi2-imx219.dtso), the
existing DTS files have it wrong, too. The bindings still appear to
document it correctly.
Laurent confirmed xcrl isn't controllable in the RPi imx219 camera module.
How about fixing this? Currently correctly written DTBs including imx219
won't work.
I noticed this while fixing the power sequences in this and a few other
drivers.
> + regulator_bulk_disable(IMX219_NUM_SUPPLIES, imx219->supplies);
> + clk_disable_unprepare(imx219->xclk);
> +
> + return 0;
> +}
...
> +static int imx219_probe(struct i2c_client *client,
> + const struct i2c_device_id *id)
> +{
> + struct device *dev = &client->dev;
> + struct fwnode_handle *endpoint;
> + struct imx219 *imx219;
> + int ret;
> +
> + imx219 = devm_kzalloc(&client->dev, sizeof(*imx219), GFP_KERNEL);
> + if (!imx219)
> + return -ENOMEM;
> +
> + imx219->dev = dev;
> +
> + v4l2_i2c_subdev_init(&imx219->sd, client, &imx219_subdev_ops);
> +
> + /* Get CSI2 bus config */
> + endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(&client->dev),
> + NULL);
> + if (!endpoint) {
> + dev_err(dev, "endpoint node not found\n");
> + return -EINVAL;
> + }
> +
> + ret = v4l2_fwnode_endpoint_parse(endpoint, &imx219->ep);
> + fwnode_handle_put(endpoint);
> + if (ret) {
> + dev_err(dev, "could not parse endpoint\n");
> + return ret;
> + }
> +
> + /* Check the number of MIPI CSI2 data lanes */
> + if (imx219->ep.bus_type != V4L2_MBUS_CSI2_DPHY ||
> + imx219->ep.bus.mipi_csi2.num_data_lanes != 2) {
> + dev_err(dev, "only 2 data lanes are currently supported\n");
> + return -EINVAL;
> + }
> +
> + /* Get system clock (xclk) */
> + imx219->xclk = devm_clk_get(dev, NULL);
> + if (IS_ERR(imx219->xclk)) {
> + dev_err(dev, "failed to get xclk\n");
> + return PTR_ERR(imx219->xclk);
> + }
> +
> + imx219->xclk_freq = clk_get_rate(imx219->xclk);
> + if (imx219->xclk_freq != IMX219_XCLK_FREQ) {
> + dev_err(dev, "xclk frequency not supported: %d Hz\n",
> + imx219->xclk_freq);
> + return -EINVAL;
> + }
> +
> + ret = imx219_get_regulators(imx219);
> + if (ret) {
> + dev_err(dev, "failed to get regulators\n");
> + return ret;
> + }
> +
> + /* Request optional enable pin */
> + imx219->reset_gpio = devm_gpiod_get_optional(dev, "reset",
> + GPIOD_OUT_HIGH);
> +
> + /*
> + * The sensor must be powered for imx219_identify_module()
> + * to be able to read the CHIP_ID register
> + */
> + ret = imx219_power_on(dev);
> + if (ret)
> + return ret;
> +
> + ret = imx219_identify_module(imx219);
> + if (ret)
> + goto error_power_off;
> +
> + /* Set default mode to max resolution */
> + imx219->mode = &supported_modes[0];
> +
> + ret = imx219_init_controls(imx219);
> + if (ret)
> + goto error_power_off;
> +
> + /* Initialize subdev */
> + imx219->sd.internal_ops = &imx219_internal_ops;
> + imx219->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
> + imx219->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR;
> +
> + /* Initialize source pad */
> + imx219->pad.flags = MEDIA_PAD_FL_SOURCE;
> +
> + ret = media_entity_pads_init(&imx219->sd.entity, 1, &imx219->pad);
> + if (ret) {
> + dev_err(dev, "failed to init entity pads: %d\n", ret);
> + goto error_handler_free;
> + }
> +
> + ret = v4l2_async_register_subdev_sensor_common(&imx219->sd);
> + if (ret < 0) {
> + dev_err(dev, "failed to register sensor sub-device: %d\n", ret);
> + goto error_media_entity;
> + }
> +
> + /* Enable runtime PM and turn off the device */
> + pm_runtime_set_active(dev);
> + pm_runtime_enable(dev);
> + pm_runtime_idle(dev);
> +
> + return 0;
> +
> +error_media_entity:
> + media_entity_cleanup(&imx219->sd.entity);
> +
> +error_handler_free:
> + imx219_free_controls(imx219);
> +
> +error_power_off:
> + imx219_power_off(dev);
> +
> + return ret;
> +}
--
Kind regards,
Sakari Ailus
next prev parent reply other threads:[~2025-01-20 10:59 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-01-10 20:09 [PATCH v3 0/2] Add IMX219 CMOS image sensor support Andrey Konovalov
2020-01-10 20:09 ` [PATCH v3 1/2] dt-bindings: media: i2c: Add IMX219 CMOS sensor binding Andrey Konovalov
2020-01-13 23:04 ` Rob Herring
2020-01-10 20:09 ` [PATCH v3 2/2] media: i2c: Add driver for Sony IMX219 sensor Andrey Konovalov
2025-01-20 10:59 ` Sakari Ailus [this message]
2025-01-20 12:28 ` Dave Stevenson
2025-01-20 13:35 ` Sakari Ailus
2025-01-20 13:59 ` Laurent Pinchart
2020-01-11 4:45 ` [PATCH v3 0/2] Add IMX219 CMOS image sensor support Ezequiel Garcia
2020-01-11 17:46 ` Andrey Konovalov
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=Z44soIWngnmCjoe6@kekkonen.localdomain \
--to=sakari.ailus@linux.intel.com \
--cc=dave.stevenson@raspberrypi.com \
--cc=devicetree@vger.kernel.org \
--cc=ezequiel@collabora.com \
--cc=linux-media@vger.kernel.org \
--cc=peter.griffin@linaro.org \
--cc=robh+dt@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