[libcamera-devel] [PATCH] imx258: Read analog gain register values

Umang Jain umang.jain at ideasonboard.com
Mon Jul 19 12:14:37 CEST 2021


Also copy and tweak imx258_read_reg() to allow signed int values.
(These constants are signed ints).

---
 drivers/media/i2c/imx258.c | 78 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 78 insertions(+)

diff --git a/drivers/media/i2c/imx258.c b/drivers/media/i2c/imx258.c
index f86ae18bc104..d029706f4d51 100644
--- a/drivers/media/i2c/imx258.c
+++ b/drivers/media/i2c/imx258.c
@@ -21,6 +21,13 @@
 #define IMX258_REG_CHIP_ID		0x0016
 #define IMX258_CHIP_ID			0x0258
 
+/* Gain constant registers */
+#define IMX258_REG_GAIN_CAP		0x0080
+#define IMX258_REG_C0			0x008E
+#define IMX258_REG_M0			0x008C
+#define IMX258_REG_C1			0x0092
+#define IMX258_REG_M1			0x0090
+
 /* V_TIMING internal */
 #define IMX258_VTS_30FPS		0x0c98
 #define IMX258_VTS_30FPS_2K		0x0638
@@ -650,6 +657,38 @@ static int imx258_read_reg(struct imx258 *imx258, u16 reg, u32 len, u32 *val)
 	return 0;
 }
 
+static int imx258_read_reg_signed(struct imx258 *imx258, u16 reg, u32 len, int16_t *val)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&imx258->sd);
+	struct i2c_msg msgs[2];
+	u8 addr_buf[2] = { reg >> 8, reg & 0xff };
+	u8 data_buf[4] = { 0, };
+	int ret;
+
+	if (len > 4)
+		return -EINVAL;
+
+	/* Write register address */
+	msgs[0].addr = client->addr;
+	msgs[0].flags = 0;
+	msgs[0].len = ARRAY_SIZE(addr_buf);
+	msgs[0].buf = addr_buf;
+
+	/* Read data from register */
+	msgs[1].addr = client->addr;
+	msgs[1].flags = I2C_M_RD;
+	msgs[1].len = len;
+	msgs[1].buf = &data_buf[4 - len];
+
+	ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
+	if (ret != ARRAY_SIZE(msgs))
+		return -EIO;
+
+	*val = get_unaligned_be32(data_buf);
+
+	return 0;
+}
+
 /* Write registers up to 2 at a time */
 static int imx258_write_reg(struct imx258 *imx258, u16 reg, u32 len, u32 val)
 {
@@ -1055,6 +1094,7 @@ static int imx258_identify_module(struct imx258 *imx258)
 	struct i2c_client *client = v4l2_get_subdevdata(&imx258->sd);
 	int ret;
 	u32 val;
+	int16_t value;
 
 	ret = imx258_read_reg(imx258, IMX258_REG_CHIP_ID,
 			      IMX258_REG_VALUE_16BIT, &val);
@@ -1070,6 +1110,44 @@ static int imx258_identify_module(struct imx258 *imx258)
 		return -EIO;
 	}
 
+	// Hijack this to also read analog gain registers and print values
+	dev_info(&client->dev, "Reading analog gain registers...\n");
+
+	ret = imx258_read_reg(imx258, IMX258_REG_GAIN_CAP, IMX258_REG_VALUE_16BIT, &val);
+	if (ret) {
+		dev_err(&client->dev, "failed to read GAIN_CAP %x\n",
+			IMX258_REG_GAIN_CAP);
+	}
+	dev_info(&client->dev, "Value of analog Gain capability: %d\n", val);
+
+	ret = imx258_read_reg_signed(imx258, IMX258_REG_C0, IMX258_REG_VALUE_16BIT, &value);
+	if (ret) {
+		dev_err(&client->dev, "failed to read C0 %x\n",
+			IMX258_REG_C0);
+	}
+	dev_info(&client->dev, "Value of C0: %d\n", value);
+
+	ret = imx258_read_reg_signed(imx258, IMX258_REG_M0, IMX258_REG_VALUE_16BIT, &value);
+	if (ret) {
+		dev_err(&client->dev, "failed to read M0 %x\n",
+			IMX258_REG_M0);
+	}
+	dev_info(&client->dev, "Value of M0: %d\n", value);
+
+	ret = imx258_read_reg_signed(imx258, IMX258_REG_C1, IMX258_REG_VALUE_16BIT, &value);
+	if (ret) {
+		dev_err(&client->dev, "failed to read C1 %x\n",
+			IMX258_REG_C1);
+	}
+	dev_info(&client->dev, "Value of C1: %d\n", value);
+
+	ret = imx258_read_reg_signed(imx258, IMX258_REG_M1, IMX258_REG_VALUE_16BIT, &value);
+	if (ret) {
+		dev_err(&client->dev, "failed to read M1 %x\n",
+			IMX258_REG_M1);
+	}
+	dev_info(&client->dev, "Value of M1: %d\n", value);
+
 	return 0;
 }
 
-- 
2.31.0



More information about the libcamera-devel mailing list