Query the sensor for its module revision, and compare it to known revisions. Currently only the '1B' revision has been added. Signed-off-by: Robert Foss <robert.foss@xxxxxxxxxx> --- drivers/media/i2c/ov8856.c | 48 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/drivers/media/i2c/ov8856.c b/drivers/media/i2c/ov8856.c index 1769acdfaa44..48e8f4b997d6 100644 --- a/drivers/media/i2c/ov8856.c +++ b/drivers/media/i2c/ov8856.c @@ -34,6 +34,18 @@ #define OV8856_MODE_STANDBY 0x00 #define OV8856_MODE_STREAMING 0x01 +/* define 1B module revision */ +#define OV8856_1B_MODULE 0x02 + +/* the OTP read-out buffer is at 0x7000 and 0xf is the offset + * of the byte in the OTP that means the module revision + */ +#define OV8856_MODULE_REVISION 0x700f +#define OV8856_OTP_MODE_CTRL 0x3d84 +#define OV8856_OTP_LOAD_CTRL 0x3d81 +#define OV8856_OTP_MODE_AUTO 0x00 +#define OV8856_OTP_LOAD_CTRL_ENABLE BIT(0) + /* vertical-timings from sensor */ #define OV8856_REG_VTS 0x380e #define OV8856_VTS_MAX 0x7fff @@ -713,6 +725,25 @@ static int ov8856_test_pattern(struct ov8856 *ov8856, u32 pattern) OV8856_REG_VALUE_08BIT, pattern); } +static int ov8856_check_revision(struct ov8856 *ov8856) +{ + int ret; + + ret = ov8856_write_reg(ov8856, OV8856_REG_MODE_SELECT, + OV8856_REG_VALUE_08BIT, OV8856_MODE_STREAMING); + if (ret) + return ret; + + ret = ov8856_write_reg(ov8856, OV8856_OTP_MODE_CTRL, + OV8856_REG_VALUE_08BIT, OV8856_OTP_MODE_AUTO); + if (ret) + return ret; + + return ov8856_write_reg(ov8856, OV8856_OTP_LOAD_CTRL, + OV8856_REG_VALUE_08BIT, + OV8856_OTP_LOAD_CTRL_ENABLE); +} + static int ov8856_set_ctrl(struct v4l2_ctrl *ctrl) { struct ov8856 *ov8856 = container_of(ctrl->handler, @@ -1145,6 +1176,23 @@ static int ov8856_identify_module(struct ov8856 *ov8856) return -ENXIO; } + /* check sensor hardware revision */ + ret = ov8856_check_revision(ov8856); + if (ret) { + dev_err(&client->dev, "failed to check sensor revision"); + return ret; + } + + ret = ov8856_read_reg(ov8856, OV8856_MODULE_REVISION, + OV8856_REG_VALUE_08BIT, &val); + if (ret) + return ret; + + dev_info(&client->dev, "OV8856 revision %x (%s) at address 0x%02x\n", + val, + val == OV8856_1B_MODULE ? "1B" : "unknown revision", + client->addr); + return 0; } -- 2.20.1