#define MT9V022_AEC_AGC_ENABLE 0xAF
#define MT9V022_MAX_TOTAL_SHUTTER_WIDTH 0xBD
+/* mt9v024 partial list register addresses changes with respect to mt9v022 */
+#define MT9V024_PIXCLK_FV_LV 0x72
+#define MT9V024_MAX_TOTAL_SHUTTER_WIDTH 0xAD
+
/* Progressive scan, master, defaults */
#define MT9V022_CHIP_CONTROL_DEFAULT 0x188
#define MT9V022_COLUMN_SKIP 1
#define MT9V022_ROW_SKIP 4
+#define is_mt9v024(id) (id == 0x1324)
+
/* MT9V022 has only one fixed colorspace per pixelcode */
struct mt9v022_datafmt {
enum v4l2_mbus_pixelcode code;
{V4L2_MBUS_FMT_Y8_1X8, V4L2_COLORSPACE_JPEG},
};
+/* only registers with different addresses on different mt9v02x sensors */
+struct mt9v02x_register {
+ u8 max_total_shutter_width;
+ u8 pixclk_fv_lv;
+};
+
+static const struct mt9v02x_register mt9v022_register = {
+ .max_total_shutter_width = MT9V022_MAX_TOTAL_SHUTTER_WIDTH,
+ .pixclk_fv_lv = MT9V022_PIXCLK_FV_LV,
+};
+
+static const struct mt9v02x_register mt9v024_register = {
+ .max_total_shutter_width = MT9V024_MAX_TOTAL_SHUTTER_WIDTH,
+ .pixclk_fv_lv = MT9V024_PIXCLK_FV_LV,
+};
+
struct mt9v022 {
struct v4l2_subdev subdev;
struct v4l2_ctrl_handler hdl;
struct v4l2_rect rect; /* Sensor window */
const struct mt9v022_datafmt *fmt;
const struct mt9v022_datafmt *fmts;
+ const struct mt9v02x_register *reg;
int num_fmts;
int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
u16 chip_control;
if (!ret)
ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, 480);
if (!ret)
- ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480);
+ ret = reg_write(client, mt9v022->reg->max_total_shutter_width, 480);
if (!ret)
/* default - auto */
ret = reg_clear(client, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1);
ret = reg_read(client, MT9V022_AEC_AGC_ENABLE);
if (ret >= 0) {
if (ret & 1) /* Autoexposure */
- ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH,
+ ret = reg_write(client, mt9v022->reg->max_total_shutter_width,
rect.height + mt9v022->y_skip_top + 43);
else
ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
/* Read out the chip version register */
data = reg_read(client, MT9V022_CHIP_VERSION);
- /* must be 0x1311 or 0x1313 */
- if (data != 0x1311 && data != 0x1313) {
+ /* must be 0x1311, 0x1313 or 0x1324 */
+ if (data != 0x1311 && data != 0x1313 && data != 0x1324) {
ret = -ENODEV;
dev_info(&client->dev, "No MT9V022 found, ID register 0x%x\n",
data);
goto ei2c;
}
+ mt9v022->reg = is_mt9v024(data) ? &mt9v024_register :
+ &mt9v022_register;
+
/* Soft reset */
ret = reg_write(client, MT9V022_RESET, 1);
if (ret < 0)
if (!(flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH))
pixclk |= 0x2;
- ret = reg_write(client, MT9V022_PIXCLK_FV_LV, pixclk);
+ ret = reg_write(client, mt9v022->reg->pixclk_fv_lv, pixclk);
if (ret < 0)
return ret;