#define REG_HAECC7     0xaa    /* Hist AEC/AGC control 7 */
 #define REG_BD60MAX    0xab    /* 60hz banding step limit */
 
+enum ov7670_model {
+       MODEL_OV7670 = 0,
+       MODEL_OV7675,
+};
+
+struct ov7670_win_size {
+       int     width;
+       int     height;
+       unsigned char com7_bit;
+       int     hstart;         /* Start/stop values for the camera.  Note */
+       int     hstop;          /* that they do not always make complete */
+       int     vstart;         /* sense to humans, but evidently the sensor */
+       int     vstop;          /* will do the right thing... */
+       struct regval_list *regs; /* Regs to tweak */
+};
+
+struct ov7670_devtype {
+       /* formats supported for each model */
+       struct ov7670_win_size *win_sizes;
+       unsigned int n_win_sizes;
+};
 
 /*
  * Information we maintain about a known sensor.
        int clock_speed;                /* External clock speed (MHz) */
        u8 clkrc;                       /* Clock divider value */
        bool use_smbus;                 /* Use smbus I/O instead of I2C */
+       const struct ov7670_devtype *devtype; /* Device specifics */
 };
 
 static inline struct ov7670_info *to_state(struct v4l2_subdev *sd)
        { 0xff, 0xff },
 };
 
-static struct ov7670_win_size {
-       int     width;
-       int     height;
-       unsigned char com7_bit;
-       int     hstart;         /* Start/stop values for the camera.  Note */
-       int     hstop;          /* that they do not always make complete */
-       int     vstart;         /* sense to humans, but evidently the sensor */
-       int     vstop;          /* will do the right thing... */
-       struct regval_list *regs; /* Regs to tweak */
-/* h/vref stuff */
-} ov7670_win_sizes[] = {
+static struct ov7670_win_size ov7670_win_sizes[] = {
        /* VGA */
        {
                .width          = VGA_WIDTH,
                .height         = VGA_HEIGHT,
                .com7_bit       = COM7_FMT_VGA,
-               .hstart         = 158,          /* These values from */
-               .hstop          =  14,          /* Omnivision */
+               .hstart         = 158,  /* These values from */
+               .hstop          =  14,  /* Omnivision */
                .vstart         =  10,
                .vstop          = 490,
-               .regs           = NULL,
+               .regs           = NULL,
        },
        /* CIF */
        {
                .width          = CIF_WIDTH,
                .height         = CIF_HEIGHT,
                .com7_bit       = COM7_FMT_CIF,
-               .hstart         = 170,          /* Empirically determined */
+               .hstart         = 170,  /* Empirically determined */
                .hstop          =  90,
                .vstart         =  14,
                .vstop          = 494,
-               .regs           = NULL,
+               .regs           = NULL,
        },
        /* QVGA */
        {
                .width          = QVGA_WIDTH,
                .height         = QVGA_HEIGHT,
                .com7_bit       = COM7_FMT_QVGA,
-               .hstart         = 168,          /* Empirically determined */
+               .hstart         = 168,  /* Empirically determined */
                .hstop          =  24,
                .vstart         =  12,
                .vstop          = 492,
-               .regs           = NULL,
+               .regs           = NULL,
        },
        /* QCIF */
        {
                .width          = QCIF_WIDTH,
                .height         = QCIF_HEIGHT,
                .com7_bit       = COM7_FMT_VGA, /* see comment above */
-               .hstart         = 456,          /* Empirically determined */
+               .hstart         = 456,  /* Empirically determined */
                .hstop          =  24,
                .vstart         =  14,
                .vstop          = 494,
-               .regs           = ov7670_qcif_regs,
-       },
+               .regs           = ov7670_qcif_regs,
+       }
 };
 
-#define N_WIN_SIZES (ARRAY_SIZE(ov7670_win_sizes))
-
+static struct ov7670_win_size ov7675_win_sizes[] = {
+       /*
+        * Currently, only VGA is supported. Theoretically it could be possible
+        * to support CIF, QVGA and QCIF too. Taking values for ov7670 as a
+        * base and tweak them empirically could be required.
+        */
+       {
+               .width          = VGA_WIDTH,
+               .height         = VGA_HEIGHT,
+               .com7_bit       = COM7_FMT_VGA,
+               .hstart         = 158,  /* These values from */
+               .hstop          =  14,  /* Omnivision */
+               .vstart         =  14,  /* Empirically determined */
+               .vstop          = 494,
+               .regs           = NULL,
+       }
+};
 
 /*
  * Store a set of start/stop values into the camera.
 {
        int index;
        struct ov7670_win_size *wsize;
+       struct ov7670_info *info = to_state(sd);
+       unsigned int n_win_sizes = info->devtype->n_win_sizes;
 
        for (index = 0; index < N_OV7670_FMTS; index++)
                if (ov7670_formats[index].mbus_code == fmt->code)
         * Round requested image size down to the nearest
         * we support, but not below the smallest.
         */
-       for (wsize = ov7670_win_sizes; wsize < ov7670_win_sizes + N_WIN_SIZES;
-            wsize++)
+       for (wsize = info->devtype->win_sizes;
+            wsize < info->devtype->win_sizes + n_win_sizes; wsize++)
                if (fmt->width >= wsize->width && fmt->height >= wsize->height)
                        break;
-       if (wsize >= ov7670_win_sizes + N_WIN_SIZES)
+       if (wsize >= info->devtype->win_sizes + n_win_sizes)
                wsize--;   /* Take the smallest one */
        if (ret_wsize != NULL)
                *ret_wsize = wsize;
        int i;
        int num_valid = -1;
        __u32 index = fsize->index;
+       unsigned int n_win_sizes = info->devtype->n_win_sizes;
 
        /*
         * If a minimum width/height was requested, filter out the capture
         * windows that fall outside that.
         */
-       for (i = 0; i < N_WIN_SIZES; i++) {
-               struct ov7670_win_size *win = &ov7670_win_sizes[index];
+       for (i = 0; i < n_win_sizes; i++) {
+               struct ov7670_win_size *win = &info->devtype->win_sizes[index];
                if (info->min_width && win->width < info->min_width)
                        continue;
                if (info->min_height && win->height < info->min_height)
 
 /* ----------------------------------------------------------------------- */
 
+static const struct ov7670_devtype ov7670_devdata[] = {
+       [MODEL_OV7670] = {
+               .win_sizes = ov7670_win_sizes,
+               .n_win_sizes = ARRAY_SIZE(ov7670_win_sizes),
+       },
+       [MODEL_OV7675] = {
+               .win_sizes = ov7675_win_sizes,
+               .n_win_sizes = ARRAY_SIZE(ov7675_win_sizes),
+       },
+};
+
 static int ov7670_probe(struct i2c_client *client,
                        const struct i2c_device_id *id)
 {
        v4l_info(client, "chip found @ 0x%02x (%s)\n",
                        client->addr << 1, client->adapter->name);
 
+       info->devtype = &ov7670_devdata[id->driver_data];
        info->fmt = &ov7670_formats[0];
        info->sat = 128;        /* Review this */
        info->clkrc = info->clock_speed / 30;
 }
 
 static const struct i2c_device_id ov7670_id[] = {
-       { "ov7670", 0 },
+       { "ov7670", MODEL_OV7670 },
+       { "ov7675", MODEL_OV7675 },
        { }
 };
 MODULE_DEVICE_TABLE(i2c, ov7670_id);