2023-10-28 08:43:12

by André Apitzsch

[permalink] [raw]
Subject: [PATCH v3 0/4] media: i2c: imx214: Extend with sensor size and firmware information

Add the effective and active sensor sizes and add functionality to read
rotation and orientation from device trees.

Signed-off-by: André Apitzsch <[email protected]>
---
Changes in v3:
- Squash patch 5/5 with patch 2/5
- Link to v2: https://lore.kernel.org/r/[email protected]

Changes in v2:
- Use integer representation for default exposure (Kieran)
- Replace dev_err_probe() by dev_err()
- Increase number of pre-allocated control slots (Jacopo)
- Fix typo in commit message (Jacopo)
- Add r-b tags
- Add patch to fix ctrls init error handling
- Link to v1: https://lore.kernel.org/r/[email protected]

---
André Apitzsch (4):
media: i2c: imx214: Explain some magic numbers
media: i2c: imx214: Move controls init to separate function
media: i2c: imx214: Read orientation and rotation from system firmware
media: i2c: imx214: Add sensor's pixel matrix size

drivers/media/i2c/imx214.c | 175 +++++++++++++++++++++++++++++++--------------
1 file changed, 120 insertions(+), 55 deletions(-)
---
base-commit: 66f1e1ea3548378ff6387b1ce0b40955d54e86aa
change-id: 20231023-imx214-68c438ebfb0c

Best regards,
--
André Apitzsch <[email protected]>


2023-10-28 08:43:40

by André Apitzsch

[permalink] [raw]
Subject: [PATCH v3 2/4] media: i2c: imx214: Move controls init to separate function

Code refinement.

While at it, don't destroy the mutex not initialized yet if the controls
are initialized incorrectly.

Reviewed-by: Jacopo Mondi <[email protected]>
Reviewed-by: Ricardo Ribalda <[email protected]>
Signed-off-by: André Apitzsch <[email protected]>
---
drivers/media/i2c/imx214.c | 115 ++++++++++++++++++++++++++-------------------
1 file changed, 67 insertions(+), 48 deletions(-)

diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c
index 1c30f6666d35..f62cd131164e 100644
--- a/drivers/media/i2c/imx214.c
+++ b/drivers/media/i2c/imx214.c
@@ -695,6 +695,69 @@ static const struct v4l2_ctrl_ops imx214_ctrl_ops = {
.s_ctrl = imx214_set_ctrl,
};

+static int imx214_ctrls_init(struct imx214 *imx214)
+{
+ static const s64 link_freq[] = {
+ IMX214_DEFAULT_LINK_FREQ
+ };
+ static const struct v4l2_area unit_size = {
+ .width = 1120,
+ .height = 1120,
+ };
+ struct v4l2_ctrl_handler *ctrl_hdlr;
+ int ret;
+
+ ctrl_hdlr = &imx214->ctrls;
+ ret = v4l2_ctrl_handler_init(&imx214->ctrls, 3);
+ if (ret)
+ return ret;
+
+ imx214->pixel_rate = v4l2_ctrl_new_std(ctrl_hdlr, NULL,
+ V4L2_CID_PIXEL_RATE, 0,
+ IMX214_DEFAULT_PIXEL_RATE, 1,
+ IMX214_DEFAULT_PIXEL_RATE);
+
+ imx214->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr, NULL,
+ V4L2_CID_LINK_FREQ,
+ ARRAY_SIZE(link_freq) - 1,
+ 0, link_freq);
+ if (imx214->link_freq)
+ imx214->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
+
+ /*
+ * WARNING!
+ * Values obtained reverse engineering blobs and/or devices.
+ * Ranges and functionality might be wrong.
+ *
+ * Sony, please release some register set documentation for the
+ * device.
+ *
+ * Yours sincerely, Ricardo.
+ */
+ imx214->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx214_ctrl_ops,
+ V4L2_CID_EXPOSURE,
+ IMX214_EXPOSURE_MIN,
+ IMX214_EXPOSURE_MAX,
+ IMX214_EXPOSURE_STEP,
+ IMX214_EXPOSURE_DEFAULT);
+
+ imx214->unit_size = v4l2_ctrl_new_std_compound(ctrl_hdlr,
+ NULL,
+ V4L2_CID_UNIT_CELL_SIZE,
+ v4l2_ctrl_ptr_create((void *)&unit_size));
+
+ ret = ctrl_hdlr->error;
+ if (ret) {
+ v4l2_ctrl_handler_free(ctrl_hdlr);
+ dev_err(imx214->dev, "failed to add controls: %d\n", ret);
+ return ret;
+ }
+
+ imx214->sd.ctrl_handler = ctrl_hdlr;
+
+ return 0;
+};
+
#define MAX_CMD 4
static int imx214_write_table(struct imx214 *imx214,
const struct reg_8 table[])
@@ -918,13 +981,6 @@ static int imx214_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct imx214 *imx214;
- static const s64 link_freq[] = {
- IMX214_DEFAULT_LINK_FREQ,
- };
- static const struct v4l2_area unit_size = {
- .width = 1120,
- .height = 1120,
- };
int ret;

