* [PATCH v2 0/2] v4l2-cci: little-endian registers
@ 2023-11-01 12:23 Alexander Stein
2023-11-01 12:23 ` [PATCH v2 1/2] media: v4l2-cci: Add support for little-endian encoded registers Alexander Stein
` (2 more replies)
0 siblings, 3 replies; 16+ messages in thread
From: Alexander Stein @ 2023-11-01 12:23 UTC (permalink / raw)
To: Mauro Carvalho Chehab, Sakari Ailus, Manivannan Sadhasivam,
Laurent Pinchart, Hans de Goede
Cc: Alexander Stein, linux-media, Alain Volmat
Hi,
after the discussions at [1] and [2], this series adds proper support for
little-endian encoded registers.
Patch 1 adds the infrastructure and patch 2 fixes imx290 driver.
As v6.6 was released with imx290 broken, both should be added to stable.
Changes in v2:
* Add proper Fixes/CC tags to both patches
* Add little-endian support for cci_read()
Best regards,
Alexander
[1] https://lore.kernel.org/linux-media/20231030173637.GA2977515@gnbcxd0016.gnb.st.com/
[2] https://lore.kernel.org/linux-media/ZUIuNDTJAN_fz3q6@kekkonen.localdomain/
Alexander Stein (2):
media: v4l2-cci: Add support for little-endian encoded registers
media: i2c: imx290: Properly encode registers as little-endian
drivers/media/i2c/imx290.c | 42 ++++++++++++++--------------
drivers/media/v4l2-core/v4l2-cci.c | 44 ++++++++++++++++++++++++------
include/media/v4l2-cci.h | 5 ++++
3 files changed, 62 insertions(+), 29 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v2 1/2] media: v4l2-cci: Add support for little-endian encoded registers
2023-11-01 12:23 [PATCH v2 0/2] v4l2-cci: little-endian registers Alexander Stein
@ 2023-11-01 12:23 ` Alexander Stein
2023-11-02 1:22 ` Laurent Pinchart
2023-11-01 12:23 ` [PATCH v2 2/2] media: i2c: imx290: Properly encode registers as little-endian Alexander Stein
2023-11-01 15:26 ` [PATCH v2 0/2] v4l2-cci: little-endian registers Hans de Goede
2 siblings, 1 reply; 16+ messages in thread
From: Alexander Stein @ 2023-11-01 12:23 UTC (permalink / raw)
To: Mauro Carvalho Chehab, Sakari Ailus, Manivannan Sadhasivam,
Laurent Pinchart, Hans de Goede
Cc: Alexander Stein, linux-media, Alain Volmat, stable
Some sensors, e.g. Sony, are using little-endian registers. Add support for
those by encoding the endianess into Bit 20 of the register address.
Fixes: af73323b97702 ("media: imx290: Convert to new CCI register access helpers")
Cc: stable@vger.kernel.org
Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
---
drivers/media/v4l2-core/v4l2-cci.c | 44 ++++++++++++++++++++++++------
include/media/v4l2-cci.h | 5 ++++
2 files changed, 41 insertions(+), 8 deletions(-)
diff --git a/drivers/media/v4l2-core/v4l2-cci.c b/drivers/media/v4l2-core/v4l2-cci.c
index bc2dbec019b04..673637b67bf67 100644
--- a/drivers/media/v4l2-core/v4l2-cci.c
+++ b/drivers/media/v4l2-core/v4l2-cci.c
@@ -18,6 +18,7 @@
int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
{
+ bool little_endian;
unsigned int len;
u8 buf[8];
int ret;
@@ -25,6 +26,7 @@ int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
if (err && *err)
return *err;
+ little_endian = reg & CCI_REG_LE;
len = FIELD_GET(CCI_REG_WIDTH_MASK, reg);
reg = FIELD_GET(CCI_REG_ADDR_MASK, reg);
@@ -40,16 +42,28 @@ int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
*val = buf[0];
break;
case 2:
- *val = get_unaligned_be16(buf);
+ if (little_endian)
+ *val = get_unaligned_le16(buf);
+ else
+ *val = get_unaligned_be16(buf);
break;
case 3:
- *val = get_unaligned_be24(buf);
+ if (little_endian)
+ *val = get_unaligned_le24(buf);
+ else
+ *val = get_unaligned_be24(buf);
break;
case 4:
- *val = get_unaligned_be32(buf);
+ if (little_endian)
+ *val = get_unaligned_le32(buf);
+ else
+ *val = get_unaligned_be32(buf);
break;
case 8:
- *val = get_unaligned_be64(buf);
+ if (little_endian)
+ *val = get_unaligned_le64(buf);
+ else
+ *val = get_unaligned_be64(buf);
break;
default:
dev_err(regmap_get_device(map), "Error invalid reg-width %u for reg 0x%04x\n",
@@ -68,6 +82,7 @@ EXPORT_SYMBOL_GPL(cci_read);
int cci_write(struct regmap *map, u32 reg, u64 val, int *err)
{
+ bool little_endian;
unsigned int len;
u8 buf[8];
int ret;
@@ -75,6 +90,7 @@ int cci_write(struct regmap *map, u32 reg, u64 val, int *err)
if (err && *err)
return *err;
+ little_endian = reg & CCI_REG_LE;
len = FIELD_GET(CCI_REG_WIDTH_MASK, reg);
reg = FIELD_GET(CCI_REG_ADDR_MASK, reg);
@@ -83,16 +99,28 @@ int cci_write(struct regmap *map, u32 reg, u64 val, int *err)
buf[0] = val;
break;
case 2:
- put_unaligned_be16(val, buf);
+ if (little_endian)
+ put_unaligned_le16(val, buf);
+ else
+ put_unaligned_be16(val, buf);
break;
case 3:
- put_unaligned_be24(val, buf);
+ if (little_endian)
+ put_unaligned_le24(val, buf);
+ else
+ put_unaligned_be24(val, buf);
break;
case 4:
- put_unaligned_be32(val, buf);
+ if (little_endian)
+ put_unaligned_le32(val, buf);
+ else
+ put_unaligned_be32(val, buf);
break;
case 8:
- put_unaligned_be64(val, buf);
+ if (little_endian)
+ put_unaligned_le64(val, buf);
+ else
+ put_unaligned_be64(val, buf);
break;
default:
dev_err(regmap_get_device(map), "Error invalid reg-width %u for reg 0x%04x\n",
diff --git a/include/media/v4l2-cci.h b/include/media/v4l2-cci.h
index 0f6803e4b17e9..ef3faf0c9d44d 100644
--- a/include/media/v4l2-cci.h
+++ b/include/media/v4l2-cci.h
@@ -32,12 +32,17 @@ struct cci_reg_sequence {
#define CCI_REG_ADDR_MASK GENMASK(15, 0)
#define CCI_REG_WIDTH_SHIFT 16
#define CCI_REG_WIDTH_MASK GENMASK(19, 16)
+#define CCI_REG_LE BIT(20)
#define CCI_REG8(x) ((1 << CCI_REG_WIDTH_SHIFT) | (x))
#define CCI_REG16(x) ((2 << CCI_REG_WIDTH_SHIFT) | (x))
#define CCI_REG24(x) ((3 << CCI_REG_WIDTH_SHIFT) | (x))
#define CCI_REG32(x) ((4 << CCI_REG_WIDTH_SHIFT) | (x))
#define CCI_REG64(x) ((8 << CCI_REG_WIDTH_SHIFT) | (x))
+#define CCI_REG16_LE(x) ((2 << CCI_REG_WIDTH_SHIFT) | (x) | CCI_REG_LE)
+#define CCI_REG24_LE(x) ((3 << CCI_REG_WIDTH_SHIFT) | (x) | CCI_REG_LE)
+#define CCI_REG32_LE(x) ((4 << CCI_REG_WIDTH_SHIFT) | (x) | CCI_REG_LE)
+#define CCI_REG64_LE(x) ((8 << CCI_REG_WIDTH_SHIFT) | (x) | CCI_REG_LE)
/**
* cci_read() - Read a value from a single CCI register
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 2/2] media: i2c: imx290: Properly encode registers as little-endian
2023-11-01 12:23 [PATCH v2 0/2] v4l2-cci: little-endian registers Alexander Stein
2023-11-01 12:23 ` [PATCH v2 1/2] media: v4l2-cci: Add support for little-endian encoded registers Alexander Stein
@ 2023-11-01 12:23 ` Alexander Stein
2023-11-02 1:23 ` Laurent Pinchart
2023-11-01 15:26 ` [PATCH v2 0/2] v4l2-cci: little-endian registers Hans de Goede
2 siblings, 1 reply; 16+ messages in thread
From: Alexander Stein @ 2023-11-01 12:23 UTC (permalink / raw)
To: Mauro Carvalho Chehab, Sakari Ailus, Manivannan Sadhasivam,
Laurent Pinchart, Hans de Goede
Cc: Alexander Stein, linux-media, Alain Volmat, stable
The conversion to CCI also converted the multi-byte register access to
big-endian. Correct the register definition by using the correct
little-endian ones.
Fixes: af73323b97702 ("media: imx290: Convert to new CCI register access helpers")
Cc: stable@vger.kernel.org
Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
---
drivers/media/i2c/imx290.c | 42 +++++++++++++++++++-------------------
1 file changed, 21 insertions(+), 21 deletions(-)
diff --git a/drivers/media/i2c/imx290.c b/drivers/media/i2c/imx290.c
index 29098612813cb..c6fea5837a19f 100644
--- a/drivers/media/i2c/imx290.c
+++ b/drivers/media/i2c/imx290.c
@@ -41,18 +41,18 @@
#define IMX290_WINMODE_720P (1 << 4)
#define IMX290_WINMODE_CROP (4 << 4)
#define IMX290_FR_FDG_SEL CCI_REG8(0x3009)
-#define IMX290_BLKLEVEL CCI_REG16(0x300a)
+#define IMX290_BLKLEVEL CCI_REG16_LE(0x300a)
#define IMX290_GAIN CCI_REG8(0x3014)
-#define IMX290_VMAX CCI_REG24(0x3018)
+#define IMX290_VMAX CCI_REG24_LE(0x3018)
#define IMX290_VMAX_MAX 0x3ffff
-#define IMX290_HMAX CCI_REG16(0x301c)
+#define IMX290_HMAX CCI_REG16_LE(0x301c)
#define IMX290_HMAX_MAX 0xffff
-#define IMX290_SHS1 CCI_REG24(0x3020)
+#define IMX290_SHS1 CCI_REG24_LE(0x3020)
#define IMX290_WINWV_OB CCI_REG8(0x303a)
-#define IMX290_WINPV CCI_REG16(0x303c)
-#define IMX290_WINWV CCI_REG16(0x303e)
-#define IMX290_WINPH CCI_REG16(0x3040)
-#define IMX290_WINWH CCI_REG16(0x3042)
+#define IMX290_WINPV CCI_REG16_LE(0x303c)
+#define IMX290_WINWV CCI_REG16_LE(0x303e)
+#define IMX290_WINPH CCI_REG16_LE(0x3040)
+#define IMX290_WINWH CCI_REG16_LE(0x3042)
#define IMX290_OUT_CTRL CCI_REG8(0x3046)
#define IMX290_ODBIT_10BIT (0 << 0)
#define IMX290_ODBIT_12BIT (1 << 0)
@@ -78,28 +78,28 @@
#define IMX290_ADBIT2 CCI_REG8(0x317c)
#define IMX290_ADBIT2_10BIT 0x12
#define IMX290_ADBIT2_12BIT 0x00
-#define IMX290_CHIP_ID CCI_REG16(0x319a)
+#define IMX290_CHIP_ID CCI_REG16_LE(0x319a)
#define IMX290_ADBIT3 CCI_REG8(0x31ec)
#define IMX290_ADBIT3_10BIT 0x37
#define IMX290_ADBIT3_12BIT 0x0e
#define IMX290_REPETITION CCI_REG8(0x3405)
#define IMX290_PHY_LANE_NUM CCI_REG8(0x3407)
#define IMX290_OPB_SIZE_V CCI_REG8(0x3414)
-#define IMX290_Y_OUT_SIZE CCI_REG16(0x3418)
-#define IMX290_CSI_DT_FMT CCI_REG16(0x3441)
+#define IMX290_Y_OUT_SIZE CCI_REG16_LE(0x3418)
+#define IMX290_CSI_DT_FMT CCI_REG16_LE(0x3441)
#define IMX290_CSI_DT_FMT_RAW10 0x0a0a
#define IMX290_CSI_DT_FMT_RAW12 0x0c0c
#define IMX290_CSI_LANE_MODE CCI_REG8(0x3443)
-#define IMX290_EXTCK_FREQ CCI_REG16(0x3444)
-#define IMX290_TCLKPOST CCI_REG16(0x3446)
-#define IMX290_THSZERO CCI_REG16(0x3448)
-#define IMX290_THSPREPARE CCI_REG16(0x344a)
-#define IMX290_TCLKTRAIL CCI_REG16(0x344c)
-#define IMX290_THSTRAIL CCI_REG16(0x344e)
-#define IMX290_TCLKZERO CCI_REG16(0x3450)
-#define IMX290_TCLKPREPARE CCI_REG16(0x3452)
-#define IMX290_TLPX CCI_REG16(0x3454)
-#define IMX290_X_OUT_SIZE CCI_REG16(0x3472)
+#define IMX290_EXTCK_FREQ CCI_REG16_LE(0x3444)
+#define IMX290_TCLKPOST CCI_REG16_LE(0x3446)
+#define IMX290_THSZERO CCI_REG16_LE(0x3448)
+#define IMX290_THSPREPARE CCI_REG16_LE(0x344a)
+#define IMX290_TCLKTRAIL CCI_REG16_LE(0x344c)
+#define IMX290_THSTRAIL CCI_REG16_LE(0x344e)
+#define IMX290_TCLKZERO CCI_REG16_LE(0x3450)
+#define IMX290_TCLKPREPARE CCI_REG16_LE(0x3452)
+#define IMX290_TLPX CCI_REG16_LE(0x3454)
+#define IMX290_X_OUT_SIZE CCI_REG16_LE(0x3472)
#define IMX290_INCKSEL7 CCI_REG8(0x3480)
#define IMX290_PGCTRL_REGEN BIT(0)
--
2.34.1
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v2 0/2] v4l2-cci: little-endian registers
2023-11-01 12:23 [PATCH v2 0/2] v4l2-cci: little-endian registers Alexander Stein
2023-11-01 12:23 ` [PATCH v2 1/2] media: v4l2-cci: Add support for little-endian encoded registers Alexander Stein
2023-11-01 12:23 ` [PATCH v2 2/2] media: i2c: imx290: Properly encode registers as little-endian Alexander Stein
@ 2023-11-01 15:26 ` Hans de Goede
2 siblings, 0 replies; 16+ messages in thread
From: Hans de Goede @ 2023-11-01 15:26 UTC (permalink / raw)
To: Alexander Stein, Mauro Carvalho Chehab, Sakari Ailus,
Manivannan Sadhasivam, Laurent Pinchart
Cc: linux-media, Alain Volmat
Hoi,
On 11/1/23 13:23, Alexander Stein wrote:
> Hi,
>
> after the discussions at [1] and [2], this series adds proper support for
> little-endian encoded registers.
> Patch 1 adds the infrastructure and patch 2 fixes imx290 driver.
> As v6.6 was released with imx290 broken, both should be added to stable.
>
> Changes in v2:
> * Add proper Fixes/CC tags to both patches
> * Add little-endian support for cci_read()
Thanks, this version looks good to me:
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
for the series.
Regards,
Hans
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 1/2] media: v4l2-cci: Add support for little-endian encoded registers
2023-11-01 12:23 ` [PATCH v2 1/2] media: v4l2-cci: Add support for little-endian encoded registers Alexander Stein
@ 2023-11-02 1:22 ` Laurent Pinchart
2023-11-02 6:30 ` Sakari Ailus
2023-11-02 7:55 ` Alexander Stein
0 siblings, 2 replies; 16+ messages in thread
From: Laurent Pinchart @ 2023-11-02 1:22 UTC (permalink / raw)
To: Alexander Stein
Cc: Mauro Carvalho Chehab, Sakari Ailus, Manivannan Sadhasivam,
Hans de Goede, linux-media, Alain Volmat, stable
Hi Alexander,
Thank you for the patch.
On Wed, Nov 01, 2023 at 01:23:53PM +0100, Alexander Stein wrote:
> Some sensors, e.g. Sony, are using little-endian registers. Add support for
I would write Sony IMX290 here, as there are Sony sensors that use big
endian.
> those by encoding the endianess into Bit 20 of the register address.
>
> Fixes: af73323b97702 ("media: imx290: Convert to new CCI register access helpers")
> Cc: stable@vger.kernel.org
> Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
> ---
> drivers/media/v4l2-core/v4l2-cci.c | 44 ++++++++++++++++++++++++------
> include/media/v4l2-cci.h | 5 ++++
> 2 files changed, 41 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/media/v4l2-core/v4l2-cci.c b/drivers/media/v4l2-core/v4l2-cci.c
> index bc2dbec019b04..673637b67bf67 100644
> --- a/drivers/media/v4l2-core/v4l2-cci.c
> +++ b/drivers/media/v4l2-core/v4l2-cci.c
> @@ -18,6 +18,7 @@
>
> int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
> {
> + bool little_endian;
> unsigned int len;
> u8 buf[8];
> int ret;
> @@ -25,6 +26,7 @@ int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
> if (err && *err)
> return *err;
>
> + little_endian = reg & CCI_REG_LE;
You could initialize the variable when declaring it. Same below.
> len = FIELD_GET(CCI_REG_WIDTH_MASK, reg);
> reg = FIELD_GET(CCI_REG_ADDR_MASK, reg);
>
> @@ -40,16 +42,28 @@ int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
> *val = buf[0];
> break;
> case 2:
> - *val = get_unaligned_be16(buf);
> + if (little_endian)
> + *val = get_unaligned_le16(buf);
> + else
> + *val = get_unaligned_be16(buf);
Unrelated to this patch, isn't buf aligned to a 4 bytes boundary ?
> break;
> case 3:
> - *val = get_unaligned_be24(buf);
> + if (little_endian)
> + *val = get_unaligned_le24(buf);
> + else
> + *val = get_unaligned_be24(buf);
> break;
> case 4:
> - *val = get_unaligned_be32(buf);
> + if (little_endian)
> + *val = get_unaligned_le32(buf);
> + else
> + *val = get_unaligned_be32(buf);
> break;
> case 8:
> - *val = get_unaligned_be64(buf);
> + if (little_endian)
> + *val = get_unaligned_le64(buf);
> + else
> + *val = get_unaligned_be64(buf);
> break;
> default:
> dev_err(regmap_get_device(map), "Error invalid reg-width %u for reg 0x%04x\n",
> @@ -68,6 +82,7 @@ EXPORT_SYMBOL_GPL(cci_read);
>
> int cci_write(struct regmap *map, u32 reg, u64 val, int *err)
> {
> + bool little_endian;
> unsigned int len;
> u8 buf[8];
> int ret;
> @@ -75,6 +90,7 @@ int cci_write(struct regmap *map, u32 reg, u64 val, int *err)
> if (err && *err)
> return *err;
>
> + little_endian = reg & CCI_REG_LE;
> len = FIELD_GET(CCI_REG_WIDTH_MASK, reg);
> reg = FIELD_GET(CCI_REG_ADDR_MASK, reg);
>
> @@ -83,16 +99,28 @@ int cci_write(struct regmap *map, u32 reg, u64 val, int *err)
> buf[0] = val;
> break;
> case 2:
> - put_unaligned_be16(val, buf);
> + if (little_endian)
> + put_unaligned_le16(val, buf);
> + else
> + put_unaligned_be16(val, buf);
> break;
> case 3:
> - put_unaligned_be24(val, buf);
> + if (little_endian)
> + put_unaligned_le24(val, buf);
> + else
> + put_unaligned_be24(val, buf);
> break;
> case 4:
> - put_unaligned_be32(val, buf);
> + if (little_endian)
> + put_unaligned_le32(val, buf);
> + else
> + put_unaligned_be32(val, buf);
> break;
> case 8:
> - put_unaligned_be64(val, buf);
> + if (little_endian)
> + put_unaligned_le64(val, buf);
> + else
> + put_unaligned_be64(val, buf);
> break;
> default:
> dev_err(regmap_get_device(map), "Error invalid reg-width %u for reg 0x%04x\n",
> diff --git a/include/media/v4l2-cci.h b/include/media/v4l2-cci.h
> index 0f6803e4b17e9..ef3faf0c9d44d 100644
> --- a/include/media/v4l2-cci.h
> +++ b/include/media/v4l2-cci.h
> @@ -32,12 +32,17 @@ struct cci_reg_sequence {
> #define CCI_REG_ADDR_MASK GENMASK(15, 0)
> #define CCI_REG_WIDTH_SHIFT 16
> #define CCI_REG_WIDTH_MASK GENMASK(19, 16)
> +#define CCI_REG_LE BIT(20)
>
> #define CCI_REG8(x) ((1 << CCI_REG_WIDTH_SHIFT) | (x))
> #define CCI_REG16(x) ((2 << CCI_REG_WIDTH_SHIFT) | (x))
> #define CCI_REG24(x) ((3 << CCI_REG_WIDTH_SHIFT) | (x))
> #define CCI_REG32(x) ((4 << CCI_REG_WIDTH_SHIFT) | (x))
> #define CCI_REG64(x) ((8 << CCI_REG_WIDTH_SHIFT) | (x))
> +#define CCI_REG16_LE(x) ((2 << CCI_REG_WIDTH_SHIFT) | (x) | CCI_REG_LE)
> +#define CCI_REG24_LE(x) ((3 << CCI_REG_WIDTH_SHIFT) | (x) | CCI_REG_LE)
> +#define CCI_REG32_LE(x) ((4 << CCI_REG_WIDTH_SHIFT) | (x) | CCI_REG_LE)
> +#define CCI_REG64_LE(x) ((8 << CCI_REG_WIDTH_SHIFT) | (x) | CCI_REG_LE)
I would put CCI_REG_LE first, to match the bits order.
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
>
> /**
> * cci_read() - Read a value from a single CCI register
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 2/2] media: i2c: imx290: Properly encode registers as little-endian
2023-11-01 12:23 ` [PATCH v2 2/2] media: i2c: imx290: Properly encode registers as little-endian Alexander Stein
@ 2023-11-02 1:23 ` Laurent Pinchart
0 siblings, 0 replies; 16+ messages in thread
From: Laurent Pinchart @ 2023-11-02 1:23 UTC (permalink / raw)
To: Alexander Stein
Cc: Mauro Carvalho Chehab, Sakari Ailus, Manivannan Sadhasivam,
Hans de Goede, linux-media, Alain Volmat, stable
Hi Alexander,
Thank you for the patch.
On Wed, Nov 01, 2023 at 01:23:54PM +0100, Alexander Stein wrote:
> The conversion to CCI also converted the multi-byte register access to
> big-endian. Correct the register definition by using the correct
> little-endian ones.
>
> Fixes: af73323b97702 ("media: imx290: Convert to new CCI register access helpers")
> Cc: stable@vger.kernel.org
> Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
> drivers/media/i2c/imx290.c | 42 +++++++++++++++++++-------------------
> 1 file changed, 21 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/media/i2c/imx290.c b/drivers/media/i2c/imx290.c
> index 29098612813cb..c6fea5837a19f 100644
> --- a/drivers/media/i2c/imx290.c
> +++ b/drivers/media/i2c/imx290.c
> @@ -41,18 +41,18 @@
> #define IMX290_WINMODE_720P (1 << 4)
> #define IMX290_WINMODE_CROP (4 << 4)
> #define IMX290_FR_FDG_SEL CCI_REG8(0x3009)
> -#define IMX290_BLKLEVEL CCI_REG16(0x300a)
> +#define IMX290_BLKLEVEL CCI_REG16_LE(0x300a)
> #define IMX290_GAIN CCI_REG8(0x3014)
> -#define IMX290_VMAX CCI_REG24(0x3018)
> +#define IMX290_VMAX CCI_REG24_LE(0x3018)
> #define IMX290_VMAX_MAX 0x3ffff
> -#define IMX290_HMAX CCI_REG16(0x301c)
> +#define IMX290_HMAX CCI_REG16_LE(0x301c)
> #define IMX290_HMAX_MAX 0xffff
> -#define IMX290_SHS1 CCI_REG24(0x3020)
> +#define IMX290_SHS1 CCI_REG24_LE(0x3020)
> #define IMX290_WINWV_OB CCI_REG8(0x303a)
> -#define IMX290_WINPV CCI_REG16(0x303c)
> -#define IMX290_WINWV CCI_REG16(0x303e)
> -#define IMX290_WINPH CCI_REG16(0x3040)
> -#define IMX290_WINWH CCI_REG16(0x3042)
> +#define IMX290_WINPV CCI_REG16_LE(0x303c)
> +#define IMX290_WINWV CCI_REG16_LE(0x303e)
> +#define IMX290_WINPH CCI_REG16_LE(0x3040)
> +#define IMX290_WINWH CCI_REG16_LE(0x3042)
> #define IMX290_OUT_CTRL CCI_REG8(0x3046)
> #define IMX290_ODBIT_10BIT (0 << 0)
> #define IMX290_ODBIT_12BIT (1 << 0)
> @@ -78,28 +78,28 @@
> #define IMX290_ADBIT2 CCI_REG8(0x317c)
> #define IMX290_ADBIT2_10BIT 0x12
> #define IMX290_ADBIT2_12BIT 0x00
> -#define IMX290_CHIP_ID CCI_REG16(0x319a)
> +#define IMX290_CHIP_ID CCI_REG16_LE(0x319a)
> #define IMX290_ADBIT3 CCI_REG8(0x31ec)
> #define IMX290_ADBIT3_10BIT 0x37
> #define IMX290_ADBIT3_12BIT 0x0e
> #define IMX290_REPETITION CCI_REG8(0x3405)
> #define IMX290_PHY_LANE_NUM CCI_REG8(0x3407)
> #define IMX290_OPB_SIZE_V CCI_REG8(0x3414)
> -#define IMX290_Y_OUT_SIZE CCI_REG16(0x3418)
> -#define IMX290_CSI_DT_FMT CCI_REG16(0x3441)
> +#define IMX290_Y_OUT_SIZE CCI_REG16_LE(0x3418)
> +#define IMX290_CSI_DT_FMT CCI_REG16_LE(0x3441)
> #define IMX290_CSI_DT_FMT_RAW10 0x0a0a
> #define IMX290_CSI_DT_FMT_RAW12 0x0c0c
> #define IMX290_CSI_LANE_MODE CCI_REG8(0x3443)
> -#define IMX290_EXTCK_FREQ CCI_REG16(0x3444)
> -#define IMX290_TCLKPOST CCI_REG16(0x3446)
> -#define IMX290_THSZERO CCI_REG16(0x3448)
> -#define IMX290_THSPREPARE CCI_REG16(0x344a)
> -#define IMX290_TCLKTRAIL CCI_REG16(0x344c)
> -#define IMX290_THSTRAIL CCI_REG16(0x344e)
> -#define IMX290_TCLKZERO CCI_REG16(0x3450)
> -#define IMX290_TCLKPREPARE CCI_REG16(0x3452)
> -#define IMX290_TLPX CCI_REG16(0x3454)
> -#define IMX290_X_OUT_SIZE CCI_REG16(0x3472)
> +#define IMX290_EXTCK_FREQ CCI_REG16_LE(0x3444)
> +#define IMX290_TCLKPOST CCI_REG16_LE(0x3446)
> +#define IMX290_THSZERO CCI_REG16_LE(0x3448)
> +#define IMX290_THSPREPARE CCI_REG16_LE(0x344a)
> +#define IMX290_TCLKTRAIL CCI_REG16_LE(0x344c)
> +#define IMX290_THSTRAIL CCI_REG16_LE(0x344e)
> +#define IMX290_TCLKZERO CCI_REG16_LE(0x3450)
> +#define IMX290_TCLKPREPARE CCI_REG16_LE(0x3452)
> +#define IMX290_TLPX CCI_REG16_LE(0x3454)
> +#define IMX290_X_OUT_SIZE CCI_REG16_LE(0x3472)
> #define IMX290_INCKSEL7 CCI_REG8(0x3480)
>
> #define IMX290_PGCTRL_REGEN BIT(0)
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 1/2] media: v4l2-cci: Add support for little-endian encoded registers
2023-11-02 1:22 ` Laurent Pinchart
@ 2023-11-02 6:30 ` Sakari Ailus
2023-11-02 7:51 ` Alexander Stein
2023-11-02 7:55 ` Alexander Stein
1 sibling, 1 reply; 16+ messages in thread
From: Sakari Ailus @ 2023-11-02 6:30 UTC (permalink / raw)
To: Laurent Pinchart
Cc: Alexander Stein, Mauro Carvalho Chehab, Manivannan Sadhasivam,
Hans de Goede, linux-media, Alain Volmat, stable
Hi Laurent,
On Thu, Nov 02, 2023 at 03:22:17AM +0200, Laurent Pinchart wrote:
> Hi Alexander,
>
> Thank you for the patch.
>
> On Wed, Nov 01, 2023 at 01:23:53PM +0100, Alexander Stein wrote:
> > Some sensors, e.g. Sony, are using little-endian registers. Add support for
>
> I would write Sony IMX290 here, as there are Sony sensors that use big
> endian.
Almost all of them. There are a few exceptions indeed. This seems to be a
bug.
>
> > those by encoding the endianess into Bit 20 of the register address.
> >
> > Fixes: af73323b97702 ("media: imx290: Convert to new CCI register access helpers")
> > Cc: stable@vger.kernel.org
> > Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
> > ---
> > drivers/media/v4l2-core/v4l2-cci.c | 44 ++++++++++++++++++++++++------
> > include/media/v4l2-cci.h | 5 ++++
> > 2 files changed, 41 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/media/v4l2-core/v4l2-cci.c b/drivers/media/v4l2-core/v4l2-cci.c
> > index bc2dbec019b04..673637b67bf67 100644
> > --- a/drivers/media/v4l2-core/v4l2-cci.c
> > +++ b/drivers/media/v4l2-core/v4l2-cci.c
> > @@ -18,6 +18,7 @@
> >
> > int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
> > {
> > + bool little_endian;
> > unsigned int len;
> > u8 buf[8];
> > int ret;
> > @@ -25,6 +26,7 @@ int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
> > if (err && *err)
> > return *err;
> >
> > + little_endian = reg & CCI_REG_LE;
>
> You could initialize the variable when declaring it. Same below.
I was thinking of the same, but then it'd be logical to move initialisation
of all related variables there. reg is modified here though. I'd keep
setting little_endian here. If someone wants to move it, that could be done
in a separate patch.
>
> > len = FIELD_GET(CCI_REG_WIDTH_MASK, reg);
> > reg = FIELD_GET(CCI_REG_ADDR_MASK, reg);
> >
> > @@ -40,16 +42,28 @@ int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
> > *val = buf[0];
> > break;
> > case 2:
> > - *val = get_unaligned_be16(buf);
> > + if (little_endian)
> > + *val = get_unaligned_le16(buf);
> > + else
> > + *val = get_unaligned_be16(buf);
>
> Unrelated to this patch, isn't buf aligned to a 4 bytes boundary ?
Very probably, as it's right after len that's an unsigned int. Adding
__aligned(8) would ensure we don't need any of the unaligned variants, and
most likely would keep the stack layout as-is.
Or... how about putting it in an union with a u64? That would mean it's
accessible as u64 alignment-wise while the alignment itself is up to the
ABI. A comment would be good to have probably.
>
> > break;
> > case 3:
> > - *val = get_unaligned_be24(buf);
> > + if (little_endian)
> > + *val = get_unaligned_le24(buf);
> > + else
> > + *val = get_unaligned_be24(buf);
> > break;
> > case 4:
> > - *val = get_unaligned_be32(buf);
> > + if (little_endian)
> > + *val = get_unaligned_le32(buf);
> > + else
> > + *val = get_unaligned_be32(buf);
> > break;
> > case 8:
> > - *val = get_unaligned_be64(buf);
> > + if (little_endian)
> > + *val = get_unaligned_le64(buf);
> > + else
> > + *val = get_unaligned_be64(buf);
> > break;
> > default:
> > dev_err(regmap_get_device(map), "Error invalid reg-width %u for reg 0x%04x\n",
--
Regards,
Sakari Ailus
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 1/2] media: v4l2-cci: Add support for little-endian encoded registers
2023-11-02 6:30 ` Sakari Ailus
@ 2023-11-02 7:51 ` Alexander Stein
2023-11-02 8:25 ` Sakari Ailus
0 siblings, 1 reply; 16+ messages in thread
From: Alexander Stein @ 2023-11-02 7:51 UTC (permalink / raw)
To: Laurent Pinchart, Sakari Ailus
Cc: Mauro Carvalho Chehab, Manivannan Sadhasivam, Hans de Goede,
linux-media, Alain Volmat, stable
Hi,
thanks for the feedback.
Am Donnerstag, 2. November 2023, 07:30:44 CET schrieb Sakari Ailus:
> Hi Laurent,
>
> On Thu, Nov 02, 2023 at 03:22:17AM +0200, Laurent Pinchart wrote:
> > Hi Alexander,
> >
> > Thank you for the patch.
> >
> > On Wed, Nov 01, 2023 at 01:23:53PM +0100, Alexander Stein wrote:
> > > Some sensors, e.g. Sony, are using little-endian registers. Add support
> > > for
> >
> > I would write Sony IMX290 here, as there are Sony sensors that use big
> > endian.
>
> Almost all of them. There are a few exceptions indeed. This seems to be a
> bug.
Let's name IMX290 here as an actual example. No need to worry about other
models here.
> > > those by encoding the endianess into Bit 20 of the register address.
> > >
> > > Fixes: af73323b97702 ("media: imx290: Convert to new CCI register access
> > > helpers") Cc: stable@vger.kernel.org
> > > Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
> > > ---
> > >
> > > drivers/media/v4l2-core/v4l2-cci.c | 44 ++++++++++++++++++++++++------
> > > include/media/v4l2-cci.h | 5 ++++
> > > 2 files changed, 41 insertions(+), 8 deletions(-)
> > >
> > > diff --git a/drivers/media/v4l2-core/v4l2-cci.c
> > > b/drivers/media/v4l2-core/v4l2-cci.c index bc2dbec019b04..673637b67bf67
> > > 100644
> > > --- a/drivers/media/v4l2-core/v4l2-cci.c
> > > +++ b/drivers/media/v4l2-core/v4l2-cci.c
> > > @@ -18,6 +18,7 @@
> > >
> > > int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
> > > {
> > >
> > > + bool little_endian;
> > >
> > > unsigned int len;
> > > u8 buf[8];
> > > int ret;
> > >
> > > @@ -25,6 +26,7 @@ int cci_read(struct regmap *map, u32 reg, u64 *val,
> > > int *err)> >
> > > if (err && *err)
> > >
> > > return *err;
> > >
> > > + little_endian = reg & CCI_REG_LE;
> >
> > You could initialize the variable when declaring it. Same below.
>
> I was thinking of the same, but then it'd be logical to move initialisation
> of all related variables there. reg is modified here though. I'd keep
> setting little_endian here. If someone wants to move it, that could be done
> in a separate patch.
>
> > > len = FIELD_GET(CCI_REG_WIDTH_MASK, reg);
> > > reg = FIELD_GET(CCI_REG_ADDR_MASK, reg);
> > >
> > > @@ -40,16 +42,28 @@ int cci_read(struct regmap *map, u32 reg, u64 *val,
> > > int *err)> >
> > > *val = buf[0];
> > > break;
> > >
> > > case 2:
> > > - *val = get_unaligned_be16(buf);
> > > + if (little_endian)
> > > + *val = get_unaligned_le16(buf);
> > > + else
> > > + *val = get_unaligned_be16(buf);
> >
> > Unrelated to this patch, isn't buf aligned to a 4 bytes boundary ?
>
> Very probably, as it's right after len that's an unsigned int. Adding
> __aligned(8) would ensure we don't need any of the unaligned variants, and
> most likely would keep the stack layout as-is.
You mean something like this?
u8 __aligned(8) buf[8];
[...]
if (little_endian)
*val = le64_to_cpup(buf);
else
*val = be64_to_cpup(buf);
But what about 24 Bits? There is no le24_to_cpup. I would rather use the same
API for all cases.
> Or... how about putting it in an union with a u64? That would mean it's
> accessible as u64 alignment-wise while the alignment itself is up to the
> ABI. A comment would be good to have probably.
An additional union seems a bit too much here. Unless something suitable
already exists for general usage.
Best regards,
Alexander
> > > break;
> > >
> > > case 3:
> > > - *val = get_unaligned_be24(buf);
> > > + if (little_endian)
> > > + *val = get_unaligned_le24(buf);
> > > + else
> > > + *val = get_unaligned_be24(buf);
> > >
> > > break;
> > >
> > > case 4:
> > > - *val = get_unaligned_be32(buf);
> > > + if (little_endian)
> > > + *val = get_unaligned_le32(buf);
> > > + else
> > > + *val = get_unaligned_be32(buf);
> > >
> > > break;
> > >
> > > case 8:
> > > - *val = get_unaligned_be64(buf);
> > > + if (little_endian)
> > > + *val = get_unaligned_le64(buf);
> > > + else
> > > + *val = get_unaligned_be64(buf);
> > >
> > > break;
> > >
> > > default:
> > > dev_err(regmap_get_device(map), "Error invalid reg-width
%u for reg
> > > 0x%04x\n",
--
TQ-Systems GmbH | Mühlstraße 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht München, HRB 105018
Geschäftsführer: Detlef Schneider, Rüdiger Stahl, Stefan Schneider
http://www.tq-group.com/
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 1/2] media: v4l2-cci: Add support for little-endian encoded registers
2023-11-02 1:22 ` Laurent Pinchart
2023-11-02 6:30 ` Sakari Ailus
@ 2023-11-02 7:55 ` Alexander Stein
2023-11-02 8:24 ` Laurent Pinchart
1 sibling, 1 reply; 16+ messages in thread
From: Alexander Stein @ 2023-11-02 7:55 UTC (permalink / raw)
To: Laurent Pinchart
Cc: Mauro Carvalho Chehab, Sakari Ailus, Manivannan Sadhasivam,
Hans de Goede, linux-media, Alain Volmat, stable
Am Donnerstag, 2. November 2023, 02:22:17 CET schrieb Laurent Pinchart:
> ********************
> Achtung externe E-Mail: Öffnen Sie Anhänge und Links nur, wenn Sie wissen,
> dass diese aus einer sicheren Quelle stammen und sicher sind. Leiten Sie
> die E-Mail im Zweifelsfall zur Prüfung an den IT-Helpdesk weiter.
> Attention external email: Open attachments and links only if you know that
> they are from a secure source and are safe. In doubt forward the email to
> the IT-Helpdesk to check it. ********************
>
> Hi Alexander,
>
> Thank you for the patch.
>
> On Wed, Nov 01, 2023 at 01:23:53PM +0100, Alexander Stein wrote:
> > Some sensors, e.g. Sony, are using little-endian registers. Add support
> > for
>
> I would write Sony IMX290 here, as there are Sony sensors that use big
> endian.
>
> > those by encoding the endianess into Bit 20 of the register address.
> >
> > Fixes: af73323b97702 ("media: imx290: Convert to new CCI register access
> > helpers") Cc: stable@vger.kernel.org
> > Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
> > ---
> >
> > drivers/media/v4l2-core/v4l2-cci.c | 44 ++++++++++++++++++++++++------
> > include/media/v4l2-cci.h | 5 ++++
> > 2 files changed, 41 insertions(+), 8 deletions(-)
> >
> > diff --git a/drivers/media/v4l2-core/v4l2-cci.c
> > b/drivers/media/v4l2-core/v4l2-cci.c index bc2dbec019b04..673637b67bf67
> > 100644
> > --- a/drivers/media/v4l2-core/v4l2-cci.c
> > +++ b/drivers/media/v4l2-core/v4l2-cci.c
> > @@ -18,6 +18,7 @@
> >
> > int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
> > {
> >
> > + bool little_endian;
> >
> > unsigned int len;
> > u8 buf[8];
> > int ret;
> >
> > @@ -25,6 +26,7 @@ int cci_read(struct regmap *map, u32 reg, u64 *val, int
> > *err)>
> > if (err && *err)
> >
> > return *err;
> >
> > + little_endian = reg & CCI_REG_LE;
>
> You could initialize the variable when declaring it. Same below.
>
> > len = FIELD_GET(CCI_REG_WIDTH_MASK, reg);
> > reg = FIELD_GET(CCI_REG_ADDR_MASK, reg);
> >
> > @@ -40,16 +42,28 @@ int cci_read(struct regmap *map, u32 reg, u64 *val,
> > int *err)>
> > *val = buf[0];
> > break;
> >
> > case 2:
> > - *val = get_unaligned_be16(buf);
> > + if (little_endian)
> > + *val = get_unaligned_le16(buf);
> > + else
> > + *val = get_unaligned_be16(buf);
>
> Unrelated to this patch, isn't buf aligned to a 4 bytes boundary ?
>
> > break;
> >
> > case 3:
> > - *val = get_unaligned_be24(buf);
> > + if (little_endian)
> > + *val = get_unaligned_le24(buf);
> > + else
> > + *val = get_unaligned_be24(buf);
> >
> > break;
> >
> > case 4:
> > - *val = get_unaligned_be32(buf);
> > + if (little_endian)
> > + *val = get_unaligned_le32(buf);
> > + else
> > + *val = get_unaligned_be32(buf);
> >
> > break;
> >
> > case 8:
> > - *val = get_unaligned_be64(buf);
> > + if (little_endian)
> > + *val = get_unaligned_le64(buf);
> > + else
> > + *val = get_unaligned_be64(buf);
> >
> > break;
> >
> > default:
> > dev_err(regmap_get_device(map), "Error invalid reg-width
%u for reg
> > 0x%04x\n",>
> > @@ -68,6 +82,7 @@ EXPORT_SYMBOL_GPL(cci_read);
> >
> > int cci_write(struct regmap *map, u32 reg, u64 val, int *err)
> > {
> >
> > + bool little_endian;
> >
> > unsigned int len;
> > u8 buf[8];
> > int ret;
> >
> > @@ -75,6 +90,7 @@ int cci_write(struct regmap *map, u32 reg, u64 val, int
> > *err)>
> > if (err && *err)
> >
> > return *err;
> >
> > + little_endian = reg & CCI_REG_LE;
> >
> > len = FIELD_GET(CCI_REG_WIDTH_MASK, reg);
> > reg = FIELD_GET(CCI_REG_ADDR_MASK, reg);
> >
> > @@ -83,16 +99,28 @@ int cci_write(struct regmap *map, u32 reg, u64 val,
> > int *err)>
> > buf[0] = val;
> > break;
> >
> > case 2:
> > - put_unaligned_be16(val, buf);
> > + if (little_endian)
> > + put_unaligned_le16(val, buf);
> > + else
> > + put_unaligned_be16(val, buf);
> >
> > break;
> >
> > case 3:
> > - put_unaligned_be24(val, buf);
> > + if (little_endian)
> > + put_unaligned_le24(val, buf);
> > + else
> > + put_unaligned_be24(val, buf);
> >
> > break;
> >
> > case 4:
> > - put_unaligned_be32(val, buf);
> > + if (little_endian)
> > + put_unaligned_le32(val, buf);
> > + else
> > + put_unaligned_be32(val, buf);
> >
> > break;
> >
> > case 8:
> > - put_unaligned_be64(val, buf);
> > + if (little_endian)
> > + put_unaligned_le64(val, buf);
> > + else
> > + put_unaligned_be64(val, buf);
> >
> > break;
> >
> > default:
> > dev_err(regmap_get_device(map), "Error invalid reg-width
%u for reg
> > 0x%04x\n",>
> > diff --git a/include/media/v4l2-cci.h b/include/media/v4l2-cci.h
> > index 0f6803e4b17e9..ef3faf0c9d44d 100644
> > --- a/include/media/v4l2-cci.h
> > +++ b/include/media/v4l2-cci.h
> > @@ -32,12 +32,17 @@ struct cci_reg_sequence {
> >
> > #define CCI_REG_ADDR_MASK GENMASK(15, 0)
> > #define CCI_REG_WIDTH_SHIFT 16
> > #define CCI_REG_WIDTH_MASK GENMASK(19, 16)
> >
> > +#define CCI_REG_LE BIT(20)
> >
> > #define CCI_REG8(x) ((1 << CCI_REG_WIDTH_SHIFT)
| (x))
> > #define CCI_REG16(x) ((2 << CCI_REG_WIDTH_SHIFT)
| (x))
> > #define CCI_REG24(x) ((3 << CCI_REG_WIDTH_SHIFT)
| (x))
> > #define CCI_REG32(x) ((4 << CCI_REG_WIDTH_SHIFT)
| (x))
> > #define CCI_REG64(x) ((8 << CCI_REG_WIDTH_SHIFT)
| (x))
> >
> > +#define CCI_REG16_LE(x) ((2 << CCI_REG_WIDTH_SHIFT)
| (x) | CCI_REG_LE)
> > +#define CCI_REG24_LE(x) ((3 << CCI_REG_WIDTH_SHIFT)
| (x) | CCI_REG_LE)
> > +#define CCI_REG32_LE(x) ((4 << CCI_REG_WIDTH_SHIFT)
| (x) | CCI_REG_LE)
> > +#define CCI_REG64_LE(x) ((8 << CCI_REG_WIDTH_SHIFT)
| (x) | CCI_REG_LE)
>
> I would put CCI_REG_LE first, to match the bits order.
You mean this order?
CCI_REG8(x)
CCI_REG16_LE(x)
CCI_REG16(x)
CCI_REG24_LE(x)
CCI_REG24(x)
CCI_REG32_LE(x)
CCI_REG32(x)
CCI_REG64_LE(x)
CCI_REG64(x)
I would either keep the _LE variants at the bottom or below to their big-
endian counterpart. I prefer readability thus I would put the _LE at the
bottom, also it aligns nicely with the additional bit set.
Best regards,
Alexander
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
>
> > /**
> >
> > * cci_read() - Read a value from a single CCI register
--
TQ-Systems GmbH | Mühlstraße 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht München, HRB 105018
Geschäftsführer: Detlef Schneider, Rüdiger Stahl, Stefan Schneider
http://www.tq-group.com/
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 1/2] media: v4l2-cci: Add support for little-endian encoded registers
2023-11-02 7:55 ` Alexander Stein
@ 2023-11-02 8:24 ` Laurent Pinchart
2023-11-02 8:31 ` Sakari Ailus
0 siblings, 1 reply; 16+ messages in thread
From: Laurent Pinchart @ 2023-11-02 8:24 UTC (permalink / raw)
To: Alexander Stein
Cc: Mauro Carvalho Chehab, Sakari Ailus, Manivannan Sadhasivam,
Hans de Goede, linux-media, Alain Volmat, stable
Hi Alexander,
On Thu, Nov 02, 2023 at 08:55:01AM +0100, Alexander Stein wrote:
> Am Donnerstag, 2. November 2023, 02:22:17 CET schrieb Laurent Pinchart:
> > On Wed, Nov 01, 2023 at 01:23:53PM +0100, Alexander Stein wrote:
> > > Some sensors, e.g. Sony, are using little-endian registers. Add support
> > > for
> >
> > I would write Sony IMX290 here, as there are Sony sensors that use big
> > endian.
> >
> > > those by encoding the endianess into Bit 20 of the register address.
> > >
> > > Fixes: af73323b97702 ("media: imx290: Convert to new CCI register access
> > > helpers") Cc: stable@vger.kernel.org
> > > Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
> > > ---
> > >
> > > drivers/media/v4l2-core/v4l2-cci.c | 44 ++++++++++++++++++++++++------
> > > include/media/v4l2-cci.h | 5 ++++
> > > 2 files changed, 41 insertions(+), 8 deletions(-)
[snip]
> > > diff --git a/include/media/v4l2-cci.h b/include/media/v4l2-cci.h
> > > index 0f6803e4b17e9..ef3faf0c9d44d 100644
> > > --- a/include/media/v4l2-cci.h
> > > +++ b/include/media/v4l2-cci.h
> > > @@ -32,12 +32,17 @@ struct cci_reg_sequence {
> > > #define CCI_REG_ADDR_MASK GENMASK(15, 0)
> > > #define CCI_REG_WIDTH_SHIFT 16
> > > #define CCI_REG_WIDTH_MASK GENMASK(19, 16)
> > > +#define CCI_REG_LE BIT(20)
> > >
> > > #define CCI_REG8(x) ((1 << CCI_REG_WIDTH_SHIFT) | (x))
> > > #define CCI_REG16(x) ((2 << CCI_REG_WIDTH_SHIFT) | (x))
> > > #define CCI_REG24(x) ((3 << CCI_REG_WIDTH_SHIFT) | (x))
> > > #define CCI_REG32(x) ((4 << CCI_REG_WIDTH_SHIFT) | (x))
> > > #define CCI_REG64(x) ((8 << CCI_REG_WIDTH_SHIFT) | (x))
> > > +#define CCI_REG16_LE(x) ((2 << CCI_REG_WIDTH_SHIFT) | (x) | CCI_REG_LE)
> > > +#define CCI_REG24_LE(x) ((3 << CCI_REG_WIDTH_SHIFT) | (x) | CCI_REG_LE)
> > > +#define CCI_REG32_LE(x) ((4 << CCI_REG_WIDTH_SHIFT) | (x) | CCI_REG_LE)
> > > +#define CCI_REG64_LE(x) ((8 << CCI_REG_WIDTH_SHIFT) | (x) | CCI_REG_LE)
> >
> > I would put CCI_REG_LE first, to match the bits order.
>
> You mean this order?
>
> CCI_REG8(x)
> CCI_REG16_LE(x)
> CCI_REG16(x)
> CCI_REG24_LE(x)
> CCI_REG24(x)
> CCI_REG32_LE(x)
> CCI_REG32(x)
> CCI_REG64_LE(x)
> CCI_REG64(x)
>
> I would either keep the _LE variants at the bottom or below to their big-
> endian counterpart. I prefer readability thus I would put the _LE at the
> bottom, also it aligns nicely with the additional bit set.
No, I meant
#define CCI_REG16_LE(x) (CCI_REG_LE | (2 << CCI_REG_WIDTH_SHIFT) | (x))
#define CCI_REG24_LE(x) (CCI_REG_LE | (3 << CCI_REG_WIDTH_SHIFT) | (x))
#define CCI_REG32_LE(x) (CCI_REG_LE | (4 << CCI_REG_WIDTH_SHIFT) | (x))
#define CCI_REG64_LE(x) (CCI_REG_LE | (8 << CCI_REG_WIDTH_SHIFT) | (x))
> > Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> >
> > > /**
> > >
> > > * cci_read() - Read a value from a single CCI register
--
Regards,
Laurent Pinchart
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 1/2] media: v4l2-cci: Add support for little-endian encoded registers
2023-11-02 7:51 ` Alexander Stein
@ 2023-11-02 8:25 ` Sakari Ailus
2023-11-02 9:27 ` Hans de Goede
0 siblings, 1 reply; 16+ messages in thread
From: Sakari Ailus @ 2023-11-02 8:25 UTC (permalink / raw)
To: Alexander Stein
Cc: Laurent Pinchart, Mauro Carvalho Chehab, Manivannan Sadhasivam,
Hans de Goede, linux-media, Alain Volmat, stable
Hi Alexander,
On Thu, Nov 02, 2023 at 08:51:12AM +0100, Alexander Stein wrote:
> Hi,
>
> thanks for the feedback.
>
> Am Donnerstag, 2. November 2023, 07:30:44 CET schrieb Sakari Ailus:
> > Hi Laurent,
> >
> > On Thu, Nov 02, 2023 at 03:22:17AM +0200, Laurent Pinchart wrote:
> > > Hi Alexander,
> > >
> > > Thank you for the patch.
> > >
> > > On Wed, Nov 01, 2023 at 01:23:53PM +0100, Alexander Stein wrote:
> > > > Some sensors, e.g. Sony, are using little-endian registers. Add support
> > > > for
> > >
> > > I would write Sony IMX290 here, as there are Sony sensors that use big
> > > endian.
> >
> > Almost all of them. There are a few exceptions indeed. This seems to be a
> > bug.
>
> Let's name IMX290 here as an actual example. No need to worry about other
> models here.
>
> > > > those by encoding the endianess into Bit 20 of the register address.
> > > >
> > > > Fixes: af73323b97702 ("media: imx290: Convert to new CCI register access
> > > > helpers") Cc: stable@vger.kernel.org
> > > > Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
> > > > ---
> > > >
> > > > drivers/media/v4l2-core/v4l2-cci.c | 44 ++++++++++++++++++++++++------
> > > > include/media/v4l2-cci.h | 5 ++++
> > > > 2 files changed, 41 insertions(+), 8 deletions(-)
> > > >
> > > > diff --git a/drivers/media/v4l2-core/v4l2-cci.c
> > > > b/drivers/media/v4l2-core/v4l2-cci.c index bc2dbec019b04..673637b67bf67
> > > > 100644
> > > > --- a/drivers/media/v4l2-core/v4l2-cci.c
> > > > +++ b/drivers/media/v4l2-core/v4l2-cci.c
> > > > @@ -18,6 +18,7 @@
> > > >
> > > > int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
> > > > {
> > > >
> > > > + bool little_endian;
> > > >
> > > > unsigned int len;
> > > > u8 buf[8];
> > > > int ret;
> > > >
> > > > @@ -25,6 +26,7 @@ int cci_read(struct regmap *map, u32 reg, u64 *val,
> > > > int *err)> >
> > > > if (err && *err)
> > > >
> > > > return *err;
> > > >
> > > > + little_endian = reg & CCI_REG_LE;
> > >
> > > You could initialize the variable when declaring it. Same below.
> >
> > I was thinking of the same, but then it'd be logical to move initialisation
> > of all related variables there. reg is modified here though. I'd keep
> > setting little_endian here. If someone wants to move it, that could be done
> > in a separate patch.
> >
> > > > len = FIELD_GET(CCI_REG_WIDTH_MASK, reg);
> > > > reg = FIELD_GET(CCI_REG_ADDR_MASK, reg);
> > > >
> > > > @@ -40,16 +42,28 @@ int cci_read(struct regmap *map, u32 reg, u64 *val,
> > > > int *err)> >
> > > > *val = buf[0];
> > > > break;
> > > >
> > > > case 2:
> > > > - *val = get_unaligned_be16(buf);
> > > > + if (little_endian)
> > > > + *val = get_unaligned_le16(buf);
> > > > + else
> > > > + *val = get_unaligned_be16(buf);
> > >
> > > Unrelated to this patch, isn't buf aligned to a 4 bytes boundary ?
> >
> > Very probably, as it's right after len that's an unsigned int. Adding
> > __aligned(8) would ensure we don't need any of the unaligned variants, and
> > most likely would keep the stack layout as-is.
>
> You mean something like this?
>
> u8 __aligned(8) buf[8];
> [...]
> if (little_endian)
> *val = le64_to_cpup(buf);
> else
> *val = be64_to_cpup(buf);
>
> But what about 24 Bits? There is no le24_to_cpup. I would rather use the same
> API for all cases.
The aligned APIs are much better choice when you can use them. The 24 bit
case can remain special IMO.
>
> > Or... how about putting it in an union with a u64? That would mean it's
> > accessible as u64 alignment-wise while the alignment itself is up to the
> > ABI. A comment would be good to have probably.
>
> An additional union seems a bit too much here. Unless something suitable
> already exists for general usage.
I think it's nicer than using __aligned() as you get ABI alignment that
way, not something you force manually --- that's a bit crude.
I wonder that others think.
--
Regards,
Sakari Ailus
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 1/2] media: v4l2-cci: Add support for little-endian encoded registers
2023-11-02 8:24 ` Laurent Pinchart
@ 2023-11-02 8:31 ` Sakari Ailus
2023-11-02 8:33 ` Sakari Ailus
0 siblings, 1 reply; 16+ messages in thread
From: Sakari Ailus @ 2023-11-02 8:31 UTC (permalink / raw)
To: Laurent Pinchart
Cc: Alexander Stein, Mauro Carvalho Chehab, Manivannan Sadhasivam,
Hans de Goede, linux-media, Alain Volmat, stable
Hi Laurent, Alexander,
On Thu, Nov 02, 2023 at 10:24:30AM +0200, Laurent Pinchart wrote:
> Hi Alexander,
>
> On Thu, Nov 02, 2023 at 08:55:01AM +0100, Alexander Stein wrote:
> > Am Donnerstag, 2. November 2023, 02:22:17 CET schrieb Laurent Pinchart:
> > > On Wed, Nov 01, 2023 at 01:23:53PM +0100, Alexander Stein wrote:
> > > > Some sensors, e.g. Sony, are using little-endian registers. Add support
> > > > for
> > >
> > > I would write Sony IMX290 here, as there are Sony sensors that use big
> > > endian.
> > >
> > > > those by encoding the endianess into Bit 20 of the register address.
> > > >
> > > > Fixes: af73323b97702 ("media: imx290: Convert to new CCI register access
> > > > helpers") Cc: stable@vger.kernel.org
> > > > Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
> > > > ---
> > > >
> > > > drivers/media/v4l2-core/v4l2-cci.c | 44 ++++++++++++++++++++++++------
> > > > include/media/v4l2-cci.h | 5 ++++
> > > > 2 files changed, 41 insertions(+), 8 deletions(-)
>
> [snip]
>
> > > > diff --git a/include/media/v4l2-cci.h b/include/media/v4l2-cci.h
> > > > index 0f6803e4b17e9..ef3faf0c9d44d 100644
> > > > --- a/include/media/v4l2-cci.h
> > > > +++ b/include/media/v4l2-cci.h
> > > > @@ -32,12 +32,17 @@ struct cci_reg_sequence {
> > > > #define CCI_REG_ADDR_MASK GENMASK(15, 0)
> > > > #define CCI_REG_WIDTH_SHIFT 16
> > > > #define CCI_REG_WIDTH_MASK GENMASK(19, 16)
> > > > +#define CCI_REG_LE BIT(20)
> > > >
> > > > #define CCI_REG8(x) ((1 << CCI_REG_WIDTH_SHIFT) | (x))
> > > > #define CCI_REG16(x) ((2 << CCI_REG_WIDTH_SHIFT) | (x))
> > > > #define CCI_REG24(x) ((3 << CCI_REG_WIDTH_SHIFT) | (x))
> > > > #define CCI_REG32(x) ((4 << CCI_REG_WIDTH_SHIFT) | (x))
> > > > #define CCI_REG64(x) ((8 << CCI_REG_WIDTH_SHIFT) | (x))
> > > > +#define CCI_REG16_LE(x) ((2 << CCI_REG_WIDTH_SHIFT) | (x) | CCI_REG_LE)
> > > > +#define CCI_REG24_LE(x) ((3 << CCI_REG_WIDTH_SHIFT) | (x) | CCI_REG_LE)
> > > > +#define CCI_REG32_LE(x) ((4 << CCI_REG_WIDTH_SHIFT) | (x) | CCI_REG_LE)
> > > > +#define CCI_REG64_LE(x) ((8 << CCI_REG_WIDTH_SHIFT) | (x) | CCI_REG_LE)
> > >
> > > I would put CCI_REG_LE first, to match the bits order.
> >
> > You mean this order?
> >
> > CCI_REG8(x)
> > CCI_REG16_LE(x)
> > CCI_REG16(x)
> > CCI_REG24_LE(x)
> > CCI_REG24(x)
> > CCI_REG32_LE(x)
> > CCI_REG32(x)
> > CCI_REG64_LE(x)
> > CCI_REG64(x)
> >
> > I would either keep the _LE variants at the bottom or below to their big-
> > endian counterpart. I prefer readability thus I would put the _LE at the
> > bottom, also it aligns nicely with the additional bit set.
>
> No, I meant
>
> #define CCI_REG16_LE(x) (CCI_REG_LE | (2 << CCI_REG_WIDTH_SHIFT) | (x))
> #define CCI_REG24_LE(x) (CCI_REG_LE | (3 << CCI_REG_WIDTH_SHIFT) | (x))
> #define CCI_REG32_LE(x) (CCI_REG_LE | (4 << CCI_REG_WIDTH_SHIFT) | (x))
> #define CCI_REG64_LE(x) (CCI_REG_LE | (8 << CCI_REG_WIDTH_SHIFT) | (x))
Ideally these numbers would be unsigned, i.e.
#define CCI_REG16_LE(x) (CCI_REG_LE | (2U << CCI_REG_WIDTH_SHIFT) | (x))
#define CCI_REG24_LE(x) (CCI_REG_LE | (3U << CCI_REG_WIDTH_SHIFT) | (x))
#define CCI_REG32_LE(x) (CCI_REG_LE | (4U << CCI_REG_WIDTH_SHIFT) | (x))
#define CCI_REG64_LE(x) (CCI_REG_LE | (8U << CCI_REG_WIDTH_SHIFT) | (x))
This is a pre-existing problem. Feel free to add a patch to address it. :-)
--
Kind regards,
Sakari Ailus
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 1/2] media: v4l2-cci: Add support for little-endian encoded registers
2023-11-02 8:31 ` Sakari Ailus
@ 2023-11-02 8:33 ` Sakari Ailus
0 siblings, 0 replies; 16+ messages in thread
From: Sakari Ailus @ 2023-11-02 8:33 UTC (permalink / raw)
To: Laurent Pinchart
Cc: Alexander Stein, Mauro Carvalho Chehab, Manivannan Sadhasivam,
Hans de Goede, linux-media, Alain Volmat, stable
On Thu, Nov 02, 2023 at 08:31:44AM +0000, Sakari Ailus wrote:
> This is a pre-existing problem. Feel free to add a patch to address it. :-)
I forgot to add that addressing may be part of the same set but come as
last, to avoid unnecessarily backporting patches. There's no bug in the
code related to this --- just a bug-prone pattern.
--
Sakari Ailus
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 1/2] media: v4l2-cci: Add support for little-endian encoded registers
2023-11-02 8:25 ` Sakari Ailus
@ 2023-11-02 9:27 ` Hans de Goede
2023-11-02 9:56 ` Sakari Ailus
0 siblings, 1 reply; 16+ messages in thread
From: Hans de Goede @ 2023-11-02 9:27 UTC (permalink / raw)
To: Sakari Ailus, Alexander Stein
Cc: Laurent Pinchart, Mauro Carvalho Chehab, Manivannan Sadhasivam,
linux-media, Alain Volmat, stable
Hi,
On 11/2/23 09:25, Sakari Ailus wrote:
> Hi Alexander,
>
> On Thu, Nov 02, 2023 at 08:51:12AM +0100, Alexander Stein wrote:
>> Hi,
>>
>> thanks for the feedback.
>>
>> Am Donnerstag, 2. November 2023, 07:30:44 CET schrieb Sakari Ailus:
>>> Hi Laurent,
>>>
>>> On Thu, Nov 02, 2023 at 03:22:17AM +0200, Laurent Pinchart wrote:
>>>> Hi Alexander,
>>>>
>>>> Thank you for the patch.
>>>>
>>>> On Wed, Nov 01, 2023 at 01:23:53PM +0100, Alexander Stein wrote:
>>>>> Some sensors, e.g. Sony, are using little-endian registers. Add support
>>>>> for
>>>>
>>>> I would write Sony IMX290 here, as there are Sony sensors that use big
>>>> endian.
>>>
>>> Almost all of them. There are a few exceptions indeed. This seems to be a
>>> bug.
>>
>> Let's name IMX290 here as an actual example. No need to worry about other
>> models here.
>>
>>>>> those by encoding the endianess into Bit 20 of the register address.
>>>>>
>>>>> Fixes: af73323b97702 ("media: imx290: Convert to new CCI register access
>>>>> helpers") Cc: stable@vger.kernel.org
>>>>> Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
>>>>> ---
>>>>>
>>>>> drivers/media/v4l2-core/v4l2-cci.c | 44 ++++++++++++++++++++++++------
>>>>> include/media/v4l2-cci.h | 5 ++++
>>>>> 2 files changed, 41 insertions(+), 8 deletions(-)
>>>>>
>>>>> diff --git a/drivers/media/v4l2-core/v4l2-cci.c
>>>>> b/drivers/media/v4l2-core/v4l2-cci.c index bc2dbec019b04..673637b67bf67
>>>>> 100644
>>>>> --- a/drivers/media/v4l2-core/v4l2-cci.c
>>>>> +++ b/drivers/media/v4l2-core/v4l2-cci.c
>>>>> @@ -18,6 +18,7 @@
>>>>>
>>>>> int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
>>>>> {
>>>>>
>>>>> + bool little_endian;
>>>>>
>>>>> unsigned int len;
>>>>> u8 buf[8];
>>>>> int ret;
>>>>>
>>>>> @@ -25,6 +26,7 @@ int cci_read(struct regmap *map, u32 reg, u64 *val,
>>>>> int *err)> >
>>>>> if (err && *err)
>>>>>
>>>>> return *err;
>>>>>
>>>>> + little_endian = reg & CCI_REG_LE;
>>>>
>>>> You could initialize the variable when declaring it. Same below.
>>>
>>> I was thinking of the same, but then it'd be logical to move initialisation
>>> of all related variables there. reg is modified here though. I'd keep
>>> setting little_endian here. If someone wants to move it, that could be done
>>> in a separate patch.
>>>
>>>>> len = FIELD_GET(CCI_REG_WIDTH_MASK, reg);
>>>>> reg = FIELD_GET(CCI_REG_ADDR_MASK, reg);
>>>>>
>>>>> @@ -40,16 +42,28 @@ int cci_read(struct regmap *map, u32 reg, u64 *val,
>>>>> int *err)> >
>>>>> *val = buf[0];
>>>>> break;
>>>>>
>>>>> case 2:
>>>>> - *val = get_unaligned_be16(buf);
>>>>> + if (little_endian)
>>>>> + *val = get_unaligned_le16(buf);
>>>>> + else
>>>>> + *val = get_unaligned_be16(buf);
>>>>
>>>> Unrelated to this patch, isn't buf aligned to a 4 bytes boundary ?
>>>
>>> Very probably, as it's right after len that's an unsigned int. Adding
>>> __aligned(8) would ensure we don't need any of the unaligned variants, and
>>> most likely would keep the stack layout as-is.
>>
>> You mean something like this?
>>
>> u8 __aligned(8) buf[8];
>> [...]
>> if (little_endian)
>> *val = le64_to_cpup(buf);
>> else
>> *val = be64_to_cpup(buf);
>>
>> But what about 24 Bits? There is no le24_to_cpup. I would rather use the same
>> API for all cases.
>
> The aligned APIs are much better choice when you can use them. The 24 bit
> case can remain special IMO.
>
>>
>>> Or... how about putting it in an union with a u64? That would mean it's
>>> accessible as u64 alignment-wise while the alignment itself is up to the
>>> ABI. A comment would be good to have probably.
>>
>> An additional union seems a bit too much here. Unless something suitable
>> already exists for general usage.
>
> I think it's nicer than using __aligned() as you get ABI alignment that
> way, not something you force manually --- that's a bit crude.
>
> I wonder that others think.
I'm fine with adding the __aligned(8) and switching the non 24 bit
cases to helpers which assume alignment. The most important note
I have is that that is a separate improvement from this series though.
So this should be done in a follow-up patch which is not Cc: stable .
Regards,
Hans
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 1/2] media: v4l2-cci: Add support for little-endian encoded registers
2023-11-02 9:27 ` Hans de Goede
@ 2023-11-02 9:56 ` Sakari Ailus
2023-11-02 9:58 ` Sakari Ailus
0 siblings, 1 reply; 16+ messages in thread
From: Sakari Ailus @ 2023-11-02 9:56 UTC (permalink / raw)
To: Hans de Goede
Cc: Alexander Stein, Laurent Pinchart, Mauro Carvalho Chehab,
Manivannan Sadhasivam, linux-media, Alain Volmat, stable
On Thu, Nov 02, 2023 at 10:27:45AM +0100, Hans de Goede wrote:
> Hi,
>
> On 11/2/23 09:25, Sakari Ailus wrote:
> > Hi Alexander,
> >
> > On Thu, Nov 02, 2023 at 08:51:12AM +0100, Alexander Stein wrote:
> >> Hi,
> >>
> >> thanks for the feedback.
> >>
> >> Am Donnerstag, 2. November 2023, 07:30:44 CET schrieb Sakari Ailus:
> >>> Hi Laurent,
> >>>
> >>> On Thu, Nov 02, 2023 at 03:22:17AM +0200, Laurent Pinchart wrote:
> >>>> Hi Alexander,
> >>>>
> >>>> Thank you for the patch.
> >>>>
> >>>> On Wed, Nov 01, 2023 at 01:23:53PM +0100, Alexander Stein wrote:
> >>>>> Some sensors, e.g. Sony, are using little-endian registers. Add support
> >>>>> for
> >>>>
> >>>> I would write Sony IMX290 here, as there are Sony sensors that use big
> >>>> endian.
> >>>
> >>> Almost all of them. There are a few exceptions indeed. This seems to be a
> >>> bug.
> >>
> >> Let's name IMX290 here as an actual example. No need to worry about other
> >> models here.
> >>
> >>>>> those by encoding the endianess into Bit 20 of the register address.
> >>>>>
> >>>>> Fixes: af73323b97702 ("media: imx290: Convert to new CCI register access
> >>>>> helpers") Cc: stable@vger.kernel.org
> >>>>> Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
> >>>>> ---
> >>>>>
> >>>>> drivers/media/v4l2-core/v4l2-cci.c | 44 ++++++++++++++++++++++++------
> >>>>> include/media/v4l2-cci.h | 5 ++++
> >>>>> 2 files changed, 41 insertions(+), 8 deletions(-)
> >>>>>
> >>>>> diff --git a/drivers/media/v4l2-core/v4l2-cci.c
> >>>>> b/drivers/media/v4l2-core/v4l2-cci.c index bc2dbec019b04..673637b67bf67
> >>>>> 100644
> >>>>> --- a/drivers/media/v4l2-core/v4l2-cci.c
> >>>>> +++ b/drivers/media/v4l2-core/v4l2-cci.c
> >>>>> @@ -18,6 +18,7 @@
> >>>>>
> >>>>> int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
> >>>>> {
> >>>>>
> >>>>> + bool little_endian;
> >>>>>
> >>>>> unsigned int len;
> >>>>> u8 buf[8];
> >>>>> int ret;
> >>>>>
> >>>>> @@ -25,6 +26,7 @@ int cci_read(struct regmap *map, u32 reg, u64 *val,
> >>>>> int *err)> >
> >>>>> if (err && *err)
> >>>>>
> >>>>> return *err;
> >>>>>
> >>>>> + little_endian = reg & CCI_REG_LE;
> >>>>
> >>>> You could initialize the variable when declaring it. Same below.
> >>>
> >>> I was thinking of the same, but then it'd be logical to move initialisation
> >>> of all related variables there. reg is modified here though. I'd keep
> >>> setting little_endian here. If someone wants to move it, that could be done
> >>> in a separate patch.
> >>>
> >>>>> len = FIELD_GET(CCI_REG_WIDTH_MASK, reg);
> >>>>> reg = FIELD_GET(CCI_REG_ADDR_MASK, reg);
> >>>>>
> >>>>> @@ -40,16 +42,28 @@ int cci_read(struct regmap *map, u32 reg, u64 *val,
> >>>>> int *err)> >
> >>>>> *val = buf[0];
> >>>>> break;
> >>>>>
> >>>>> case 2:
> >>>>> - *val = get_unaligned_be16(buf);
> >>>>> + if (little_endian)
> >>>>> + *val = get_unaligned_le16(buf);
> >>>>> + else
> >>>>> + *val = get_unaligned_be16(buf);
> >>>>
> >>>> Unrelated to this patch, isn't buf aligned to a 4 bytes boundary ?
> >>>
> >>> Very probably, as it's right after len that's an unsigned int. Adding
> >>> __aligned(8) would ensure we don't need any of the unaligned variants, and
> >>> most likely would keep the stack layout as-is.
> >>
> >> You mean something like this?
> >>
> >> u8 __aligned(8) buf[8];
> >> [...]
> >> if (little_endian)
> >> *val = le64_to_cpup(buf);
> >> else
> >> *val = be64_to_cpup(buf);
> >>
> >> But what about 24 Bits? There is no le24_to_cpup. I would rather use the same
> >> API for all cases.
> >
> > The aligned APIs are much better choice when you can use them. The 24 bit
> > case can remain special IMO.
> >
> >>
> >>> Or... how about putting it in an union with a u64? That would mean it's
> >>> accessible as u64 alignment-wise while the alignment itself is up to the
> >>> ABI. A comment would be good to have probably.
> >>
> >> An additional union seems a bit too much here. Unless something suitable
> >> already exists for general usage.
> >
> > I think it's nicer than using __aligned() as you get ABI alignment that
> > way, not something you force manually --- that's a bit crude.
> >
> > I wonder that others think.
>
> I'm fine with adding the __aligned(8) and switching the non 24 bit
> cases to helpers which assume alignment. The most important note
> I have is that that is a separate improvement from this series though.
>
> So this should be done in a follow-up patch which is not Cc: stable .
I'm fine with that.
So I think these are good as-is then.
--
Sakari Ailus
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 1/2] media: v4l2-cci: Add support for little-endian encoded registers
2023-11-02 9:56 ` Sakari Ailus
@ 2023-11-02 9:58 ` Sakari Ailus
0 siblings, 0 replies; 16+ messages in thread
From: Sakari Ailus @ 2023-11-02 9:58 UTC (permalink / raw)
To: Hans de Goede
Cc: Alexander Stein, Laurent Pinchart, Mauro Carvalho Chehab,
Manivannan Sadhasivam, linux-media, Alain Volmat, stable
On Thu, Nov 02, 2023 at 09:56:24AM +0000, Sakari Ailus wrote:
> On Thu, Nov 02, 2023 at 10:27:45AM +0100, Hans de Goede wrote:
> > Hi,
> >
> > On 11/2/23 09:25, Sakari Ailus wrote:
> > > Hi Alexander,
> > >
> > > On Thu, Nov 02, 2023 at 08:51:12AM +0100, Alexander Stein wrote:
> > >> Hi,
> > >>
> > >> thanks for the feedback.
> > >>
> > >> Am Donnerstag, 2. November 2023, 07:30:44 CET schrieb Sakari Ailus:
> > >>> Hi Laurent,
> > >>>
> > >>> On Thu, Nov 02, 2023 at 03:22:17AM +0200, Laurent Pinchart wrote:
> > >>>> Hi Alexander,
> > >>>>
> > >>>> Thank you for the patch.
> > >>>>
> > >>>> On Wed, Nov 01, 2023 at 01:23:53PM +0100, Alexander Stein wrote:
> > >>>>> Some sensors, e.g. Sony, are using little-endian registers. Add support
> > >>>>> for
> > >>>>
> > >>>> I would write Sony IMX290 here, as there are Sony sensors that use big
> > >>>> endian.
> > >>>
> > >>> Almost all of them. There are a few exceptions indeed. This seems to be a
> > >>> bug.
> > >>
> > >> Let's name IMX290 here as an actual example. No need to worry about other
> > >> models here.
> > >>
> > >>>>> those by encoding the endianess into Bit 20 of the register address.
> > >>>>>
> > >>>>> Fixes: af73323b97702 ("media: imx290: Convert to new CCI register access
> > >>>>> helpers") Cc: stable@vger.kernel.org
> > >>>>> Signed-off-by: Alexander Stein <alexander.stein@ew.tq-group.com>
> > >>>>> ---
> > >>>>>
> > >>>>> drivers/media/v4l2-core/v4l2-cci.c | 44 ++++++++++++++++++++++++------
> > >>>>> include/media/v4l2-cci.h | 5 ++++
> > >>>>> 2 files changed, 41 insertions(+), 8 deletions(-)
> > >>>>>
> > >>>>> diff --git a/drivers/media/v4l2-core/v4l2-cci.c
> > >>>>> b/drivers/media/v4l2-core/v4l2-cci.c index bc2dbec019b04..673637b67bf67
> > >>>>> 100644
> > >>>>> --- a/drivers/media/v4l2-core/v4l2-cci.c
> > >>>>> +++ b/drivers/media/v4l2-core/v4l2-cci.c
> > >>>>> @@ -18,6 +18,7 @@
> > >>>>>
> > >>>>> int cci_read(struct regmap *map, u32 reg, u64 *val, int *err)
> > >>>>> {
> > >>>>>
> > >>>>> + bool little_endian;
> > >>>>>
> > >>>>> unsigned int len;
> > >>>>> u8 buf[8];
> > >>>>> int ret;
> > >>>>>
> > >>>>> @@ -25,6 +26,7 @@ int cci_read(struct regmap *map, u32 reg, u64 *val,
> > >>>>> int *err)> >
> > >>>>> if (err && *err)
> > >>>>>
> > >>>>> return *err;
> > >>>>>
> > >>>>> + little_endian = reg & CCI_REG_LE;
> > >>>>
> > >>>> You could initialize the variable when declaring it. Same below.
> > >>>
> > >>> I was thinking of the same, but then it'd be logical to move initialisation
> > >>> of all related variables there. reg is modified here though. I'd keep
> > >>> setting little_endian here. If someone wants to move it, that could be done
> > >>> in a separate patch.
> > >>>
> > >>>>> len = FIELD_GET(CCI_REG_WIDTH_MASK, reg);
> > >>>>> reg = FIELD_GET(CCI_REG_ADDR_MASK, reg);
> > >>>>>
> > >>>>> @@ -40,16 +42,28 @@ int cci_read(struct regmap *map, u32 reg, u64 *val,
> > >>>>> int *err)> >
> > >>>>> *val = buf[0];
> > >>>>> break;
> > >>>>>
> > >>>>> case 2:
> > >>>>> - *val = get_unaligned_be16(buf);
> > >>>>> + if (little_endian)
> > >>>>> + *val = get_unaligned_le16(buf);
> > >>>>> + else
> > >>>>> + *val = get_unaligned_be16(buf);
> > >>>>
> > >>>> Unrelated to this patch, isn't buf aligned to a 4 bytes boundary ?
> > >>>
> > >>> Very probably, as it's right after len that's an unsigned int. Adding
> > >>> __aligned(8) would ensure we don't need any of the unaligned variants, and
> > >>> most likely would keep the stack layout as-is.
> > >>
> > >> You mean something like this?
> > >>
> > >> u8 __aligned(8) buf[8];
> > >> [...]
> > >> if (little_endian)
> > >> *val = le64_to_cpup(buf);
> > >> else
> > >> *val = be64_to_cpup(buf);
> > >>
> > >> But what about 24 Bits? There is no le24_to_cpup. I would rather use the same
> > >> API for all cases.
> > >
> > > The aligned APIs are much better choice when you can use them. The 24 bit
> > > case can remain special IMO.
> > >
> > >>
> > >>> Or... how about putting it in an union with a u64? That would mean it's
> > >>> accessible as u64 alignment-wise while the alignment itself is up to the
> > >>> ABI. A comment would be good to have probably.
> > >>
> > >> An additional union seems a bit too much here. Unless something suitable
> > >> already exists for general usage.
> > >
> > > I think it's nicer than using __aligned() as you get ABI alignment that
> > > way, not something you force manually --- that's a bit crude.
> > >
> > > I wonder that others think.
> >
> > I'm fine with adding the __aligned(8) and switching the non 24 bit
> > cases to helpers which assume alignment. The most important note
> > I have is that that is a separate improvement from this series though.
> >
> > So this should be done in a follow-up patch which is not Cc: stable .
>
> I'm fine with that.
>
> So I think these are good as-is then.
Or rather with the non-functional changes made in v3.
--
Sakari Ailus
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2023-11-02 9:58 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-01 12:23 [PATCH v2 0/2] v4l2-cci: little-endian registers Alexander Stein
2023-11-01 12:23 ` [PATCH v2 1/2] media: v4l2-cci: Add support for little-endian encoded registers Alexander Stein
2023-11-02 1:22 ` Laurent Pinchart
2023-11-02 6:30 ` Sakari Ailus
2023-11-02 7:51 ` Alexander Stein
2023-11-02 8:25 ` Sakari Ailus
2023-11-02 9:27 ` Hans de Goede
2023-11-02 9:56 ` Sakari Ailus
2023-11-02 9:58 ` Sakari Ailus
2023-11-02 7:55 ` Alexander Stein
2023-11-02 8:24 ` Laurent Pinchart
2023-11-02 8:31 ` Sakari Ailus
2023-11-02 8:33 ` Sakari Ailus
2023-11-01 12:23 ` [PATCH v2 2/2] media: i2c: imx290: Properly encode registers as little-endian Alexander Stein
2023-11-02 1:23 ` Laurent Pinchart
2023-11-01 15:26 ` [PATCH v2 0/2] v4l2-cci: little-endian registers Hans de Goede
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.