[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