ret = imx214_parse_fwnode(dev);
@@ -979,48 +1035,10 @@ static int imx214_probe(struct i2c_client *client)
pm_runtime_enable(imx214->dev);
pm_runtime_idle(imx214->dev);

- v4l2_ctrl_handler_init(&imx214->ctrls, 3);
-
- imx214->pixel_rate = v4l2_ctrl_new_std(&imx214->ctrls, NULL,
- V4L2_CID_PIXEL_RATE, 0,
- IMX214_DEFAULT_PIXEL_RATE, 1,
- IMX214_DEFAULT_PIXEL_RATE);
- imx214->link_freq = v4l2_ctrl_new_int_menu(&imx214->ctrls, NULL,
- V4L2_CID_LINK_FREQ,
- ARRAY_SIZE(link_freq) - 1,
- 0, link_freq);
- if (imx214->link_freq)
- imx214->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY;
-
- /*
- * WARNING!
- * Values obtained reverse engineering blobs and/or devices.
- * Ranges and functionality might be wrong.
- *
- * Sony, please release some register set documentation for the
- * device.
- *
- * Yours sincerely, Ricardo.
- */
- imx214->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx214_ctrl_ops,
- V4L2_CID_EXPOSURE,
- IMX214_EXPOSURE_MIN,
- IMX214_EXPOSURE_MAX,
- IMX214_EXPOSURE_STEP,
- IMX214_EXPOSURE_DEFAULT);
-
- imx214->unit_size = v4l2_ctrl_new_std_compound(&imx214->ctrls,
- NULL,
- V4L2_CID_UNIT_CELL_SIZE,
- v4l2_ctrl_ptr_create((void *)&unit_size));
- ret = imx214->ctrls.error;
- if (ret) {
- dev_err(&client->dev, "%s control init failed (%d)\n",
- __func__, ret);
- goto free_ctrl;
- }
+ ret = imx214_ctrls_init(imx214);
+ if (ret < 0)
+ goto error_power_off;

- imx214->sd.ctrl_handler = &imx214->ctrls;
mutex_init(&imx214->mutex);
imx214->ctrls.lock = &imx214->mutex;

@@ -1050,6 +1068,7 @@ static int imx214_probe(struct i2c_client *client)
free_ctrl:
mutex_destroy(&imx214->mutex);
v4l2_ctrl_handler_free(&imx214->ctrls);
+error_power_off:
pm_runtime_disable(imx214->dev);

return ret;

--
2.42.0

2023-10-28 08:43:41

by André Apitzsch

[permalink] [raw]
Subject: [PATCH v3 4/4] media: i2c: imx214: Add sensor's pixel matrix size

Set effective and active sensor pixel sizes as shown in product
brief[1].

[1]: https://www.mouser.com/datasheet/2/897/ProductBrief_IMX214_20150428-1289331.pdf

Reviewed-by: Jacopo Mondi <[email protected]>
Signed-off-by: André Apitzsch <[email protected]>
---
drivers/media/i2c/imx214.c | 39 ++++++++++++++++++++++++++++++++-------
1 file changed, 32 insertions(+), 7 deletions(-)

diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c
index 81f126a1b145..0aba28d6dc2f 100644
--- a/drivers/media/i2c/imx214.c
+++ b/drivers/media/i2c/imx214.c
@@ -36,6 +36,14 @@
#define IMX214_EXPOSURE_STEP 1
#define IMX214_EXPOSURE_DEFAULT 3184

+/* IMX214 native and active pixel array size */
+#define IMX214_NATIVE_WIDTH 4224U
+#define IMX214_NATIVE_HEIGHT 3136U
+#define IMX214_PIXEL_ARRAY_LEFT 8U
+#define IMX214_PIXEL_ARRAY_TOP 8U
+#define IMX214_PIXEL_ARRAY_WIDTH 4208U
+#define IMX214_PIXEL_ARRAY_HEIGHT 3120U
+
static const char * const imx214_supply_name[] = {
"vdda",
"vddd",
@@ -634,14 +642,31 @@ static int imx214_get_selection(struct v4l2_subdev *sd,
{
struct imx214 *imx214 = to_imx214(sd);

- if (sel->target != V4L2_SEL_TGT_CROP)
- return -EINVAL;
+ switch (sel->target) {
+ case V4L2_SEL_TGT_CROP:
+ mutex_lock(&imx214->mutex);
+ sel->r = *__imx214_get_pad_crop(imx214, sd_state, sel->pad,
+ sel->which);
+ mutex_unlock(&imx214->mutex);
+ return 0;

- mutex_lock(&imx214->mutex);
- sel->r = *__imx214_get_pad_crop(imx214, sd_state, sel->pad,
- sel->which);
- mutex_unlock(&imx214->mutex);
- return 0;
+ case V4L2_SEL_TGT_NATIVE_SIZE:
+ sel->r.top = 0;
+ sel->r.left = 0;
+ sel->r.width = IMX214_NATIVE_WIDTH;
+ sel->r.height = IMX214_NATIVE_HEIGHT;
+ return 0;
+
+ case V4L2_SEL_TGT_CROP_DEFAULT:
+ case V4L2_SEL_TGT_CROP_BOUNDS:
+ sel->r.top = IMX214_PIXEL_ARRAY_TOP;
+ sel->r.left = IMX214_PIXEL_ARRAY_LEFT;
+ sel->r.width = IMX214_PIXEL_ARRAY_WIDTH;
+ sel->r.height = IMX214_PIXEL_ARRAY_HEIGHT;
+ return 0;
+ }
+
+ return -EINVAL;
}

static int imx214_entity_init_cfg(struct v4l2_subdev *subdev,

--
2.42.0

2023-10-28 08:44:02

by André Apitzsch

[permalink] [raw]
Subject: [PATCH v3 1/4] media: i2c: imx214: Explain some magic numbers

Code refinement, no functional changes.

Reviewed-by: Ricardo Ribalda <[email protected]>
Signed-off-by: André Apitzsch <[email protected]>
---
drivers/media/i2c/imx214.c | 24 +++++++++++++++++++-----
1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c
index 4f77ea02cc27..1c30f6666d35 100644
--- a/drivers/media/i2c/imx214.c
+++ b/drivers/media/i2c/imx214.c
@@ -19,12 +19,23 @@
#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>

+#define IMX214_REG_MODE_SELECT 0x0100
+#define IMX214_MODE_STANDBY 0x00
+#define IMX214_MODE_STREAMING 0x01
+
#define IMX214_DEFAULT_CLK_FREQ 24000000
#define IMX214_DEFAULT_LINK_FREQ 480000000
#define IMX214_DEFAULT_PIXEL_RATE ((IMX214_DEFAULT_LINK_FREQ * 8LL) / 10)
#define IMX214_FPS 30
#define IMX214_MBUS_CODE MEDIA_BUS_FMT_SRGGB10_1X10

+/* Exposure control */
+#define IMX214_REG_EXPOSURE 0x0202
+#define IMX214_EXPOSURE_MIN 0
+#define IMX214_EXPOSURE_MAX 3184
+#define IMX214_EXPOSURE_STEP 1
+#define IMX214_EXPOSURE_DEFAULT 3184
+
static const char * const imx214_supply_name[] = {
"vdda",
"vddd",
@@ -665,7 +676,7 @@ static int imx214_set_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_EXPOSURE:
vals[1] = ctrl->val;
vals[0] = ctrl->val >> 8;
- ret = regmap_bulk_write(imx214->regmap, 0x202, vals, 2);
+ ret = regmap_bulk_write(imx214->regmap, IMX214_REG_EXPOSURE, vals, 2);
if (ret < 0)
dev_err(imx214->dev, "Error %d\n", ret);
ret = 0;
@@ -743,7 +754,7 @@ static int imx214_start_streaming(struct imx214 *imx214)
dev_err(imx214->dev, "could not sync v4l2 controls\n");
goto error;
}
- ret = regmap_write(imx214->regmap, 0x100, 1);
+ ret = regmap_write(imx214->regmap, IMX214_REG_MODE_SELECT, IMX214_MODE_STREAMING);
if (ret < 0) {
dev_err(imx214->dev, "could not sent start table %d\n", ret);
goto error;
@@ -761,7 +772,7 @@ static int imx214_stop_streaming(struct imx214 *imx214)
{
int ret;

- ret = regmap_write(imx214->regmap, 0x100, 0);
+ ret = regmap_write(imx214->regmap, IMX214_REG_MODE_SELECT, IMX214_MODE_STANDBY);
if (ret < 0)
dev_err(imx214->dev, "could not sent stop table %d\n", ret);

@@ -991,9 +1002,12 @@ static int imx214_probe(struct i2c_client *client)
*
* Yours sincerely, Ricardo.
*/
- imx214->exposure = v4l2_ctrl_new_std(&imx214->ctrls, &imx214_ctrl_ops,
+ imx214->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx214_ctrl_ops,
V4L2_CID_EXPOSURE,
- 0, 3184, 1, 0x0c70);
+ IMX214_EXPOSURE_MIN,
+ IMX214_EXPOSURE_MAX,
+ IMX214_EXPOSURE_STEP,
+ IMX214_EXPOSURE_DEFAULT);

imx214->unit_size = v4l2_ctrl_new_std_compound(&imx214->ctrls,
NULL,

--
2.42.0

2023-10-30 15:58:10

by Kieran Bingham

[permalink] [raw]
Subject: Re: [PATCH v3 1/4] media: i2c: imx214: Explain some magic numbers

Quoting André Apitzsch (2023-10-28 09:41:45)
> Code refinement, no functional changes.
>
> Reviewed-by: Ricardo Ribalda <[email protected]>

Reviewed-by: Kieran Bingham <[email protected]>

> Signed-off-by: André Apitzsch <[email protected]>
> ---
> drivers/media/i2c/imx214.c | 24 +++++++++++++++++++-----
> 1 file changed, 19 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c
> index 4f77ea02cc27..1c30f6666d35 100644
> --- a/drivers/media/i2c/imx214.c
> +++ b/drivers/media/i2c/imx214.c
> @@ -19,12 +19,23 @@
> #include <media/v4l2-fwnode.h>
> #include <media/v4l2-subdev.h>
>
> +#define IMX214_REG_MODE_SELECT 0x0100
> +#define IMX214_MODE_STANDBY 0x00
> +#define IMX214_MODE_STREAMING 0x01
> +
> #define IMX214_DEFAULT_CLK_FREQ 24000000
> #define IMX214_DEFAULT_LINK_FREQ 480000000
> #define IMX214_DEFAULT_PIXEL_RATE ((IMX214_DEFAULT_LINK_FREQ * 8LL) / 10)
> #define IMX214_FPS 30
> #define IMX214_MBUS_CODE MEDIA_BUS_FMT_SRGGB10_1X10
>
> +/* Exposure control */
> +#define IMX214_REG_EXPOSURE 0x0202
> +#define IMX214_EXPOSURE_MIN 0
> +#define IMX214_EXPOSURE_MAX 3184
> +#define IMX214_EXPOSURE_STEP 1
> +#define IMX214_EXPOSURE_DEFAULT 3184
> +
> static const char * const imx214_supply_name[] = {
> "vdda",
> "vddd",
> @@ -665,7 +676,7 @@ static int imx214_set_ctrl(struct v4l2_ctrl *ctrl)
> case V4L2_CID_EXPOSURE:
> vals[1] = ctrl->val;
> vals[0] = ctrl->val >> 8;
> - ret = regmap_bulk_write(imx214->regmap, 0x202, vals, 2);
> + ret = regmap_bulk_write(imx214->regmap, IMX214_REG_EXPOSURE, vals, 2);
> if (ret < 0)
> dev_err(imx214->dev, "Error %d\n", ret);
> ret = 0;
> @@ -743,7 +754,7 @@ static int imx214_start_streaming(struct imx214 *imx214)
> dev_err(imx214->dev, "could not sync v4l2 controls\n");
> goto error;
> }
> - ret = regmap_write(imx214->regmap, 0x100, 1);
> + ret = regmap_write(imx214->regmap, IMX214_REG_MODE_SELECT, IMX214_MODE_STREAMING);
> if (ret < 0) {
> dev_err(imx214->dev, "could not sent start table %d\n", ret);
> goto error;
> @@ -761,7 +772,7 @@ static int imx214_stop_streaming(struct imx214 *imx214)
> {
> int ret;
>
> - ret = regmap_write(imx214->regmap, 0x100, 0);
> + ret = regmap_write(imx214->regmap, IMX214_REG_MODE_SELECT, IMX214_MODE_STANDBY);
> if (ret < 0)
> dev_err(imx214->dev, "could not sent stop table %d\n", ret);
>
> @@ -991,9 +1002,12 @@ static int imx214_probe(struct i2c_client *client)
> *
> * Yours sincerely, Ricardo.
> */
> - imx214->exposure = v4l2_ctrl_new_std(&imx214->ctrls, &imx214_ctrl_ops,
> + imx214->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx214_ctrl_ops,
> V4L2_CID_EXPOSURE,
> - 0, 3184, 1, 0x0c70);
> + IMX214_EXPOSURE_MIN,
> + IMX214_EXPOSURE_MAX,
> + IMX214_EXPOSURE_STEP,
> + IMX214_EXPOSURE_DEFAULT);
>
> imx214->unit_size = v4l2_ctrl_new_std_compound(&imx214->ctrls,
> NULL,
>
> --
> 2.42.0
>

2023-11-26 22:07:39

by André Apitzsch

[permalink] [raw]
Subject: Re: [PATCH v3 0/4] media: i2c: imx214: Extend with sensor size and firmware information

Am Samstag, dem 28.10.2023 um 10:41 +0200 schrieb André Apitzsch:
> Add the effective and active sensor sizes and add functionality to
> read
> rotation and orientation from device trees.
>
> Signed-off-by: André Apitzsch <[email protected]>
> ---
> Changes in v3:
> - Squash patch 5/5 with patch 2/5
> - Link to v2:
> https://lore.kernel.org/r/[email protected]
>
> Changes in v2:
> - Use integer representation for default exposure (Kieran)
> - Replace dev_err_probe() by dev_err()
> - Increase number of pre-allocated control slots (Jacopo)
> - Fix typo in commit message (Jacopo)
> - Add r-b tags
> - Add patch to fix ctrls init error handling
> - Link to v1:
> https://lore.kernel.org/r/[email protected]
>
> ---
> André Apitzsch (4):
>       media: i2c: imx214: Explain some magic numbers
>       media: i2c: imx214: Move controls init to separate function
>       media: i2c: imx214: Read orientation and rotation from system
> firmware
>       media: i2c: imx214: Add sensor's pixel matrix size
>
>  drivers/media/i2c/imx214.c | 175 +++++++++++++++++++++++++++++++----
> ----------
>  1 file changed, 120 insertions(+), 55 deletions(-)
> ---
> base-commit: 66f1e1ea3548378ff6387b1ce0b40955d54e86aa
> change-id: 20231023-imx214-68c438ebfb0c
>
> Best regards,

Hi,

what's missing to get this series accepted. Shall I resend?

Best regards,
André